CSS Introduction

What CSS is, selector and property syntax, the three ways to include CSS, and specificity basics.

What is CSS?

CSS (Cascading Style Sheets) controls how HTML elements are presented — colors, fonts, spacing, layout, animation. HTML describes what content is; CSS describes how it looks. Separating the two means the same markup can be restyled completely (a redesign, a dark theme, a print layout) without touching a single line of HTML.

Css
h1 {
    color: #1f2937;
    font-size: 2rem;
}

Syntax: selectors, properties, and values

A CSS rule pairs a selector with a block of declarations:

Css
selector {
    property: value;
    property: value;
}
Css
p {
    color: #374151;
    font-size: 16px;
    line-height: 1.5;
}
  • The selector (p) chooses which elements the rule applies to.
  • Each declaration is a property: value; pair — color: #374151; sets the color property to a specific value.
  • The whole { ... } block is a declaration block.

Common selector types

Css
/* Type selector — matches every <p> */
p { margin-bottom: 1rem; }

/* Class selector — matches elements with class="card" */
.card { border-radius: 8px; }

/* ID selector — matches the single element with id="header" */
#header { position: sticky; }

/* Descendant selector — matches <a> anywhere inside .nav */
.nav a { text-decoration: none; }

/* Direct child selector — only immediate <li> children of .menu */
.menu > li { padding: 0.5rem; }

/* Attribute selector */
input[type="email"] { border-color: #3b82f6; }

/* Pseudo-class — matches on state */
button:hover { opacity: 0.9; }

/* Pseudo-element — targets a generated sub-part */
p::first-line { font-weight: bold; }

Three ways to include CSS

1. External stylesheet (the standard, recommended approach — cacheable, reusable across pages):

HTML
<link rel="stylesheet" href="/css/styles.css">

2. Internal (embedded) stylesheet — CSS inside a <style> tag in the document's <head>:

HTML
<head>
    <style>
        body { font-family: sans-serif; }
    </style>
</head>

3. Inline styles — a style attribute directly on an element:

HTML
<p style="color: red; font-weight: bold;">Warning</p>

External stylesheets should be the default for any real project — they keep style separate from markup, are cached by the browser across page loads, and let you update the look of an entire site by editing one file. Inline styles are the least maintainable (mixed with markup, hard to override, can't be reused) and are best reserved for one-off cases like dynamically-computed values set by JavaScript.

Specificity, briefly

When multiple rules target the same element with conflicting declarations, CSS decides the winner using specificity — a weighted score, roughly:

Selector type Weight
Inline style="..." Highest
#id High
.class, [attribute], :pseudo-class Medium
element, ::pseudo-element Low
Css
p { color: blue; }          /* specificity: 0-0-1 */
.text { color: green; }     /* specificity: 0-1-0 — wins over the above */
#intro { color: red; }      /* specificity: 1-0-0 — wins over both */
HTML
<p id="intro" class="text">What color am I?</p> <!-- red — #id wins -->

If two rules have equal specificity, the one that appears later in the stylesheet wins. !important overrides normal specificity entirely and should be used sparingly — it makes styles harder to override later and is a common source of "why won't this CSS apply" debugging sessions.

The full topic (specificity math, the cascade, inheritance) is covered in more depth on the interview questions page — this is just enough to reason about simple conflicts.

Common mistakes

  • Relying on inline styles or !important to "win" a specificity fight instead of writing a more specific (or simpler) selector.
  • Forgetting that the cascade also considers source order — two equally-specific rules resolve in favor of whichever was declared last.
  • Over-using #id selectors for styling — IDs have very high specificity, which makes later overrides painful; classes are the idiomatic default for reusable styling.