Sites, apps, and email
Marketing pages, dashboards, docs, and many HTML emails are styled with CSS. Learn it once and you can read other people’s stylesheets.

CSS stands for Cascading Style Sheets. It is the language that gives a web page its look: color, type, spacing, layout, and motion. HTML holds the words and pictures. CSS styling decides how they appear.
Without CSS, the browser shows a plain document. With CSS, the same HTML can become a product page, a dashboard, or a phone layout. That is the whole job of this CSS tutorial: take structure you already have and make it clear, usable, and pleasant to look at.
It describes presentation. It does not loop, calculate a shopping cart, or listen for clicks. Pair it with HTML for structure and JavaScript when the page needs behavior.
If you want to build anything people see in a browser, CSS is part of the job. You do not need to memorize every property. You need the ideas that show up on every site.
Marketing pages, dashboards, docs, and many HTML emails are styled with CSS. Learn it once and you can read other people’s stylesheets.
A shared stylesheet keeps buttons, headings, and spacing consistent. Change the file, and every page that links it picks up the new CSS styling.
The same HTML can stack on a phone and spread out on a desktop. Media queries, Flexbox, and CSS Grid are how modern interfaces do that.
Save the file and refresh. Color, type, and layout update immediately, which makes CSS for beginners a good second step after HTML.
You write rules. The browser matches those rules to HTML elements, settles conflicts, then paints pixels.
<style> blocks, and style attributes.p or .card names which elements receive the declarations.Cascading means more than one rule can apply to the same element. The browser does not mix two competing colors. It chooses one.
| Question | What wins |
|---|---|
Is one declaration marked !important? | That declaration wins. Treat this as a last resort. It is hard to override later. |
| Which selector is more specific? | An inline style beats an ID. An ID beats a class. A class beats an element name. |
| Are the selectors equally specific? | The rule that appears later in the stylesheet wins. |
Here a class and an element both set color. The class is more specific, so the paragraph is teal:
This line uses only a p rule, so it stays slate.
This line also has a class. The class color wins.
p {
color: #334155;
}
.intro {
color: #0f766e;
} Some properties pass from a parent to its children. color and font-family do. margin, padding, border, and background do not. The box below sets a teal color. The paragraphs inside inherit it. The padding stays on the box.
This text inherits the parent color.
The parent’s padding does not become the paragraph’s padding.
Set the font and text color on body. Children inherit them, so you do not repeat those declarations on every element.
There are three ways to attach CSS styling to HTML. The rule looks the same. Only the location changes. Real projects almost always use an external file.
A style attribute. Fast for a test. Awkward to reuse, and it beats normal selectors in the cascade.
style="color: #0f766e;"A <style> element. Handy for a single demo or this tutorial’s examples.
<style> p { color: #0f766e; } </style>A .css file linked from <head>. One file can style the whole site, and the browser can cache it.
<link rel="stylesheet" href="styles.css"><head>
<link rel="stylesheet" href="styles.css">
</head> The next lesson, How to Use CSS, walks through each method with an editor.
Skip @import for your main file. A <link> in the head loads the stylesheet earlier. @import inside a CSS file waits until that file is read, which can slow the first paint.
A rule has a selector and a declaration block. Each declaration is a property, a colon, a value, and a semicolon.
selector {
property: value;
}
h1 {
color: #0f766e;
font-size: 2rem;
} h1 means every top-level heading.property: value; pair. End it with a semicolon.You can also nest rules. The heading rule below applies only to an h2 inside .card. The & refers to .card itself:
.card {
padding: 1rem;
h2 {
margin: 0 0 0.5rem;
}
&:hover {
border-color: #0f766e;
}
} .card, .btn.bgcolor..Card when the HTML says class="card".!important because a selector did not match.A selector is the part of the rule that finds elements. These four cover most beginner pages. The full set lives in the CSS selectors lesson.
| Selector | Matches | Example |
|---|---|---|
| Element | Every tag of that type | p { } |
| Class | Elements with that class | .card { } and class="card" |
| ID | The one element with that id | #hero { } |
| Descendant | An element inside another | .card p { } |
Prefer classes for reusable components. An ID is very specific, so it is harder to override. Group selectors with a comma when they share declarations: h1, h2 { font-family: system-ui, sans-serif; }.
A property is what you change. A value is the setting. The browser ignores a declaration it does not understand, so a typo fails quietly.
| Property | What it controls | Example value |
|---|---|---|
color | Text color | #0f766e |
font-size | Type size | 1.125rem |
margin | Space outside the border | 1rem 0 |
display | How the box participates in layout | flex |
background | Fill behind the content | #f0fdfa |
16px, 1rem, 100%. width: 100 is invalid. 0 may omit the unit.margin: 1rem 2rem is shorthand. The first value is top and bottom. The second is left and right.People use “types of CSS” for the three ways a rule can be attached. They differ in scope, reuse, and how strongly they compete in the cascade.
| Type | Scope | Best for | Watch out |
|---|---|---|---|
| Inline | That one tag | A quick experiment | Beats class and element selectors |
| Internal | The current document | A single demo page | Copied styles drift apart across pages |
| External | Every page that links the file | A real website | The path in href must be correct |
Write external CSS for anything you will keep. Use internal CSS while you are learning a single example. Leave inline CSS for rare one-off cases.
You do not need all of these on day one. Knowing the names helps you pick the right tool when a layout or theme comes up.
Specificity and order decide which rule paints an element when several match.
Content, padding, border, and margin are how spacing actually works.
Modern layout. Flexbox lines items up. CSS Grid builds rows and columns.
Fluid sizes plus media queries and container queries adapt the page to the screen.
Named values such as --brand keep colors and spacing consistent.
Transitions, transforms, and keyframe animations add feedback without JavaScript.
:hover, :focus-visible, and ::before style states and extras.
Write related rules inside a parent selector so a component stays in one place.
Every element is a rectangle. Four layers sit around the words or image. Once you can see them, margin and padding stop feeling random.
Outside in: margin, then border, then padding, then the content.
| Layer | Role |
|---|---|
| Content | The text, image, or child elements |
| Padding | Space between the content and the border. It takes the background color. |
| Border | The line around the padding. It can be solid, dashed, or transparent. |
| Margin | Space outside the border. It separates this box from its neighbors. It is transparent. |
*,
*::before,
*::after {
box-sizing: border-box;
}
.card {
width: 20rem;
padding: 1.25rem;
border: 2px solid #cbd5e1;
margin: 1.5rem auto;
} border-box.The initial value, content-box, adds padding and border on top of width, so a “20rem” card becomes wider than 20rem. border-box includes them in the width you set. Put it on every element at the top of your stylesheet.
Logical properties such as padding-inline and margin-block follow the writing direction. They are the modern stand-in for physical left and right when a page may be right-to-left.
Color is usually the first property people try. Prefer values you can repeat: a hex code, or a custom property that stores it.
.hero {
color: #ffffff;
background-color: #0f766e;
background-image: linear-gradient(#0f766e, #115e59);
} teal, white. Fine for a demo. Easy to outgrow.#0f766e. Six digits: red, green, blue.rgb(15 118 110), hsl(175 80% 26%), and modern oklch() when you want more predictable lightness.background-color, images, and linear-gradient(). Check that text on the background still meets contrast.Typography is hierarchy: a clear heading, a comfortable paragraph, and a line length that is easy to scan. You get most of that from a small set of CSS properties.
body {
font-family: system-ui, sans-serif;
font-size: 1rem;
line-height: 1.6;
}
h1 {
font-size: clamp(1.75rem, 4vw, 2.5rem);
line-height: 1.2;
} rem is relative to the root font size, so it respects a reader who enlarges text in the browser. clamp() picks a size between a minimum and a maximum as the viewport changes. List a fallback in font-family in case the first face is missing.
Layout is how boxes share the page. Start with display and position. Use Flexbox for one direction and CSS Grid when you need both rows and columns.
Items share a line. flex: 1 gives each an equal slice of free space.
display: flex;
A header spans both columns. The two cells below sit side by side.
display: grid;
The badge is absolute. It anchors to the relative parent, not the whole page.
| Tool | Use it when |
|---|---|
display: block and inline | Normal document flow. Headings stack. Links sit in a sentence. |
| Flexbox | A nav, a toolbar, a row of cards, or centering one item. |
| CSS Grid | A page with a header, sidebar, and main area. |
position | relative offsets a box. absolute and fixed take it out of flow. sticky sticks while scrolling. |
.row {
display: flex;
gap: 0.75rem;
}
.page {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 1rem;
}
.badge {
position: absolute;
top: 0.5rem;
right: 0.5rem;
} Floats used to build whole pages. Today, use a float only to wrap text around an image. Reach for Flexbox or Grid for layout.
Responsive web design means one page that fits the screen in front of the reader. Mobile-first means you write the small-screen layout first, then add rules for wider screens.
This preview uses a container query. Narrow the window and the three regions stack. Widen it and they sit in a row. The query watches this component, not the whole browser.
max-width, %, fr, and gap instead of a fixed 960px page.img { max-width: 100%; height: auto; } so pictures shrink with the column..panel {
container-type: inline-size;
}
@container (min-width: 36rem) {
.panel-title {
font-size: 1.5rem;
}
} The query watches an ancestor. Put container-type on the parent, then style the children inside @container.
A media query applies rules when a condition is true. For layout, that condition is usually a minimum viewport width. Write the phone styles first, then enhance.
.cards {
display: grid;
gap: 1rem;
}
@media (min-width: 48rem) {
.cards {
grid-template-columns: 1fr 1fr;
}
} Below 48rem the cards stack, because a single column is the default. At 48rem and up they form two columns. More patterns are in CSS media queries. Related at-rules such as @media and @layer are grouped under at-rules.
A zoomed browser or a long translation can wrap a “desktop” layout. min-width in rem tracks the root font size, which helps when readers enlarge text.
Motion should explain a change: a button lifts, a panel fades in. CSS can do that without JavaScript.
| Feature | What it does |
|---|---|
transition | Animates a property from the old value to the new one. Ideal for hover and focus. |
transform | Moves, scales, or rotates an element. Prefer this over animating top or width. |
@keyframes | A multi-step animation you start with the animation property. |
.btn {
transition: transform 0.25s ease;
}
.btn:hover {
transform: translateY(-3px);
}
@media (prefers-reduced-motion: reduce) {
.btn {
transition: none;
}
} If someone has asked their system to reduce motion, drop the transition. The button can still look the same. It just should not move.
Pseudo-classes match a state. Pseudo-elements style a part of an element that is not its own HTML tag. Write pseudo-elements with two colons.
| Selector | Kind | Typical use |
|---|---|---|
:hover | Pseudo-class | Pointer is over the element |
:focus-visible | Pseudo-class | Keyboard focus ring, without a ring on every mouse click |
:nth-child() | Pseudo-class | Style every odd row, or the third card |
::before / ::after | Pseudo-element | Decorative marks. They need a content value, even if it is empty. |
A custom property is a value you name yourself. It starts with two dashes. var() reads it. Change the name once, and every use updates. These are live in the browser, unlike variables in a preprocessor.
The border and the heading use var(--brand). The radios swap that custom property with :has(). No JavaScript required.
:root {
--brand: #0f766e;
--ink: #0f172a;
}
button {
background: var(--brand);
color: #fff;
} Define shared tokens on :root. Override --brand on a section when that region needs a different theme. Custom properties inherit, so children see the nearest value.
Each language has one main job. Mixing them is what makes a page. Confusing them is what makes a page hard to change.
| HTML | CSS | JavaScript | |
|---|---|---|---|
| Role | Structure and meaning | Presentation and layout | Behavior |
| You write | Tags such as <h1> and <p> | Rules such as p { } | Functions and events |
| Example | A button exists | The button is teal and padded | A click submits the form |
| Kind of language | Markup | Style sheets | Programming |
If the change is visual, reach for CSS first. Hover colors, show-and-hide panels, and many menus do not need a script. Use JavaScript when the page must remember state, talk to a server, or change content.
This introduction is the map. Each card is a topic you can open next. Start anywhere, or follow the roadmap underneath.
Attach a rule
Inline, internal, and external styles, and what happens when a later rule repeats a property.
Find elements
Elements, classes, attributes, and combinators. The matching half of every CSS rule.
Set values
The CSS properties catalog: what each property changes and which values it accepts.
Space and size
Padding, border, margin, and border-box. The diagram on this page is the short version.
One axis
Rows, columns, equal-height items, and alignment. The layout you will use every week.
Two axes
Page regions, tracks, and gaps. Grid and Flexbox work together on real interfaces.
Follow this order if you are new. Each step is short enough to practice the same day.
When a rule looks wrong, check the selector, then specificity, then whether a later rule replaces it. Comments that explain a tricky value help. The comments lesson shows the syntax. An editor with highlighting is covered in CSS editors.
You can start this CSS tutorial with three things. Nothing to install beyond a browser and a text editor.
Know <h1>, <p>, <a>, and class. The HTML introduction is enough to begin.
Chrome, Firefox, Edge, or Safari. Use the page inspector when a rule does not apply. It shows the winning declaration.
Any editor that saves .html and .css files. The Try It Yourself buttons on this site work in the browser too.
This page styles itself with an internal stylesheet. It uses custom properties, a system font, and a heading size that scales between two limits. Open it, then change --brand.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My first styled page</title>
<style>
:root {
--ink: #0f172a;
--brand: #0f766e;
--paper: #f0fdfa;
}
body {
margin: 0;
font-family: system-ui, sans-serif;
line-height: 1.6;
color: var(--ink);
background: var(--paper);
}
header {
background: var(--brand);
color: #fff;
padding: 2rem 1.25rem;
}
h1 {
margin: 0;
font-size: clamp(1.75rem, 4vw, 2.5rem);
}
main {
max-width: 40rem;
margin: 0 auto;
padding: 1.5rem 1.25rem 3rem;
}
</style>
</head>
<body>
<header>
<h1>Welcome to my page</h1>
</header>
<main>
<p>This started as plain HTML. CSS added the color, type, and spacing.</p>
</main>
</body>
</html> :root stores the ink, brand, and paper colors as custom properties.body uses those variables for text and background, and removes the browser’s default margin.header paints the brand color. main keeps the paragraph in a readable column.A class selector version of a smaller demo is in the button example.
selector { property: value; }. Classes are the selectors you will reuse.Next step: put a rule on a real page in How to Use CSS.
CSS stands for Cascading Style Sheets. One external file can style every page on a site. Change a single custom property, such as --brand, and every button that uses it updates.
Attach your first rule with a style attribute, a style element, or a class.
11 people found this page helpful