Introduction to CSS
ZOOOOOOM!
Is everything big enough and are we in dark mode?
An Introduction to CSS
Agenda
- Basic Syntax
- Selectors
- Cascade
- Box Model
- Flow Layout
- Debugging
Let's get some markup
Well, we need something to style
<div class="overview">
<h1>Syntax Overview</h1>
<p>Some things you can see in this example:</p>
<ol class="features">
<li>Declarations</li>
<li>Rules</li>
<li>Resets/Normalizations</li>
<li class="fancy">Class selectors</li>
<li>Psuedo-class selectors</li>
</ol>
<blockquote>Then - like just draw the rest of the owl</blockquote>
</div>
Syntax Overview
Some things you can see in this example:
- Declarations
- Rules
- Resets/Normalizations
- Class selectors
- Psuedo-class selectors
Then - like just draw the rest of the owl
Now let's style it
<div class="overview">
<h1>Syntax Overview</h1>
<p>Some things you can see in this example:</p>
<ol class="features">
<li>Declarations</li>
<li>Rules</li>
<li>Resets/Normalizations</li>
<li class="fancy">Class selectors</li>
<li>Psuedo-class selectors</li>
</ol>
<blockquote>Then - like just draw the rest of the owl</blockquote>
</div>
h1 {
color: lightblue;
margin: 0px;
}
.overview {
padding: 1rem;
transition: all 300ms;
border: solid 4px transparent;
}
.fancy {
text-decoration: underline;
}
.overview:hover {
border-color: lightblue;
}Syntax Overview
Some things you can see in this example:
- Declarations
- Rules
- Resets/Normalizations
- Class selectors
- Psuedo-class selectors
Then - like just draw the rest of the owl
Selectors
/* Element */
h1 {}
/* ID */
#thing-id {}
/* Class */
.some-class {}
/* Attribute */
some-selector[myattr="value"] {}
/* Psuedo-class */
some-selector:psuedoclass {}Combining Selectors (Combinators)
<div class="a">
<div class="b">First child of A that is B</div>
<div class="b">Other B Child</div>
<div>
<div class="b">Nested B Child</div>
</div>
<div class="b">Another B Child</div>
<div class="c">Some other content in A</div>
</div>
<div class="b">B as a sibling of A</div>
<div class="b">Some other B sibling of A</div>
First child of A that is B
Other B Child
Nested B Child
Another B Child
Some other content in A
B as a sibling of A
Some other B sibling of A
Combinators
<div class="a">
<div class="b">First child of A that is B</div>
<div class="b">Other B Child</div>
<div>
<div class="b">Nested B Child</div>
</div>
<div class="b">Another B Child</div>
<div class="c">Some other content in A</div>
</div>
<div class="b">B as a sibling of A</div>
<div class="b">Some other B sibling of A</div>
/* Descendant */
.a .b { background-color: green; }
/* Child */
.a > .b { background-color: blue; }
/* Next-sibling */
.a + .b {background-color: red; }
/* Multiple */
.a, .b, .c { padding: 1rem; }
First child of A that is B
Other B Child
Nested B Child
Another B Child
Some other content in A
B as a sibling of A
Some other B sibling of A
The Cascade
- CSS stands for "Cascading Style Sheets"
- The Cascade determines which specific styles get applied to an element
- Specificity of a selector matters
- Order of rules matter
Specificity
- Used by browser to determine the most relevant declaration
- Based on the selector used
- Type of selector, combinators used, and level of impact this
Order
- Where is the style in the stylesheet
- Used to break ties in specificity
Calculated Specificity
Rules for specificity are pretty tricky, but your IDE should show this to you when hovering over a class
<div id="a" class="a">
<div class="b">First child of A that is B</div>
<div class="b">Other B Child</div>
<div>
<div class="b">Nested B Child</div>
</div>
<div class="b">Another B Child</div>
<div class="c">Some other content in A</div>
</div>
<div class="b">B as a sibling of A</div>
<div class="b">Some other B sibling of A</div>
<blockquote>
Note that all content in A is now Green. The Selector with the higher
specificity takes priority even though it is defined earlier in the stylesheet
</blockquote>
/*1,1,0*/
#a .b { background-color: green; }
/*0,1,0*/
.b { background-color: blue; }
/*0,2,0*/
.a + .b {background-color: red; }
.a, .b, .c { padding: 1rem; }First child of A that is B
Other B Child
Nested B Child
Another B Child
Some other content in A
B as a sibling of A
Some other B sibling of A
Note that all content in A is now Green. The Selector with the higher specificity takes priority even though it is defined earlier in the stylesheet
Psuedo-class Selectors
- Used in addition to other selectors
- Select an element based on DOM state
Some common Psuedo-classes
<label>
An Email Input
<input type="email" id="email" pattern=".+@.+\..+" size="30" required />
</label>
input {
color:black;
padding: 1rem;
font-size: large;
font-weight: bold;
border: 4px solid black;
outline: none;
}
input:focus {
background-color: plum;
}
input:hover {
background-color: lightblue;
}
input:invalid {
border-color: lightcoral;
}
input:valid {
border-color: aquamarine;
}
The Box Model
Rectangles all the way down
<div class="example">
<div class="before">before block</div>
<div class="box"><div class="content">content</div></div>
<div class="after">after block</div>
</div>
.example {
background-color: lightblue;
}
.before, .after {
padding: 10px;
background-color: lightgrey;
}
.content {
background-color: lightgrey;
height: 50px;
}
.box {
background-color: lightcoral;
border: 1rem solid lightgreen;
padding: 2rem;
margin: 3rem;
}
before block
content
after block
Flow - Block vs Inline Block
- Default layout Mode
- Block elements are placed top-to-bottom
- Inline elements are placed left-to-right and wrap with reading width
- Layout behaves and interacts differently
- Sizing is calculated differently
- Some properties will behave differently based on this
<div class="example">
<div class="spacer">spacer</div>
<div class="block">block</div>
<div class="block">block</div>
<div class="spacer">spacer</div>
<div class="inline">inline</div>
<div class="inline">inline</div>
<div class="spacer">spacer</div>
<div class="inline-block">inline-block</div>
<div class="inline-block">inline-block</div>
<div class="spacer">spacer</div>
</div>
spacer
block
block
spacer
inline
inline
spacer
inline-block
inline-block
spacer
Debugging
Firefox has the best CSS Tooling (in general)
- Hover tooltips
- CSS Overrides
- HTML Breakpoints
- Flex and Grid Tools
<div class="example">
<div class="before">before block</div>
<div class="box"><div class="content">content</div></div>
<div class="after">after block</div>
</div>
<style>
.example {
background-color: #f3cc9b;
}
.before,
.after {
padding: 10px;
background-color: lightgrey;
}
.content {
background-color: #a8c6e9;
height: 50px;
}
.box {
background-color: #c7dfb7;
border: 1rem solid #fceeba;
padding: 2rem;
margin: 3rem;
}
</style>
before block
content
after block
And if you're still stuck
Well, you can just:
<button onclick="body.classList.toggle('debug-mode')"
>Give Everything a Red Border</button
>
<style>
body.debug-mode * {
border: red 1px solid;
}
</style>
References and Further Reading
Anything by Josh W. Comeau pretty much
MDN
CSS Tricks