One rule, three parts
A CSS rule has a selector, a property and a value.
p {
color: #333;
font-size: 16px;
}
Put your CSS in a file called style.css and link it from the head:
<link rel="stylesheet" href="style.css">
Common selectors:
p- every paragraph.card- every element withclass="card"#contact- the one element withid="contact"nav a- every link inside a nav
Use classes for styling. Use ids for linking and for JavaScript. An id must appear only once per page.
Every element is a box
This is the idea that fixes most layout confusion. Each element is a rectangle with four layers, from inside out:
- content - the text or image
- padding - space inside the box, gets the background colour
- border - the line around it
- margin - space outside the box, always transparent
Now the trap. By default, width sets the width of the content only.
.card {
width: 300px;
padding: 20px;
border: 2px solid #ccc;
}
That card is not 300px wide on screen. It is 300 + 20 + 20 + 2 + 2 = 344px. Put four of them in a 1200px row and they overflow. This one rule has broken more student layouts than any other.
The fix is one line at the top of every stylesheet:
* {
box-sizing: border-box;
}
Now width: 300px means the whole box is 300px, and padding and border eat into it from inside. Almost every real project uses this.
Margin collapse
Two vertical margins that touch do not add up. They merge, and the larger one wins.
h2 { margin-bottom: 30px; }
p { margin-top: 20px; }
The gap is 30px, not 50px. This happens only to top and bottom margins, never left and right, and never inside a flex container.
Flexbox
Before flexbox, people centred things with floats and hacks. Now one line turns an element into a row manager.
.row {
display: flex;
gap: 16px;
}
Every direct child becomes a flex item sitting in a row. The useful properties on the container:
| Property | Does |
|---|---|
flex-direction |
row (default) or column |
justify-content |
spacing along the main axis |
align-items |
alignment across the other axis |
gap |
space between items |
flex-wrap |
wrap lets items drop to a new line |
A complete, working card row:
* { box-sizing: border-box; margin: 0; }
body {
font-family: system-ui, Arial, sans-serif;
padding: 24px;
background: #f7f7f8;
}
.row {
display: flex;
gap: 16px;
flex-wrap: wrap;
}
.card {
flex: 1 1 260px;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
background: #fff;
}
.card h3 { margin-bottom: 8px; }
flex: 1 1 260px reads as: grow if there is space, shrink if there is not, and aim for 260px. Cards share the row and wrap to the next line on a phone. That is responsive design with one property.
To centre anything, both ways:
.centre {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
100vh means the full height of the viewport.
justify-content and align-items swap meaning when you set flex-direction: column. In a column, justify-content controls vertical position and align-items controls horizontal. Students set the wrong one and think flexbox is broken. It is not; the axis moved.
Why layouts break
Three causes cover most cases:
- Box sizing, as above.
- A rule you wrote is being overridden. Specificity: an id beats a class,
a class beats a tag name. Two rules of equal weight? The later one wins.
- You styled a parent when you meant the child, or the other way round.
Stop guessing. Right click the broken element, choose Inspect, and look at the Styles panel. Overridden rules appear with a line through them, and the box model diagram at the bottom shows the real pixel numbers. This is faster than adding !important and hoping.
Next: JavaScript, and how to change this page while it is running.