# Session 04 - CSS, Part 2 - including Flexbox

Harvard Extension School
Fall 2023

Course Web Site: https://cscie12.dce.harvard.edu/

### Topics

1. CSS Review
2. CSS Specificity
3. Box Model
4. CSS Flexbox
5. CSS Flexbox and Grid
6. CSS Flexbox
7. Lists as Navigation
8. Two approaches - border or content?
9. Working an Example
10. Flex and Simple Layouts
11. CSS calc()
12. CSS Remedy, Normalize, and Reset

Session 04 - CSS, Part 2 - including Flexbox, slide1
CSS Review, slide2
CSS Guides and Reference and Tools, slide3
Anatomy of a CSS Rule, slide4
CSS selectors - elements, class, id, and contextual, slide5
class selectors, slide6
Contextual Selectors, slide7
CSS Specificity, slide8
CSS Selector Specificity, slide9
Specificity, slide10
Box Model, slide11
Box Sizing - How do you measure width?, slide12
When 25% is not 1/4 of the screen, slide13
* { box-sizing: border-box; }, slide14
CSS Flexbox, slide15
CSS Flexbox and Grid, slide16
CSS Flexbox, slide17
flex-basis, slide18
flex-grow and flex-shrink, slide19
Flex and Wrap, slide20
Lists as Navigation, slide21
Two approaches - border or content?, slide22
Working an Example, slide23
Some Notes about the Example, slide24
Flex and Simple Layouts, slide25
CSS calc(), slide26
CSS Remedy, Normalize, and Reset, slide27

Presentation contains 27 slides

- img
- img
- img
- img
- img

## CSS Review

- Structure / Markup (HTML)
  - Structure
  - Content
- Style / Presentation (CSS)
  - Style
  - Presentation
  - Appearance
- Function (JavaScript)
  - Actions
  - Manipulations

## CSS Guides and Reference and Tools

- CSS: Cascading Style Sheets | MDN
- CSS reference | MDN
- Learning Web Design, Part III, CSS For Presentation
  Chapters 11, 12, 13, 14, 16

### Your Browser's "Inspect" function!

### CSS Validator

- W3C CSS Validation Service
  `http://jigsaw.w3.org/css-validator/`

## Anatomy of a CSS Rule

### CSS Rule

### Selector and Declarations

### Properties and Values

## CSS selectors - elements, class, id, and contextual

- elements
- class / id

### element selectors

    p {
    background-color: white;
    color: maroon;
    }

    ul {
    border: medium solid green;
    }

    li {
    background-color: lightsalmon;
    }

    h1,
    h2,
    h3 {
    background-color: black;
    color: white;
    }

CSS element selector example

## class selectors

When to use classes?

- Within a page, there are elements that are the "same" from a markup perspective, but need to be styled differently.
- Within a site, there is content that has the "same" markup, but needs to be styled differently.

    section  {
        background-repeat: no-repeat;
        background-size: 80px;
        padding-left: 100px;
        padding-bottom: 1.5rem;
    }
    section h2 {
       color: rgb(163,28,48);

    }
    section.html {
        background-image: url(../images/logo-html5.png);
    }
    section.css {
        background-image: url(../images/logo-css3.png);
    }
    section.javascript {
        background-image: url(../images/logo-js.png);
    }

## Contextual Selectors

Tip: Often I see classes being used when a contextual selector would do!

`selector1 selector2 { ...rules... }`

Often you'll see this as ways to apply different rules in `header`, `main`, and `footer`

    main p {
    /* rules for p inside of main */
    }
    footer p {
    /* rules for p inside of main */
    }
    h2 {
    /* rules for h2 everywhere*/
    }
    section h2 {
    /* rules for h2 inside of section */
    }
    nav a:link,
    nav a:visited,
    nav a:hover,
    nav a:active {
      /* rules for nav links */
    }
    footer a:link,
    footer a:visited,
    footer a:hover,
    footer a:active {
      /* rules for nav links */
    }

### Example of "li em" selector

Example 4.1 - contextual selectors - Example 4.1
<div><em>Emphasized text</em> outside of <strong>li</strong> appear "normal". <ul><li><em>Emphasized text</em> within <strong>li</strong> have a different style. </li></ul></div> li em { color: red; background-color: navy;}

- Markup
- Style
- Display
- Screenshot

     <div>
       <em>Emphasized text   </em>outside of
       <strong>li   </strong>appear "normal".
       <ul>
         <li>
           <em>Emphasized text       </em>within
           <strong>li       </strong>have a different style.
         </li>   </ul>
     </div>

In `style` element (`<style>`) within `head` element:

    li em { color: red; background-color: navy;}

## CSS Specificity

See: Calculating a selector's specificity.

### Stylesheet Origin

- author stylesheet
- reader (user) stylesheet
- browser (user agent) stylesheet

### Specificity of Selector

- style attribute
- count "id" attributes
- count number of other attributes ("class")
- count element names

### Order

- last occurence has higher specificity

  `@import`-ed stylesheets come before rules in the importing sheet.

## CSS Selector Specificity

Specificity is expressed in a form of a list of four numbers: `(a,b,c,d)`

1. inline style
2. id
3. class, pseudo-class and attributes
4. element and pseudo-elements

Start comparing at "a", if equal go to "b", etc.

    nav li {...}                     /* (0,0,0,2) */
    nav.primary {...}                /* (0,0,1,1) */
    nav.primary li {...}             /* (0,0,1,2) */
    nav.primary li:first-child {...} /* (0,0,2,2) */
    nav.primary li.getinfo {...}     /* (0,0,2,2) */
    #globalnav {...}                 /* (0,1,0,0) */

`#globalnav` >
`nav.primary li.getinfo` >
`nav.primary li:first-child` >
`nav.primary li` >
`nav.primary` >
`nav li`

## Specificity

And for a fun take on CSS Specificity, take a look at CSS SpeciFISHity

## Box Model

- margin
- border
- padding
- content

### A more detailed look:

Image from Cascading Style Sheets: The Definitive Guide, 3rd ed by Eric Meyer, published by O'Reilly

### In your browser

## Box Sizing - How do you measure width?

By default, box sizing (width or height) is measured in terms of the "content-box". So any padding or border is "in addition to" the width set in CSS.

Use `box-sizing` property to make box widths behave more like what you expect.

Example 4.2 - box sizing - Example 4.2
<img src="https://via.placeholder.com/400x50/000000/ffffff.png?text=400px+wide+image"/><div class="dog sizing"> Dog <pre>width: 400px; box-sizing: border-box;</pre></div><div class="cat"> Cat <pre>width: 400px; box-sizing: content-box;</pre></div><img src="https://via.placeholder.com/520x50/000000/ffffff.png?text=520px+wide+image"/><div class="goat"> Goat <pre>width: 400px; /* default box-sizing, which is content-box */</pre></div> .dog { box-sizing: border-box; } .cat { box-sizing: content-box; } .goat { box-sizing: unset; } div { margin: 20px; font-size: xx-large; background-color: rgb(230,230,230); padding: 20px 40px; text-align: left; width: 400px; border: 20px outset rgb(220,220,255); } div pre { font-size: x-large;} img { margin-left: 20px;}

- Markup
- Style
- Display
- Screenshot

     <img src="https://via.placeholder.com/400x50/000000/ffffff.png?text=400px+wide+image"/>

     <div class="dog sizing">Dog
       <pre>width: 400px; box-sizing: border-box;   </pre>
     </div>
     <div class="cat">Cat
       <pre>width: 400px; box-sizing: content-box;   </pre>
     </div>
     <img src="https://via.placeholder.com/520x50/000000/ffffff.png?text=520px+wide+image"/>

     <div class="goat">Goat
       <pre>width: 400px; /* default box-sizing, which is content-box */   </pre>
     </div>

In `style` element (`<style>`) within `head` element:

      .dog {
        box-sizing: border-box;
      }
      .cat {
        box-sizing: content-box;
      }
      .goat {
        box-sizing: unset;
      }
      div {
        margin: 20px;
        font-size: xx-large;
        background-color: rgb(230,230,230);
        padding: 20px 40px;
        text-align: left;
        width: 400px;
        border: 20px outset rgb(220,220,255);
      }
      div pre { font-size: x-large;}

      img { margin-left: 20px;}

## When 25% is not 1/4 of the screen

Example 4.3 - Box Sizing - 25% is not 1/4 - Example 4.3
<div class="full"><p>Container - 100%</p><div class="quarter">One (25%)</div><div class="quarter">Two (25%)</div><div class="quarter">Three (25%)</div><div class="quarter">Four (25%)</div></div> div.quarter { width: 25%; border: 2px dashed purple; background-color: rgb(240, 200, 240); float: left; overflow: auto; text-align: center; padding-top: 1rem; padding-bottom: 1rem; } div.full { width: 100%; border: 2px solid black; overflow: auto; }

- Markup
- Style
- Display

     <div class="full">
       <p>Container - 100%
       </p>
       <div class="quarter">One (25%)
       </div>
       <div class="quarter">Two (25%)
       </div>
       <div class="quarter">Three (25%)
       </div>
       <div class="quarter">Four (25%)
       </div>
     </div>

In `style` element (`<style>`) within `head` element:

      div.quarter {
        width: 25%;
        border: 2px dashed purple;
        background-color: rgb(240, 200, 240);
        float: left;
        overflow: auto;
        text-align: center;
        padding-top: 1rem;
        padding-bottom: 1rem;
      }
      div.full {
        width: 100%;
        border: 2px solid black;
        overflow: auto;
      }

Example 4.4 - Box Sizing - 25% is 1/4 - Example 4.4
<div class="full"><p>Container - 100%</p><div class="quarter">One (25%)</div><div class="quarter">Two (25%)</div><div class="quarter">Three (25%)</div><div class="quarter">Four (25%)</div></div> div.quarter { width: 25%; box-sizing: border-box; border: 2px dashed purple; background-color: rgb(240, 200, 240); float: left; overflow: auto; text-align: center; padding-top: 1rem; padding-bottom: 1rem; } div.full { width: 100%; border: 2px solid black; overflow: auto; }

- Markup
- Style
- Display

     <div class="full">
       <p>Container - 100%
       </p>
       <div class="quarter">One (25%)
       </div>
       <div class="quarter">Two (25%)
       </div>
       <div class="quarter">Three (25%)
       </div>
       <div class="quarter">Four (25%)
       </div>
     </div>

In `style` element (`<style>`) within `head` element:

      div.quarter {
        width: 25%;
        box-sizing: border-box;
        border: 2px dashed purple;
        background-color: rgb(240, 200, 240);
        float: left;
        overflow: auto;
        text-align: center;
        padding-top: 1rem;
        padding-bottom: 1rem;
      }
      div.full {
        width: 100%;
        border: 2px solid black;
        overflow: auto;
      }

## * { box-sizing: border-box; }

It is a common practice to set box-sizing property to "border-box" for all elements

      * { box-sizing: border-box; }

## CSS Flexbox

Flexbox is a one-dimensional layout method for arranging items in rows or columns. Items flex (expand) to fill additional space or shrink to fit into smaller spaces.

When to use it: Building simple page or content layouts without having use `float` or `position`ing.

## CSS Flexbox and Grid

### Flexbox

- One primary axis
- Basic layouts for pages and content
- Easier then "grid" (?)

### Grid

- Two axes
- More complex layouts
- Overlapping items

## CSS Flexbox

- MDN: Basic Concepts of Flexbox
- CSS Tricks: A complete Guide to Flexbox and a fantastic poster!

### Container and Items

1. Set up your flex container and properties of the container.
2. Set the "flex" properties on the items within your container.

Example 4.5 - Flex - Example 4.5
<div id="f3container"><div class="box box1">1</div><div class="box box2">2</div><div class="box box3">3</div><div class="box box4">4</div><div class="box box5">5</div></div>#f3container { display: flex; } .box1, .box2, .box3, .box4, .box5 { flex-grow: 0; flex-shrink: 0; flex-basis: 5em; } .box1 { background-color: lightpink;} .box2 { background-color: lightsteelblue;} .box3 { background-color: wheat;} .box4 { background-color: plum;} .box5 { background-color: palegreen;} .box { padding: 2em; border: medium solid black; width: 3em; }

- Markup
- Style
- Display

     <div id="f3container">
       <div class="box box1">1
       </div>
       <div class="box box2">2
       </div>
       <div class="box box3">3
       </div>
       <div class="box box4">4
       </div>
       <div class="box box5">5
       </div>
     </div>

In `style` element (`<style>`) within `head` element:

    #f3container {
      display: flex;
    }
    .box1, .box2, .box3, .box4, .box5 {
      flex-grow: 0;
      flex-shrink: 0;
      flex-basis: 5em;
    }
    .box1 { background-color: lightpink;}
    .box2 { background-color: lightsteelblue;}
    .box3 { background-color: wheat;}
    .box4 { background-color: plum;}
    .box5 { background-color: palegreen;}
    .box {
      padding: 2em;
      border: medium solid black;
      width: 3em;
    }

## flex-basis

Controls the initial size of the flex item

Example 4.6 - Flex - Example 4.6
<div id="f4container"><div class="box box1">1</div><div class="box box2">2</div><div class="box box3">3</div></div>#f4container { display: flex; } .box1 { flex-basis: 15%; background-color: lightpink; } .box2 { flex-basis: 25%; background-color: lightsteelblue; } .box3 { flex-basis: 50%; background-color: wheat; } .box { padding: 2em; border: medium solid black; width: 3em; }

- Markup
- Style
- Display

     <div id="f4container">
       <div class="box box1">1
       </div>
       <div class="box box2">2
       </div>
       <div class="box box3">3
       </div>
     </div>

In `style` element (`<style>`) within `head` element:

    #f4container {
      display: flex;
    }
    .box1 {
      flex-basis: 15%;
      background-color: lightpink;
    }
    .box2 {
      flex-basis: 25%;
      background-color: lightsteelblue;
    }
    .box3 {
      flex-basis: 50%;
      background-color: wheat;
    }
    .box {
      padding: 2em;
      border: medium solid black;
      width: 3em;
    }

## flex-grow and flex-shrink

Controls if and how the flex item will grow or shrink from its original flex-basis size.

Example 4.7 - Flex - Example 4.7
<div id="f5container"><div class="box box1">1</div><div class="box box2">2</div><div class="box box3">3</div></div> #f5container { display: flex; } .box1 { flex-grow: 1; flex-shrink: 1; flex-basis: 200px; background-color: lightpink; } .box2 { flex-grow: 1; flex-shrink: 1; flex-basis: 100px; background-color: lightsteelblue; } .box3 { flex-grow: 1; flex-shrink: 1; flex-basis: 500px; background-color: wheat; } .box { padding: 2em; border: medium solid black; width: 3em; }

- Markup
- Style
- Display

     <div id="f5container">
       <div class="box box1">1
       </div>
       <div class="box box2">2
       </div>
       <div class="box box3">3
       </div>
     </div>

In `style` element (`<style>`) within `head` element:

    #f5container {
      display: flex;
    }
    .box1 {
      flex-grow: 1;
      flex-shrink: 1;
      flex-basis: 200px;
      background-color: lightpink;
    }
    .box2 {
      flex-grow: 1;
      flex-shrink: 1;
      flex-basis: 100px;
      background-color: lightsteelblue;
    }
    .box3 {
      flex-grow: 1;
      flex-shrink: 1;
      flex-basis: 500px;
      background-color: wheat;
    }
    .box {
      padding: 2em;
      border: medium solid black;
      width: 3em;
    }

## Flex and Wrap

Controls whether flex items will "line wrap" — by default flex items do not wrap!

Example 4.8 - Flex Wrap - Example 4.8
<div id="f6container"><div class="box box1">1</div><div class="box box2">2</div><div class="box box3">3</div><div class="box box4">4</div><div class="box box5">5</div><div class="box box6">6</div></div>#f6container { display: flex; flex-wrap: wrap; justify-content: space-evenly; background-color: linen; border: thin solid black; } .box1, .box2, .box3, .box4, .box5, .box6 { flex-grow: 0; flex-shrink: 0; flex-basis: 28%; box-sizing: border-box; margin: 1rem 0; } .box1 { background-color: lightpink;} .box2 { background-color: lightsteelblue;} .box3 { background-color: wheat;} .box4 { background-color: plum;} .box5 { background-color: palegreen;} .box6 { background-color: turquoise;} .box { padding: 2em; border: medium solid black; }

- Markup
- Style
- Display

     <div id="f6container">
       <div class="box box1">1
       </div>
       <div class="box box2">2
       </div>
       <div class="box box3">3
       </div>
       <div class="box box4">4
       </div>
       <div class="box box5">5
       </div>
       <div class="box box6">6
       </div>
     </div>

In `style` element (`<style>`) within `head` element:

    #f6container {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-evenly;
      background-color: linen;
      border: thin solid black;
    }
    .box1, .box2, .box3, .box4, .box5, .box6 {
      flex-grow: 0;
      flex-shrink: 0;
      flex-basis: 28%;
      box-sizing: border-box;
      margin: 1rem 0;
    }
    .box1 { background-color: lightpink;}
    .box2 { background-color: lightsteelblue;}
    .box3 { background-color: wheat;}
    .box4 { background-color: plum;}
    .box5 { background-color: palegreen;}
    .box6 { background-color: turquoise;}
    .box {
      padding: 2em;
      border: medium solid black;
    }

## Lists as Navigation

Commonly use `nav` and `ul`, with `ul` being the flex container.

Example 4.9 - Example 4.9
<nav><ul><li><a href="#">Planet</a></li><li><a href="#">Solar System</a></li><li><a href="#">Galaxy</a></li><li><a href="#">Universe</a></li></ul></nav>nav ul { display: flex; } nav ul { list-style: none; } nav ul li { margin-left: 1em; }

- Markup
- Style
- Display

     <nav>
       <ul>
         <li>
           <a href="#">Planet       </a>
         </li>
         <li>
           <a href="#">Solar System       </a>
         </li>
         <li>
           <a href="#">Galaxy       </a>
         </li>
         <li>
           <a href="#">Universe       </a>
         </li>   </ul> </nav>

In `head` element:

    <link rel="stylesheet" href="example9.css"/>

In example9.css

    nav ul { display: flex; }
    nav ul { list-style: none;
    }
    nav ul li { margin-left: 1em; }

## Two approaches - border or content?

When doing navigation, how about a "border" or "content" property?

Border

See the Pen Navigation - horizontal with border by David Heitmeyer (@dpheitmeyer) on CodePen.

Content

See the Pen Navigation - horizontal with border by David Heitmeyer (@dpheitmeyer) on CodePen.

## Working an Example

## Some Notes about the Example

- Adding class attributes may be helpful
- anchor (a elements) with display of block for navigation
- :first-child and :last-child pseudo-class
- sometimes flex parent containers will be there, sometimes you have to add them

## Flex and Simple Layouts

- Layout with Flex - 1
- Layout with Flex - 2

## CSS calc()

CSS `calc()` function give a way to calculate values. See: calc() function on MDN

`width: calc(33.33% - 2rem);`

Example 4.10 - box sizing - Example 4.10
<ul><li>Item One</li><li>Item Two</li><li>Item Three</li></ul> ul, li { margin-left: 0; padding-left: 0;} ul { list-style: none; overflow: auto; background-color: #ffffdd; border: thin solid black;} li { box-sizing: border-box; padding: 1rem; margin: 1rem; float: left; width: calc(33.33% - 2rem); font-weight: bold; text-align: center; border: 5px dotted green; }

- Markup
- Style
- Display

     <ul>
       <li>Item One
       </li>
       <li>Item Two
       </li>
       <li>Item Three
       </li> </ul>

In `style` element (`<style>`) within `head` element:

      ul, li { margin-left: 0; padding-left: 0;}
      ul { list-style: none; overflow: auto; background-color: #ffffdd; border: thin solid black;}
      li { box-sizing: border-box;
        padding: 1rem; margin: 1rem; float: left;
        width: calc(33.33% - 2rem);
        font-weight: bold; text-align: center; border: 5px dotted green; }

## CSS Remedy, Normalize, and Reset

Sometimes default browser behavior helps, sometimes it gets in the way. Three approaches are:

- CSS Remedy
- CSS Normalize
- CSS Reset

Three approaches:

- CSS Remedy / Sensible Defaults: free yourself from history and provide a remedy for CSS legacy 'mistakes'; provide yourself with sensible starting point and defaults.
- CSS Normalize: give yourself consistency across browsers.
- CSS Reset: give yourself a "blank slate" to build upon; that is, effectively remove all browser default styles.

### Examples

- Basic Markup
- Jen Simmons's "CSS Remedy" — Basic Markup with Jen Simmons's CSS Remedy
- Eric Meyer's Reset CSS — Basic Markup with Eric Meyer CSS Reset
- normalize.css project — Basic Markup with CSS Normalize
- Andy Bell's "A Modern CSS Reset" — Basic Markup with Andy Bell's Modern CSS Reset