01 — HAMBURGER MENU
pure CSS · no JS.hamburger { display: flex; flex-direction: column; /* stack bars top→bottom */ justify-content: space-between; /* even gaps */ width: 32px; height: 22px; cursor: pointer; } .hamburger span { height: 2px; /* each bar */ background: #1a1a2e; transition: transform 0.3s, opacity 0.3s; transform-origin: center; /* rotate from middle */ } /* The trick: hidden checkbox holds the state */ #toggle:checked + .hamburger span:nth-child(1) { transform: translateY(10px) rotate(45deg); } #toggle:checked + .hamburger span:nth-child(2) { opacity: 0; /* vanish middle bar */ } #toggle:checked + .hamburger span:nth-child(3) { transform: translateY(-10px) rotate(-45deg); }
💡 The key insight: a hidden
<input type="checkbox"> stores open/closed state. The :checked pseudo-class + adjacent sibling selector (+) lets you change styles with zero JavaScript.
02 — CARD
hover lift · overflow clipcard.title
A self-contained block of content. Hover to float.
.card { background: white; border-radius: 8px; overflow: hidden; /* clips img to rounded corners */ box-shadow: 0 2px 8px rgba(0,0,0,.10), 0 0 0 1px rgba(0,0,0,.06); /* 2-layer shadow */ transition: transform 0.2s, box-shadow 0.2s; } .card:hover { transform: translateY(-4px); /* float upward */ box-shadow: 0 8px 24px rgba(0,0,0,.15), 0 0 0 1px rgba(0,0,0,.06); } .card-image { width: 100%; /* fills card width */ height: 100px; } .card-body { padding: 1rem; /* breathing room for text */ }
💡 The
2-layer box-shadow trick: one shadow for depth, one thin ring (0 0 0 1px) acts as a subtle border — this looks far more refined than border: 1px solid.
03 — BUTTONS
primary · outline · ghost.btn { display: inline-flex; /* shrink-wraps content */ align-items: center; /* centers icon + text */ padding: 0.6rem 1.2rem; border: 2px solid transparent; /* holds space for outline */ cursor: pointer; transition: all 0.15s ease; } .btn-primary { background: var(--accent); color: white; border-color: var(--accent); /* matches background */ } .btn-outline { background: transparent; border-color: currentColor; /* border = text color */ } .btn-ghost { background: transparent; border-color: transparent; color: var(--muted); /* low emphasis */ }
💡 Setting
border: 2px solid transparent on the base class means all button variants occupy the same height — swapping between primary/outline won't cause layout shift.
05 — MODAL OVERLAY
position:fixed · z-index.modal-overlay { position: fixed; /* covers whole viewport */ inset: 0; /* top/right/bottom/left: 0 */ background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; /* centers the box */ opacity: 0; /* hidden by default */ pointer-events: none; /* can't click when hidden */ z-index: 100; /* above all other content */ transition: opacity 0.2s; } #toggle:checked ~ .modal-overlay { opacity: 1; pointer-events: all; /* now interactive */ } .modal-box { transform: translateY(16px) scale(0.97); /* start low */ transition: transform 0.2s; } #toggle:checked ~ .overlay .modal-box { transform: none; /* snaps into place */ }
💡
pointer-events: none is how you make something visually invisible AND unclickable. z-index only matters when position is set to anything other than static.