
CSS
CSS hiện đại: Grid, Flexbox và Container Queries
Khám phá các kỹ thuật CSS hiện đại để tạo layouts responsive và beautiful.
20 tháng 12, 2023
8 phút đọc
CSS hiện đại: Grid, Flexbox và Container Queries
CSS đã phát triển mạnh mẽ trong những năm gần đây với nhiều tính năng mới giúp tạo layouts responsive và beautiful. Hãy cùng khám phá các kỹ thuật CSS hiện đại.
CSS Grid Layout
Basic Grid Setup
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
padding: 2rem;
}
.grid-item {
background: white;
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
Advanced Grid Layouts
.dashboard-grid {
display: grid;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
grid-template-columns: 250px 1fr 200px;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
gap: 1rem;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
/* Responsive */
@media (max-width: 768px) {
.dashboard-grid {
grid-template-areas:
"header"
"main"
"sidebar"
"aside"
"footer";
grid-template-columns: 1fr;
}
}
Grid với dynamic content
.masonry-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-rows: 10px; /* Small row height */
gap: 1rem;
}
.masonry-item {
/* JavaScript sẽ set grid-row-end dựa trên content height */
background: white;
border-radius: 8px;
padding: 1rem;
}
// JavaScript để tính toán grid-row-end
function resizeGridItem(item) {
const grid = document.querySelector('.masonry-grid');
const rowHeight = parseInt(window.getComputedStyle(grid).getPropertyValue('grid-auto-rows'));
const rowGap = parseInt(window.getComputedStyle(grid).getPropertyValue('gap'));
const rowSpan = Math.ceil((item.scrollHeight + rowGap) / (rowHeight + rowGap));
item.style.gridRowEnd = `span ${rowSpan}`;
}
Flexbox Advanced Techniques
Perfect Centering
.center-everything {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
/* Hoặc với grid */
.center-with-grid {
display: grid;
place-items: center;
min-height: 100vh;
}
Flexible Card Layouts
.card-container {
display: flex;
flex-wrap: wrap;
gap: 1rem;
padding: 1rem;
}
.card {
flex: 1 1 300px; /* grow, shrink, basis */
min-width: 0; /* Prevent overflow */
background: white;
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
/* Equal height cards */
.equal-height-cards {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.equal-height-cards .card {
flex: 1 1 calc(33.333% - 1rem);
display: flex;
flex-direction: column;
}
.card-content {
flex: 1; /* Takes remaining space */
}
Container Queries
Container queries cho phép styling dựa trên kích thước của container thay vì viewport:
.card-container {
container-type: inline-size;
container-name: card;
}
.card {
padding: 1rem;
background: white;
border-radius: 8px;
}
/* Khi container >= 400px */
@container card (min-width: 400px) {
.card {
display: flex;
flex-direction: row;
gap: 1rem;
}
.card-image {
flex: 0 0 150px;
}
.card-content {
flex: 1;
}
}
/* Khi container >= 600px */
@container card (min-width: 600px) {
.card {
padding: 2rem;
}
.card-title {
font-size: 1.5rem;
}
}
CSS Custom Properties (Variables)
Dynamic Theming
:root {
/* Light theme */
--color-primary: hsl(210, 100%, 50%);
--color-secondary: hsl(210, 100%, 60%);
--color-background: hsl(0, 0%, 100%);
--color-text: hsl(0, 0%, 10%);
--color-border: hsl(0, 0%, 90%);
/* Spacing system */
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 2rem;
--spacing-xl: 4rem;
/* Typography */
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
--font-size-xl: 1.25rem;
--font-size-2xl: 1.5rem;
}
[data-theme="dark"] {
--color-primary: hsl(210, 100%, 60%);
--color-secondary: hsl(210, 100%, 70%);
--color-background: hsl(0, 0%, 10%);
--color-text: hsl(0, 0%, 90%);
--color-border: hsl(0, 0%, 20%);
}
.component {
background: var(--color-background);
color: var(--color-text);
border: 1px solid var(--color-border);
padding: var(--spacing-md);
font-size: var(--font-size-base);
}
Responsive Custom Properties
:root {
--container-padding: 1rem;
--grid-columns: 1;
--font-size-hero: 2rem;
}
@media (min-width: 768px) {
:root {
--container-padding: 2rem;
--grid-columns: 2;
--font-size-hero: 3rem;
}
}
@media (min-width: 1024px) {
:root {
--container-padding: 3rem;
--grid-columns: 3;
--font-size-hero: 4rem;
}
}
.container {
padding: var(--container-padding);
}
.grid {
display: grid;
grid-template-columns: repeat(var(--grid-columns), 1fr);
gap: var(--spacing-lg);
}
.hero-title {
font-size: var(--font-size-hero);
}
Modern CSS Functions
clamp() cho Responsive Typography
.responsive-text {
/* min, preferred, max */
font-size: clamp(1rem, 4vw, 2.5rem);
line-height: clamp(1.2, 1.5, 1.8);
margin-bottom: clamp(0.5rem, 2vw, 2rem);
}
.container {
/* Responsive container width */
width: clamp(300px, 90vw, 1200px);
margin: 0 auto;
padding: clamp(1rem, 5vw, 3rem);
}
min(), max(), và calc()
.flexible-width {
/* Không bao giờ nhỏ hơn 200px, không lớn hơn 50% */
width: max(200px, 50%);
/* Không bao giờ lớn hơn 800px, không nhỏ hơn 90% */
max-width: min(800px, 90vw);
/* Dynamic spacing */
margin: calc(2rem + 3vw) auto;
padding: calc(1rem + 2vw);
}
CSS Logical Properties
Tốt hơn cho internationalization:
.component {
/* Thay vì margin-left, margin-right */
margin-inline: 1rem;
/* Thay vì margin-top, margin-bottom */
margin-block: 2rem;
/* Thay vì padding-left */
padding-inline-start: 1rem;
/* Thay vì border-left */
border-inline-start: 2px solid var(--color-primary);
/* Thay vì text-align: left */
text-align: start;
}
CSS Subgrid
.main-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
.card {
display: grid;
grid-template-rows: subgrid;
grid-row: span 3; /* Spans 3 rows of parent */
}
.card-header,
.card-content,
.card-footer {
/* Automatically aligns with parent grid */
}
Performance Tips
CSS Containment
.independent-component {
/* Tells browser this component is independent */
contain: layout style paint;
}
.list-item {
/* For long lists */
contain: layout paint;
}
will-change Property
.animated-element {
/* Hint to browser about upcoming changes */
will-change: transform, opacity;
transition: transform 0.3s ease, opacity 0.3s ease;
}
.animated-element:hover {
transform: translateY(-5px);
opacity: 0.8;
}
/* Remove will-change after animation */
.animated-element.animation-complete {
will-change: auto;
}
Kết luận
CSS hiện đại cung cấp nhiều công cụ mạnh mẽ để tạo layouts responsive và beautiful:
- CSS Grid cho complex 2D layouts
- Flexbox cho 1D layouts và alignment
- Container Queries cho truly responsive components
- Custom Properties cho maintainable theming
- Modern functions cho responsive design
- Logical Properties cho internationalization
Việc nắm vững những kỹ thuật này sẽ giúp bạn tạo ra những giao diện web hiện đại, responsive và performant.
Tags: CSS, Frontend, Design, Responsive, Grid, Flexbox, Modern CSS
Tags:
CSS
Frontend
Design
Responsive
Grid
Flexbox
Modern CSS