Box Model & Sizing
Create a .box that is exactly 300px wide and 200px tall regardless of padding. Give it 20px padding all around and a 2px solid #1572B6 border. The total visible size should remain 300×200px.
▶ Show Solution
.box {
box-sizing: border-box;
width: 300px;
height: 200px;
padding: 20px;
border: 2px solid #1572B6;
}
Why: box-sizing: border-box makes width/height include padding and border. Without it, the total would be 344×244px.
Two <p> elements: first has margin-bottom: 32px, second has margin-top: 24px. What is the actual space between them? Then explain how to prevent margin collapse.
▶ Show Solution
Answer: 32px — the larger margin wins (margins collapse). The space is NOT 56px.
How to prevent collapse:
/* Method 1: Add padding (or border) to the parent */
.parent { padding-top: 1px; }
/* Method 2: Use overflow */
.parent { overflow: hidden; }
/* Method 3: Use flexbox/grid (margins don't collapse in flex/grid) */
.parent { display: flex; flex-direction: column; }
/* Best: just use gap in flex/grid instead of margins */
.parent { display: flex; flex-direction: column; gap: 32px; }
Flexbox
Make a .hero section that fills the full viewport height and perfectly centers its content both horizontally and vertically using Flexbox. Use two methods.
▶ Show Solution
/* Method 1: Flexbox */
.hero {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
/* Method 2: Grid */
.hero {
display: grid;
place-items: center;
min-height: 100vh;
}
Build a navigation bar where the logo is on the left, nav links are in the center, and a button is on the right — all using Flexbox. On screens below 768px, stack everything vertically.
▶ Show Solution
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 2rem;
background: #1572B6;
}
.navbar__logo { color: #fff; font-weight: 800; }
.navbar__links {
display: flex;
gap: 1.5rem;
list-style: none;
margin: 0; padding: 0;
}
.navbar__links a { color: rgba(255,255,255,.85); text-decoration: none; }
.navbar__links a:hover { color: #fff; }
.navbar__btn { /* see projects/navigation.html for full implementation */ }
@media (max-width: 768px) {
.navbar { flex-direction: column; gap: 1rem; text-align: center; }
.navbar__links { flex-direction: column; gap: .75rem; }
}
CSS Grid
Create a responsive card grid where columns automatically fill the container — each column is at least 250px wide. Cards should fill remaining space equally. No media queries allowed.
▶ Show Solution
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 1.5rem;
}
/* auto-fill: creates as many columns as fit, even empty ones
minmax(250px, 1fr): each column is at least 250px, grows to fill space */
Create the "Holy Grail" page layout: a full-height page with a header, a footer, and a three-column middle section (left sidebar, main content, right sidebar) using CSS Grid.
▶ Show Solution
.page {
display: grid;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
grid-template-columns: 220px 1fr 220px;
min-height: 100vh;
gap: 1rem;
}
.page-header { grid-area: header; }
.page-sidebar { grid-area: sidebar; }
.page-main { grid-area: main; }
.page-aside { grid-area: aside; }
.page-footer { grid-area: footer; }
@media (max-width: 768px) {
.page {
grid-template-areas:
"header"
"main"
"sidebar"
"aside"
"footer";
grid-template-columns: 1fr;
}
}
Positioning & Stacking
Make a .header that sticks to the top of the viewport when the user scrolls past it, but scrolls normally until it reaches the top.
▶ Show Solution
.header {
position: sticky;
top: 0;
z-index: 100;
background: #fff;
box-shadow: 0 2px 8px rgba(0,0,0,.1);
}
/* sticky requires that no ancestor has overflow: hidden/auto/scroll */
Create a card component with an image that has an absolutely positioned "NEW" badge in the top-right corner of the image. The badge should not affect the image's layout.
▶ Show Solution
.card { position: relative; } /* positioning context */
.card__img { display: block; width: 100%; }
.card__badge {
position: absolute;
top: 12px;
right: 12px;
background: #e44d26;
color: #fff;
font-size: .75rem;
font-weight: 700;
padding: .25rem .6rem;
border-radius: 12px;
text-transform: uppercase;
letter-spacing: .05em;
}
Typography & Colors
Create a heading font size that is 1rem on small screens, grows proportionally with the viewport, and maxes out at 3rem — without using any media queries.
▶ Show Solution
h1 {
font-size: clamp(1rem, 3vw + 0.5rem, 3rem);
/* clamp(min, preferred, max)
min: 1rem on tiny screens
preferred: 3vw + 0.5rem — grows with viewport
max: 3rem on large screens */
}
Set up a simple dark/light theme system using CSS custom properties. The theme should switch by toggling a data-theme="dark" attribute on <html>.
▶ Show Solution
:root {
--bg: #ffffff;
--text: #1a1a1a;
--surface: #f5f5f5;
--primary: #1572B6;
}
[data-theme="dark"] {
--bg: #121212;
--text: #f1f1f1;
--surface: #1e1e1e;
--primary: #4fc3f7;
}
body { background: var(--bg); color: var(--text); transition: background .3s, color .3s; }
.card { background: var(--surface); }
document.getElementById('themeBtn').addEventListener('click', () => {
const html = document.documentElement;
html.setAttribute('data-theme',
html.getAttribute('data-theme') === 'dark' ? 'light' : 'dark'
);
});
Animations & Effects
Create a button that lifts up 4px and has a deeper shadow on hover. The animation must be smooth and must only use GPU-composited properties.
▶ Show Solution
.btn {
background: #1572B6;
color: #fff;
padding: .75rem 1.5rem;
border: none;
border-radius: 6px;
cursor: pointer;
transform: translateY(0);
box-shadow: 0 2px 6px rgba(0,0,0,.2);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.btn:hover {
transform: translateY(-4px);
box-shadow: 0 8px 20px rgba(0,0,0,.25);
}
/* transform is GPU-composited — no layout reflow */
Create a skeleton loading placeholder for a card component. Use a shimmering animation that travels left to right across the grey placeholder areas.
▶ Show Solution
@keyframes shimmer {
from { background-position: -200% 0; }
to { background-position: 200% 0; }
}
.skeleton {
background: linear-gradient(
90deg,
#e0e0e0 25%,
#f0f0f0 50%,
#e0e0e0 75%
);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
border-radius: 4px;
}
.skeleton-title { height: 20px; width: 70%; margin-bottom: 12px; }
.skeleton-text { height: 14px; width: 100%; margin-bottom: 8px; }
.skeleton-image { height: 180px; width: 100%; margin-bottom: 16px; }
Responsive Design
Create a card grid that shows 1 column on mobile, 2 columns on tablet (≥600px), and 3 columns on desktop (≥1024px). Use mobile-first media queries.
▶ Show Solution
/* Mobile first: 1 column */
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 1.5rem;
}
/* Tablet: 2 columns */
@media (min-width: 600px) {
.grid { grid-template-columns: repeat(2, 1fr); }
}
/* Desktop: 3 columns */
@media (min-width: 1024px) {
.grid { grid-template-columns: repeat(3, 1fr); }
}
Build a working accordion (expandable/collapsible sections) using only CSS — no JavaScript. Clicking a section header reveals its content; clicking again collapses it.
▶ Show Solution
<details class="accordion">
<summary class="accordion__header">Section 1 <span>+</span></summary>
<div class="accordion__body">Content here...</div>
</details>
.accordion {
border: 1px solid var(--border-color);
border-radius: 6px;
margin-bottom: .5rem;
}
.accordion__header {
padding: 1rem 1.25rem;
cursor: pointer;
list-style: none;
display: flex;
justify-content: space-between;
font-weight: 600;
}
.accordion__header::-webkit-details-marker { display: none; }
.accordion[open] .accordion__header span { transform: rotate(45deg); }
.accordion__header span { transition: transform .2s; display: inline-block; }
.accordion__body { padding: 0 1.25rem 1rem; }
/* The <details> element handles open/close natively */
Build a card that flips 180° on hover to reveal a back face, using 3D CSS transforms. The front shows a question; the back shows the answer.
▶ Show Solution
.flip-card {
width: 280px;
height: 180px;
perspective: 800px; /* creates 3D depth */
}
.flip-card__inner {
position: relative;
width: 100%; height: 100%;
transform-style: preserve-3d;
transition: transform 0.6s ease;
}
.flip-card:hover .flip-card__inner {
transform: rotateY(180deg);
}
.flip-card__front,
.flip-card__back {
position: absolute;
inset: 0;
backface-visibility: hidden; /* hides the reverse face */
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
padding: 1.5rem;
text-align: center;
}
.flip-card__front { background: #1572B6; color: #fff; }
.flip-card__back { background: #e44d26; color: #fff; transform: rotateY(180deg); }
📋 Next Steps
- Practice building complete components — see the CSS Projects section.
- Review CSS Interview Questions to test your theoretical knowledge.
- Apply these patterns to real layouts: Full Landing Page Style.