CSS: selectors, the cascade, and layout
Topic Slides
Agenda Slides Open fullscreen β
Open slides ↗Post-Class Notes
TL;DR#
Today we covered CSS selectors, element, class and ID, and finally answered what the "cascading" in Cascading Style Sheets means. Two classmates gave lightning talks on an AI coding startup whose agents build software on their own and on a forecasting tournament where AI took most of the top places. Before Tuesday, move your rules out of the <style> block into css/styles.css and link that file from your page.
How a project runs now#
flowchart LR
I(["`**Intent**
PROPOSAL.md
you lead, AI asks questions`"]) --> S["`**Specs**
PRD.md
AI drafts, you decide`"]
S --> M["`**Implementation**
code
agent leads, you review`"]
M --> E(["`**Evaluation**
tests, your client
agent verifies, you validate`"])
E -. verify: does it work? .-> M
E -. validate: is it what they need? .-> Iflowchart LR
I(["`**Intent**
PROPOSAL.md
you lead, AI asks questions`"]) --> S["`**Specs**
PRD.md
AI drafts, you decide`"]
S --> M["`**Implementation**
code
agent leads, you review`"]
M --> E(["`**Evaluation**
tests, your client
agent verifies, you validate`"])
E -. verify: does it work? .-> M
E -. validate: is it what they need? .-> I
classDef ends font-size:22px,stroke-width:4px
classDef mid opacity:0.4
class I,E ends
class S,M midCoding classes used to spend most of their time on the code. A coding agent now writes most of it, so the work that decides whether a project succeeds sits at the two ends.
Intent. Why the project should exist. It can come from a client or from you, and in the real world it turns up in a conversation, an email, a message or a note to yourself. In this course you write it down in PROPOSAL.md. AI can help by interviewing you, and the answers are still yours to give.
Specs. What to build: every page, the navigation, the content and the look. Add two or three things a visitor must be able to do, such as "find the next meeting from a phone in under 10 seconds". Those sentences are what you will evaluate against. In this course the specs go in PRD.md. AI can draft it from your interview; you decide what stays.
Implementation. Ask the agent to read PRD.md and propose a plan before it writes anything, and approve the plan first. AGENTS.md holds the rules it follows on every request. From there the agent writes most of the code.
Evaluation asks two questions, which software engineers call verification and validation. Verification asks whether it works: links go where they should, the page reads on a phone, nothing breaks. The agent can check much of this for you. Validation asks whether it is what the client needs, and only you and the client can answer that, by putting the page in front of them.
Most projects go around this loop several times. A broken link sends you back to the code. A client who sees the page and says "that is not quite it" sends you back to the intent. Because an agent can build a rough first version in minutes, showing the client a draft early is one of the fastest ways to find out what they actually want.
On Tuesday we will turn a PROPOSAL.md into a PRD.md together.
Where CSS can live#
You have now seen all three:
- Inline, as a
styleattribute on a single tag - A
<style>block inside<head> - An external file, linked from
<head>
The third one is the one to use. The reasons came out of class:
- You change one file instead of every page that uses that style.
- Several pages linking the same file look like one website. That matters for your project, where every page should belong to the same site.
Inline styles work for a quick test, and they are hard to maintain, so take them out afterwards.
Moving your CSS into a file#
Please go through the CSS Essentials slides on your own before Tuesday and do every exercise on them. The last two matter most, and this is the first of them:
- Create
css/styles.cssin youroim3690repository and paste your rules into it. - Delete the
<style>block fromabout-me.html. - Link the file instead, inside
<head>:
<link rel="stylesheet" href="css/styles.css">- Reload. The page should look exactly as it did before.
If the page loses its styling, the href does not match where the file actually sits. That is the whole demonstration from the start of class: the file moved into a folder, and the link still pointed at the old place.
Then write three more rules yourself: one on your <h1>, one on a class you invent, and one a:hover. Add a rule that conflicts with another one, open DevTools, and see which wins.
Then ask AI to polish it, and read every rule before you accept it.
The file name matters. Several of the stylesheets in this class are called style.css, styles.css or about-me.css, in different folders, because an agent picked the name. Use css/styles.css.
Which URL opens a file in your course repo#
Your oim3690 repository is served under its own name:
https://<your-github-username>.github.io/oim3690/about-me.htmlYour personal site is a separate repository, and it is served at the root:
https://<your-github-username>.github.io/index.html is the home page of a folder, so you never have to type it.
Selectors#
How to say which elements a rule applies to:
- Element selector:
p { }styles every paragraph. - Class selector:
.card { }styles every element whoseclassiscard. - ID selector:
#interests { }styles the one element whoseidisinterests.
A class labels elements as the same kind of thing. That is why an agent gives three boxes the same class: it is saying these three are cards, style them together.
We built up to this in class from a real problem. To make one paragraph match the heading:
h1, p { }makes them share the whole rule, which is wrong when the fonts should differ.p { }hits every paragraph on the page.- Wrapping the heading and that paragraph in a
<div class="highlight">and writing.highlight { }targets exactly those two.
Once you can read class names, you can read most of the CSS an agent writes for you. .container, .interest-card and .footer-content each map onto a visible part of the page.
ID has one job class cannot do: in-page links. <a href="#academics"> jumps to the element whose id is academics, which is how the section links on most long pages work. For styling, use class.
What "cascading" means#
When several rules target the same element and the same property, the browser compares them roughly in this order:
- How specific the selector is. An ID beats a class, and a class beats an element name.
- Source order. When two rules tie on specificity, the one written later wins.
An inline style attribute sits above any rule in a stylesheet, no matter where that rule appears, which is why moving a rule further down the file will not beat it.
!important sits above the whole comparison. It wins wherever you put it and whatever selector it is attached to. Use it rarely, because it is the thing that makes the next conflict harder to debug.
So a stylesheet saying p { color: red; } and then p { color: blue; } gives you blue. This happens constantly on real sites, because a stylesheet is written across months by several people.
For your project, you will rarely need to reason about specificity. When a rule seems to have no effect, open DevTools, find the element, and look at which rule is crossed out.
Pseudo-classes and combining selectors#
a:hover { color: orange; }applies while the pointer is over the link. You can change the background and remove the underline withtext-decoration: nonethe same way.:nth-child(even)styles every second item, which is how table rows get their stripes without naming each one.nav a { }matches only the links inside<nav>. The space means "inside". Take thenavaway and the rule matches every link on the page.
Recognize these when you read them. Memorizing the syntax is not the point.
Colors#
- A name, such as
red rgb(255, 0, 0), three channels from 0 to 255#ff0000, the same three numbers written in base 16rgba(255, 0, 0, 0.5), where the fourth value is transparency
red and rgb(255, 0, 0) are the same color. Lowering a channel darkens it, so rgb(100, 0, 0) is a dark red. All three channels at 255 is white and all three at zero is black.
Three channels of 256 values give about 16 million colors, which is why most of them have no English name. You do not need to convert hex by hand. You need to recognize that #006644 is three numbers.
Fonts#
A font-family rule usually lists several fonts:
font-family: "Fig Tree", Helvetica, sans-serif;That list is a fallback chain for the machine reading your page. If the first font is missing or cannot be downloaded, the browser tries the next one. The list is not a way to use different fonts in different places.
Learn CSS by inspecting#
Right-click anything on any page, choose Inspect, and the right-hand panel shows the CSS that produced it. That is how to find out what font a site uses, how a hover effect was built, or why your own rule is not applying.
We also opened a real, live stylesheet in class. It was long, minified and messy, because a large site loads several stylesheets maintained by different people. The structure underneath is the same thing you are writing: a selector and a set of rules.
File and folder names#
A file name with a space in it becomes %20 in a URL and often will not open the way you expect. A file with no extension will download instead of opening in the browser. Keep names lowercase, put hyphens between words, and give every file its extension: lightning-talk.pdf.
Lightning talks#
The first talk covered Factory, which raised $200 million this week at a valuation that tripled in five months. Its product is a set of agents called Droids that write, test, review and deploy code across an engineering team, rather than completing lines inside an editor. The talk's question was what a good programmer still needs to know when AI writes most of the code, and the room argued for judgment, domain expertise, security awareness and systems thinking.
A few things from the discussion:
Prompt engineering has already shifted. Most of the tricks people collected and bookmarked two years ago no longer apply, so building a habit around any one of them is a poor investment.
Judgment and taste are the two words this course leans on most, and they are genuinely hard to teach. Domain knowledge is easier to point at. You are building for a client in a field, and knowing accounting, or retail, or sport, is the part AI cannot supply about your particular client.
Recursive self-improvement is the term that came up for using AI to improve AI. Today the next generation of a model is designed and trained by people. The question raised in class was what happens to the pace of everything, including scientific research, once a model is good enough to do that work on the model that replaces it.
The second talk covered the Metaculus Cup, a quarterly forecasting tournament where AI entrants took most of the top places, and where that leaves human forecasters. The discussion covered insider information, odds that move during a live event, and whether moral judgment is something a model can hold.
The stock market is the oldest prediction market there is, it is open to you, and studying a company and taking a position is the same exercise with far more public information behind it.
Both talks were built the way this course asks for, including one made by pointing Copilot at a reference site and then adjusting what came back. When you present, set the text larger than you would on your own laptop, because the room reads it from 20 feet away.
Claim your own slot on the lightning board.
What Is Next#
Go through the CSS Essentials slides and do every exercise on them. In your oim3690 repository that leaves you with:
about-me.html, with rules of your own.css/styles.css, linked from the page, and the<style>block gone.logs/wk03.md, with the same four prompts as the last two weeks.
Mini Project 1: ideally, by Tuesday, have your client interview done and PROPOSAL.md in the project repository. The times table in the spec is a suggested pace. The deadline is 9/29.
On Tuesday we will turn a proposal into a PRD together, using your personal site as the example, and cover the box model and Flexbox so a page holds its layout on a phone.