The idea
HTML says what things are; CSS (Cascading Style Sheets) says how they look. A stylesheet is a list of rules, and each rule says "for these elements, set these properties":
selector {
property: value;
another-property: value;
}
Two concepts carry almost everything else in CSS: selectors (which elements a rule applies to) and the box model (how every element's size and spacing is calculated).
Adding CSS to a page
CSS usually lives in a separate file linked from the <head> (<link rel="stylesheet" href="styles.css">). For small examples, a <style> element works the same way:
<style>
h1 { color: #7a4b2a; }
p { line-height: 1.6; }
</style>
<h1>Toko Kita</h1>
<p>Freshly roasted Indonesian coffee, delivered to your door.</p>
In the exercises, the style.css tab plays the role of the stylesheet file.
Selectors
The selector is how a rule says which elements it applies to. Sometimes you want every paragraph, sometimes only the price on a product card, sometimes only links while the mouse is over them. Here are the selectors you'll use day to day, each with a comment saying what it picks:
<style>
p { color: #333; } /* type: every <p> */
.price { font-weight: bold; } /* class: every element with class="price" */
#featured { background: #fff4e5; } /* id: the one element with id="featured" */
.card h3 { margin: 0; } /* descendant: <h3> anywhere inside .card */
.card > p { color: #666; } /* child: <p> directly inside .card */
h1, h2, h3 { font-family: Georgia, serif; } /* group: same rule for several selectors */
a:hover { text-decoration: none; } /* pseudo-class: a state */
</style>
<article class="card" id="featured">
<h3>Arabica Gayo</h3>
<p>Fruity and smooth.</p>
<p class="price">Rp 95.000</p>
</article>
In practice, classes do most of the work: they're reusable, they describe a role (.card, .price, .button) and they're easy to override. Ids are unique per page and very "strong" in the cascade (module 7), so keep them for links and JavaScript, not styling.
The box model
Every element is a rectangular box made of four layers, from the inside out:
┌──────────────── margin (space outside, transparent) ────────────────┐
│ ┌───────────── border ───────────────────────────────────────────┐ │
│ │ ┌────────── padding (space inside, has the background) ────┐ │ │
│ │ │ │ │ │
│ │ │ content (width × height) │ │ │
│ │ │ │ │ │
│ │ └──────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────┘
<style>
.box {
width: 200px;
padding: 20px;
border: 5px solid #7a4b2a;
margin: 30px;
background: #fff4e5;
}
</style>
<div class="box">A box</div>
How wide is that box on screen? By default, width sets only the content, and padding and border are added on top: 200 + 20 + 20 + 5 + 5 = 250 px. Plus 30 px of margin on each side that pushes neighbours away.
box-sizing: border-box
Adding padding and making the box grow is rarely what you want. With box-sizing: border-box, width includes padding and border:
<style>
*, *::before, *::after { box-sizing: border-box; }
.box { width: 200px; padding: 20px; border: 5px solid #7a4b2a; background: #fff4e5; }
</style>
<div class="box">Exactly 200px wide, padding and border included</div>
Almost every modern stylesheet starts with that first line. Then width: 200px means 200 px on screen, and adding padding never breaks a layout.
Shorthands
Setting padding-top, padding-right, padding-bottom and padding-left one by one gets tedious. Most box properties have a shorthand that sets several sides in one line. The order to remember is clockwise from the top:
padding: 10px; /* all four sides */
padding: 10px 20px; /* top & bottom 10, left & right 20 */
padding: 10px 20px 30px 40px; /* top, right, bottom, left (clockwise) */
margin: 0 auto; /* centre a block that has a width */
border: 1px solid #ddd; /* width, style, colour */
Two things that surprise everyone once:
- Vertical margins collapse: two paragraphs with
margin: 20pxsit 20 px apart, not 40. The larger margin wins. - Inline elements (
<a>,<span>,<strong>) ignorewidth,heightand vertical margins. Setdisplay: inline-blockordisplay: blockwhen you need a box you can size.
A CSS rule is selector + declarations. Style mostly with classes. Every element is content + padding + border + margin; set box-sizing: border-box everywhere so width means the visible width.
Why this matters for clean code
Class-based selectors that describe roles (.card, .price) make CSS reusable and predictable, and a global border-box removes a whole category of layout arithmetic bugs. Clean CSS starts with the same habit as clean Python: name things by what they are, not by how they look (.price, not .bold-red-text).
Recap
- Rule =
selector { property: value; }; link a stylesheet or use<style>. - Selectors:
p,.class,#id,.a .b(descendant),.a > .b(child),a, b(group),:hover. - Box model: content → padding → border → margin.
- Default
widthis content only;box-sizing: border-boxincludes padding and border. - Shorthands go top, right, bottom, left; vertical margins collapse; inline elements ignore width/height.