πŸ“ Tutorials
Β· 7 min read

CSS Complete Guide: Modern Styling from Basics to Advanced


CSS has evolved dramatically. Modern CSS gives you layout systems (Flexbox, Grid), custom properties, container queries, and animations that used to require JavaScript. This guide covers the fundamentals through advanced techniques, with links to tools and cheat sheets throughout.

Selectors

Selectors target which elements your styles apply to. For a complete reference, see our CSS selectors cheat sheet.

/* Element, class, ID */
p { color: gray; }
.card { padding: 1rem; }
#hero { height: 100vh; }

/* Combinators */
.card > h2 { }       /* direct child */
.card h2 { }         /* any descendant */
.card + .card { }    /* adjacent sibling */
.card ~ .card { }    /* general sibling */

/* Pseudo-classes */
a:hover { }
li:first-child { }
input:focus-visible { }
p:has(> img) { }     /* parent selector β€” modern CSS */

/* Pseudo-elements */
p::first-line { }
.icon::before { content: "β†’"; }

The :has() selector is a game-changer β€” it lets you style a parent based on its children, something CSS couldn’t do for 25 years.

The Box Model

Every element is a box with content, padding, border, and margin. Visualize it with our CSS box model visualizer.

/* Always use border-box β€” it makes sizing predictable */
*, *::before, *::after {
  box-sizing: border-box;
}

With border-box, width: 200px means the total width is 200px including padding and border. Without it, padding and border are added on top.

Flexbox

Flexbox handles one-dimensional layouts β€” rows or columns. See the CSS Flexbox & Grid cheat sheet for all properties, or experiment in our Flexbox playground.

.container {
  display: flex;
  gap: 1rem;
  justify-content: space-between; /* main axis */
  align-items: center;            /* cross axis */
}

Common patterns:

/* Center anything */
.center {
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Push last item to the right */
.nav {
  display: flex;
  gap: 1rem;
}
.nav .logout {
  margin-left: auto;
}

/* Equal-width columns */
.columns {
  display: flex;
}
.columns > * {
  flex: 1;
}

If your Flexbox centering isn’t working, check our Flexbox not centering fix.

CSS Grid

Grid handles two-dimensional layouts β€” rows and columns simultaneously. Generate layouts with our CSS Grid generator.

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
}

Common patterns:

/* Holy grail layout */
.page {
  display: grid;
  grid-template: "header header" auto
                 "sidebar main" 1fr
                 "footer footer" auto
                 / 250px 1fr;
  min-height: 100vh;
}
.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

/* Responsive card grid */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1rem;
}

If grid items overflow their container, see our CSS Grid overflow fix.

Custom Properties (CSS Variables)

:root {
  --color-primary: #3b82f6;
  --color-text: #1f2937;
  --spacing: 1rem;
  --radius: 0.5rem;
}

.button {
  background: var(--color-primary);
  padding: var(--spacing);
  border-radius: var(--radius);
}

/* Override per context */
.dark {
  --color-primary: #60a5fa;
  --color-text: #f9fafb;
}

Custom properties cascade and can be changed with JavaScript, making them perfect for theming.

Responsive Design

Use our CSS media queries cheat sheet for breakpoint reference.

/* Mobile-first approach */
.container {
  padding: 1rem;
}

@media (min-width: 768px) {
  .container {
    padding: 2rem;
    max-width: 1200px;
    margin: 0 auto;
  }
}

Modern alternatives to media queries:

/* Container queries β€” respond to parent size, not viewport */
.card-container {
  container-type: inline-size;
}

@container (min-width: 400px) {
  .card { flex-direction: row; }
}

/* clamp() for fluid typography */
h1 {
  font-size: clamp(1.5rem, 4vw, 3rem);
}

Animations and Transitions

For a full reference, see our CSS animations cheat sheet.

/* Transitions β€” animate between states */
.button {
  background: #3b82f6;
  transition: background 200ms ease, transform 200ms ease;
}
.button:hover {
  background: #2563eb;
  transform: translateY(-1px);
}

/* Keyframe animations */
@keyframes fade-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.card {
  animation: fade-in 300ms ease-out;
}

Respect user preferences:

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

Shadows and Effects

Generate shadows with our CSS box shadow generator and gradients with the CSS gradient generator.

.card {
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.1), 0 1px 2px rgb(0 0 0 / 0.06);
}

.hero {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

Position and Stacking

/* Sticky header */
.header {
  position: sticky;
  top: 0;
  z-index: 50;
}

If position: sticky isn’t working, check our sticky not working fix. For z-index issues, see the z-index fix.

Tailwind CSS

Tailwind is a utility-first CSS framework that’s become the most popular way to write CSS in modern projects. See our Tailwind CSS cheat sheet and browse ready-made Tailwind components.

<div class="flex items-center gap-4 rounded-lg bg-white p-6 shadow-md">
  <img class="h-12 w-12 rounded-full" src="avatar.jpg" alt="" />
  <div>
    <h3 class="text-lg font-semibold text-gray-900">Alice</h3>
    <p class="text-sm text-gray-500">Developer</p>
  </div>
</div>

If you’re migrating to Tailwind v4, check our Tailwind v4 migration fix. For classes not applying, see the Tailwind classes fix. Deciding between approaches? Read Tailwind vs CSS Modules.

You can also convert between formats with our Tailwind to CSS converter.

CSS Tools

We’ve built several tools to speed up your CSS workflow:

Modern CSS Features

CSS has gained powerful features in recent years that reduce the need for JavaScript and preprocessors.

Nesting

Native CSS nesting (supported in all modern browsers):

.card {
  padding: 1rem;
  background: white;

  & h2 {
    font-size: 1.25rem;
    margin-bottom: 0.5rem;
  }

  &:hover {
    box-shadow: 0 4px 12px rgb(0 0 0 / 0.1);
  }

  @media (min-width: 768px) {
    padding: 2rem;
  }
}

Color Functions

.button {
  --brand: oklch(65% 0.25 260);
  background: var(--brand);
  border-color: oklch(from var(--brand) calc(l - 0.1) c h);
}

/* Light/dark with color-mix */
.subtle {
  background: color-mix(in oklch, var(--brand) 10%, white);
}

Scroll-Driven Animations

Animate elements based on scroll position β€” no JavaScript needed:

@keyframes reveal {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}

.section {
  animation: reveal linear both;
  animation-timeline: view();
  animation-range: entry 0% entry 100%;
}

Logical Properties

Write CSS that works for both LTR and RTL languages:

/* Instead of margin-left/right */
.sidebar {
  margin-inline-start: 2rem;
  padding-block: 1rem;
  border-inline-end: 1px solid #e5e7eb;
}

Accessibility

CSS plays a critical role in accessibility:

/* Visible focus indicators */
:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* Screen reader only (visually hidden but accessible) */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Respect user preferences */
@media (prefers-color-scheme: dark) {
  :root {
    --color-bg: #0f172a;
    --color-text: #f1f5f9;
  }
}

@media (prefers-contrast: more) {
  :root {
    --color-text: black;
    --color-bg: white;
  }
}

Always ensure sufficient color contrast (4.5:1 for normal text, 3:1 for large text) and never rely on color alone to convey information.

Performance

CSS can impact page load performance:

/* Use content-visibility for off-screen content */
.below-fold {
  content-visibility: auto;
  contain-intrinsic-size: 0 500px;
}

/* Avoid expensive properties in animations */
/* βœ… Good β€” GPU-accelerated */
transform: translateX(100px);
opacity: 0.5;

/* ❌ Slow β€” triggers layout */
left: 100px;
width: 200px;

Tips:

  • Minimize CSS file size β€” use our CSS minifier
  • Avoid @import in CSS files (use bundler imports instead)
  • Use will-change sparingly and only on elements that actually animate
  • Prefer transform and opacity for animations β€” they’re GPU-accelerated

CSS Architecture

For larger projects, organize your CSS with a clear structure:

styles/
β”œβ”€β”€ base/          /* reset, typography, variables */
β”œβ”€β”€ components/    /* button, card, modal */
β”œβ”€β”€ layouts/       /* header, footer, sidebar */
└── utilities/     /* spacing, visibility helpers */

Naming conventions like BEM help keep things maintainable:

/* Block__Element--Modifier */
.card { }
.card__title { }
.card__title--highlighted { }
.card--featured { }

Or skip naming conventions entirely and use Tailwind’s utility-first approach or CSS Modules for component-scoped styles.

Common Issues

Next Steps