Frontend Development

The Ultimate Comprehensive Guide for Mastering CSS

By the Domain India teamPublished 9 min read
Knowledge base article
Contents (10 sections)

CSS (Cascading Style Sheets) controls how every web page looks: colours, fonts, spacing, layout and how the design adapts from a phone to a wide monitor. CSS has changed a lot in the last few years. Nesting, container queries, cascade layers and the :has() selector now work in every current browser, and many old tricks are no longer needed. This guide covers the fundamentals and the modern features, with short examples you can copy.

Key takeaways

Put your styles in a separate .css file and link it from your HTML. Learn the cascade, specificity and the box model first; set box-sizing: border-box everywhere. Use Flexbox for one-dimensional layouts and Grid for page layouts; floats are for wrapping text around images only. Build mobile-first with relative units, clamp() and container queries, keep design values in custom properties, and respect prefers-reduced-motion and visible focus styles.

1. Adding CSS to a page

Keep styles in their own file and link it in the page's head:

html
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="css/styles.css">
</head>

The viewport line is essential for mobile layouts. Inline style attributes work but are hard to maintain and override, so use them only for one-off values set by scripts.

A rule is a selector followed by declarations:

css
p {
  color: #333;
  line-height: 1.6;
}

2. Selectors, the cascade and specificity

Common selectors:

css
p { }                     /* element */
.card { }                 /* class */
#site-header { }          /* id */
input[type="email"] { }   /* attribute */
a:hover, a:focus-visible { } /* pseudo-classes */
.card > h2 { }            /* direct child */
.card:has(img) { }        /* a card that contains an image */
p::first-line { }         /* pseudo-element */

When two rules target the same element, the browser decides in this order:

  1. Origin and importance: !important declarations beat normal ones.
  2. Cascade layers: styles in later @layer blocks win over earlier ones; unlayered styles win over all layers.
  3. Specificity: an ID beats a class, and a class beats an element selector.
  4. Order: if everything else is equal, the rule that comes last wins.

Style with classes rather than IDs; IDs have very high specificity and are hard to override. Avoid !important except for small utility classes. The :where() selector has zero specificity, which makes base styles easy to override:

css
:where(ul, ol) { padding-left: 1.25rem; }

Cascade layers let you order whole groups of styles, so a third-party stylesheet never fights your own:

css
@layer reset, vendor, base, components, utilities;

@layer base {
  body { font-family: system-ui, sans-serif; }
}

3. The box model

Every element is a box made of content, padding, border and margin. By default, width sets the content width only, so padding and border make the box bigger. Almost every project starts with:

css
*, *::before, *::after {
  box-sizing: border-box;
}

Now width includes padding and border. Margins push boxes apart; padding adds space inside. Use the gap property in Flexbox and Grid instead of margins between items.

Logical properties such as margin-inline, padding-block and inline-size follow the writing direction, so layouts also work for right-to-left languages.

4. Layout: Flexbox and Grid

Flexbox arranges items in one direction, a row or a column. It is ideal for navigation bars, toolbars and centring:

css
.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

Grid handles two dimensions, rows and columns together. This pattern makes a responsive card grid without any media query:

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

Named areas make whole-page layouts readable:

css
.page {
  display: grid;
  grid-template-areas: "header" "main" "footer";
}
@media (min-width: 60rem) {
  .page {
    grid-template-columns: 16rem 1fr;
    grid-template-areas: "header header" "sidebar main" "footer footer";
  }
}

Use position: sticky for headers that stay in view, and position: absolute only inside a parent set to position: relative. Floats are now only for wrapping text around an image.

5. Responsive design

  • Mobile first. Write the base styles for small screens, then add min-width media queries for larger ones.
  • Relative units. Use rem for font sizes and spacing so text respects the visitor's settings, and %, fr or viewport units for layout.
  • Fluid type with clamp(). One line replaces several breakpoints: font-size: clamp(1.5rem, 1rem + 2vw, 2.5rem);
  • Container queries. A component can adapt to the space it has, not to the whole screen:
css
.sidebar { container-type: inline-size; }

@container (min-width: 30rem) {
  .product-card { display: grid; grid-template-columns: 8rem 1fr; }
}
  • Responsive images. Add max-width: 100%; height: auto; to images so they never overflow their container.

6. Custom properties, colour and fonts

Custom properties (CSS variables) keep design values in one place and can change at runtime, for example for a dark theme:

css
:root {
  --brand: #1d4ed8;
  --text: #1f2937;
  --bg: #ffffff;
}
@media (prefers-color-scheme: dark) {
  :root { --text: #e5e7eb; --bg: #111827; }
}
body { color: var(--text); background: var(--bg); }
.button { background: var(--brand); }
.button:hover { background: color-mix(in oklch, var(--brand), black 15%); }

color-mix() replaces most colour functions that once needed Sass. Check text contrast against WCAG guidance: at least 4.5:1 for normal text.

For fonts, a system font stack (system-ui, sans-serif) loads instantly. For a web font, load it with a link tag in the HTML head rather than @import inside your CSS, which delays rendering. Self-hosted fonts should be WOFF2 files with font-display: swap.

7. Native nesting and when you still need Sass

Nesting now works in plain CSS:

css
.card {
  padding: 1rem;
  & h2 { margin-top: 0; }
  &:hover { box-shadow: 0 4px 12px rgb(0 0 0 / 0.1); }
}

With nesting, custom properties, color-mix() and layers, many projects no longer need a preprocessor. Sass is still useful for large codebases with mixins and loops. If you use it, use the Dart Sass module system (@use, and color.adjust() or color.scale() instead of the old darken() and lighten()). A build tool such as Lightning CSS, or PostCSS with Autoprefixer and cssnano, adds any vendor prefixes your browser targets still need and minifies the output.

8. Transitions, animation and accessibility

css
.button {
  transition: background-color 0.2s ease, transform 0.2s ease;
}
.button:hover { transform: translateY(-1px); }

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

Animate transform and opacity, which are cheap for the browser, rather than width, top or margin. Always keep a visible focus style for keyboard users. Style :focus-visible rather than removing outlines.

9. Keeping CSS fast and maintainable

  • Use one naming convention for classes (for example BEM, or a utility framework such as Tailwind CSS) and stick to it.
  • Remove unused CSS; large frameworks ship far more than a small site needs.
  • Keep selectors short and flat; deep chains are slow to read and hard to override.
  • Minify CSS for production and serve it compressed.
  • Use your browser's developer tools (right-click, Inspect) to see which rule won and why; the Styles panel shows overridden declarations struck through.

10. Running this on Domain India

On Domain India shared hosting (cPanel, DirectAdmin or Webuzo), CSS files are static files: upload them with File Manager or FTP into your site's folder, for example public_html/css/. See How do I use the File Manager and What settings do I need to upload my website.

If an updated stylesheet doesn't appear, your browser or a cache in front of the server may still hold the old copy. Change the file reference each time you publish, for example styles.css?v=2, and do a hard refresh (Ctrl+F5, or Cmd+Shift+R on a Mac).

On WordPress, add small changes under Appearance › Customize › Additional CSS in classic themes, or under Styles in the Site Editor for block themes, rather than editing theme files that an update overwrites. See the WordPress guide.

cPanel Starter
₹125/mo + GST
  • 25 GB NVMe SSD Storage
  • 50 GB Monthly Bandwidth
  • 1 Website
  • 10 Email Accounts
See plan details
Should I use Flexbox or CSS Grid?

Use Flexbox to arrange items in one direction, such as a navigation bar or a row of buttons. Use Grid for two-dimensional layouts with rows and columns, such as a page layout or a card gallery. Many pages use both.

Do I still need Sass in 2026?

Often not. Plain CSS now has nesting, custom properties, color-mix() and cascade layers, which cover most reasons people used Sass. Sass is still useful for large codebases that rely on mixins and loops.

Why is my CSS change not showing on my website?

Usually the browser or a server cache still holds the old file. Add a version to the link, such as styles.css?v=2, and hard-refresh the page. If it still does not change, check in the browser's developer tools that another rule with higher specificity is not overriding yours.

What does box-sizing: border-box do?

It makes an element's width and height include its padding and border, so adding padding no longer makes the box wider than you set. Most projects apply it to every element.

What are container queries?

Container queries let a component change its layout based on the width of its own container instead of the whole screen. The same card can then show one layout in a narrow sidebar and another in a wide main column.

How do I make my CSS accessible?

Keep text contrast high, use rem units so text respects the visitor's font size, keep a visible :focus-visible style for keyboard users, and reduce animations when the visitor has prefers-reduced-motion set.

Ready to publish your design? Compare cPanel hosting and DirectAdmin hosting plans, or use the AI Website Builder if you'd rather not write CSS at all.

Host your website

Shared hosting with a control panel, free SSL and File Manager for uploading your HTML and CSS.

See hosting plans

Was this article helpful?

Your answer helps us decide what to improve next.

Still need help? Open a support ticket and our team will reply.

Prefer an app? Add this site to your home screen.Get the app
Modern CSS Guide: Selectors, Grid, Flexbox & More