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

css-basic-layouts/Syntax.astro
<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:

  1. Declarations
  2. Rules
  3. Resets/Normalizations
  4. Class selectors
  5. Psuedo-class selectors
Then - like just draw the rest of the owl

Now let's style it

css-basic-layouts/Syntax.astro
<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>
css-basic-layouts/syntax.css
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:

  1. Declarations
  2. Rules
  3. Resets/Normalizations
  4. Class selectors
  5. Psuedo-class selectors
Then - like just draw the rest of the owl

Selectors

css-basic-layouts/selectors.css
/* Element */
h1 {}

/* ID */
#thing-id {}

/* Class */
.some-class {}

/* Attribute */
some-selector[myattr="value"] {}

/* Psuedo-class */
some-selector:psuedoclass {}

Combining Selectors (Combinators)

css-basic-layouts/Combinators.astro
<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

css-basic-layouts/Combinators.astro
<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>
css-basic-layouts/combinators.css
/* 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

css-basic-layouts/Specificity.astro
<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>
css-basic-layouts/specificity.css
/*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

css-basic-layouts/Psuedo.astro
<label>
  An Email Input
  <input type="email" id="email" pattern=".+@.+\..+" size="30" required />
</label>
css-basic-layouts/psuedo.css
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

css-basic-layouts/BoxModel.astro
<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>
css-basic-layouts/box-model.css
.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
css-basic-layouts/InlineVBlock.astro
<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
css-basic-layouts/BoxModelStandalone.astro
<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:

css-basic-layouts/DebugCSSButton.astro
<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