Advanced CSS: Units & Layout
CSS Units Comparison
/* Absolute units */
px /* 1 pixel */
pt /* 1 point = 1/72 inch */
/* Relative to parent */
em /* 1em = parent's font-size */
% /* Percentage of parent */
/* Relative to root */
rem /* 1rem = root (html) font-size */
/* Viewport relative */
vw /* 1vw = 1% of viewport width */
vh /* 1vh = 1% of viewport height */
vmin /* 1vmin = 1% of smaller dimension */
vmax /* 1vmax = 1% of larger dimension */
/* Examples */
.element {
font-size: 1rem; /* 16px if root is 16px */
padding: 1em; /* Equals current font-size */
width: 50%; /* 50% of parent */
height: 100vh; /* Full viewport height */
}rem vs em
/* rem - consistent, predictable */
html { font-size: 16px; }
.button {
font-size: 1rem; /* Always 16px */
padding: 0.5rem 1rem; /* Always 8px 16px */
}
/* em - contextual, component-relative */
.card {
font-size: 1rem;
padding: 1em; /* 16px (equals font-size) */
}
.card .button {
font-size: 0.875em; /* 14px (87.5% of 16px) */
margin: 0.5em; /* 7px (0.5 * 14px) */
}
/* Best practice: rem for layout, em for components */
body { font-size: 1rem; }
.component { padding: 1em; } /* Scales with component */Fluid Typography with clamp()
/* clamp(min, preferred, max) */
h1 {
font-size: clamp(1.5rem, 4vw, 3rem);
/* Min: 24px, Preferred: 4vw, Max: 48px */
}
/* Fluid spacing */
.container {
padding: clamp(1rem, 3vw, 2rem);
max-width: min(100% - 2rem, 1200px);
}
/* Complete fluid type scale */
:root {
--fluid-min: 1rem;
--fluid-max: 2.5rem;
--fluid-ratio: 1.25;
}
h1 { font-size: clamp(var(--fluid-min), 5vw, var(--fluid-max)); }
h2 { font-size: clamp(var(--fluid-min), 4vw, 2rem); }
p { font-size: clamp(0.875rem, 2vw, 1.125rem); }CSS Math Functions
/* calc() - calculations */
.element {
width: calc(100% - 2rem);
margin-left: calc(50% - 300px);
}
/* min() - smallest value */
.container {
width: min(100%, 1200px);
padding: min(5vw, 2rem);
}
/* max() - largest value */
.sidebar {
width: max(200px, 20%);
}
/* Combine functions */
.card {
width: calc(min(100%, 400px) - 2rem);
font-size: clamp(1rem, 2vw, max(1.125rem, 2vw));
}Container Queries
/* Define container */
.card-container {
container-type: inline-size;
container-name: card;
}
/* Query container size (not viewport) */
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 1fr 1fr;
}
}
@container card (min-width: 600px) {
.card {
grid-template-columns: 1fr 1fr 1fr;
}
}
/* Container query units */
@container card (min-width: 30cqw) {
/* cqw = container query width */
}Modern Responsive Patterns
/* Responsive grid */
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
/* Responsive flex */
.flex {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.flex > * {
flex: 1 1 300px; /* Grow, shrink, basis */
}
/* Aspect ratio */
.video {
aspect-ratio: 16 / 9;
width: 100%;
}
/* Responsive images */
img {
max-width: 100%;
height: auto;
object-fit: cover;
}Subgrid
/* Parent grid */
.parent {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
/* Child uses parent's grid */
.child {
display: grid;
grid-template-columns: subgrid;
grid-column: span 2;
}Key Takeaways
- Use rem for consistent sizing
- Use em for component-relative sizing
- Use clamp() for fluid typography
- Use container queries for component responsiveness
- Use min()/max() for constraints
Next Steps
Continue to professional skills: