CSS 101 - The Box Model

"#yourMother { width: 99999999px; }"
It's just a fact m8
  1. The Box Model

    CSS uses what's called a "box model" to deal with sizing of elements. The box model defines how height, width, padding, margin, borders, and outlines are related to each other:

  2. Size

    The innermost circle is size, or width and height. We can change the values with... get this.. "width" and "height" css attributes!

    #element
      width: 88px
      height: 44px

    Example

    I know this is super complex, next level, cutting edge stuff, so here are some examples:

    #element
      width: 100px
      height: 50px
    #element
      width: 10px
      height: 80px
    #element
      width: 50%
      height: 50px
  3. Note the 'width 50%' in the last example. If you resize your browser window you'll see the width of the element actually changes in order to take up 50% of the space of it's container. This brings us to our next section.

  4. Units

    There are fifteen different units recognized by css. Of these, we'll use pixels and percentages 99% of the time. Do not use the ones in red.

    Unit Description
    px Pixels. Note that the "pixel" will be relative to the screen density. On a "retina" display, 1px will take up two physical pixels.
    % Percentage. Takes up a percent of the encapsulating container
    vh/vw/vmin Viewport Height, Viewport Width, and Viewport Min (1vw or 1vh, whichever is smaller). A newer addition to the CSS spec, so rarely used only because not many people are familiar with it yet. Note that the unit is a percentage, so 100vw will be 100% of the viewport width.
    em / rem Relative to the font size of the element (2em means 2 times the size of the current font). Rem is relative to the font-size of the root element.
    pt / pc Points and picas. 1pt = 1/72 of an inch. 1pc = 12pt = 1/6 of an inch. Takes into account screen density, sometimes. Used mostly by people who are bad at writing css. They're the Comic Sans and Papyrus of css units.
    in/cm/mm Inch, centimeter, millimeter. Takes into account screen density, sometimes. Otherwise defaults to 1in = 96px, from which cm and mm are derrived. Worth noting that I have never once seen these units, nor any ones listed below, ever used in production.
    ex Relative to the x-height of the current font. Rarely used, but actually valuable if you're doing very typography specific things.
    ch The width of a single '0' character. Relative to the font being used.
  5. Padding

    Padding makes the size bigger. When we talk about the size of an element, by default we add in the padding. So an element with

    #element
      width: 88px
      height: 44px
      padding: 6px

    would be considered to be 100 pixels wide (88 + 6 + 6) not 88 pixels.

    example

    Padding is the distance between the edge of the element and the content within it. For example, take the red square to the right. It has a quote from Shakesphere in it.

    Drag the slider below to change the padding.

    Current padding: 0px

    Current size (width): 300px

    "They don't think it be like it is, but it do."
  6. The TRBL with tribbles

    CSS allows us to write many things in short hand. If we wanted different padding for each side of an element, we could write it this way:

    #element
      padding-top: 10px
      padding-right: 5px
      padding-bottom: 2px
      padding-left: 1px
    

    We can also condense all of them in a short hand format where we declare each value in sequence on a single line.

    The order is Top -> Right -> Bottom -> Left, or TRBL (pronounced trouble).

    #element 
      padding: 10px 5px 2px 1px
    
  7. Border

    Border is straight forward. It's just like the border in sketch or the stroke in photoshop, with the caveat that its position is always set to 'outside'. The syntax for a border declaration is broken up into three parts:

    #element
      border: SIZE STYLE COLOR

    examples

    Size can be declared as a single value:
    #element
      border: 3px solid #ff5230
    Or separated out with the border-width property:
    #element
      border: solid #ff5230
      border-width: 8px
    You can also use TRBL declarations on border-width:
    #element
      border: solid #ff5230
      border-width: 2px 4px 8px 16px
    

    You can also target a side directly.

    #element
      border: 8px solid #ff5230
      border-left: 16px solid #4C9AFF

    Borders can have many different styles (solid, dashed, dotted, double, groove, ridge, inset, and outset), but in general we almost always only use solid.

    solid
    dashed
    dotted
    double
    groove
    ridge
    inset
    outset
  8. Margin

    Margin is the personal space of the elements. It details how close another element can get to it.

    #element
      margin: 12px
    

    examples

    Use the slider below to change the margin of the elements to the right. Note that the left-most element has its right margin hard-set to 20px.

    Current margin: 0px

    Use the slider below to change the margin of the elements to the right. Note that the top-most element has its bottom margin hard-set to 20px.

    Current margin: 0px

    If two elements have vertical margins that are touching, the largest margin wins. Or in other words, if one element has a margin of 10px, and another element has a margin of 20px, the distance between the two elements will be 20px. Vertical margins do not stack with other margins*.

    *Unless the elements have a float applied to them

    Auto margins

    Another example where vertical margins work differently than horizontal margins is with the 'auto' value.

    #element
      margin: 0 auto

    Inspect the #marginAutoExample element below (the magenta box). Try changing the margin-left and margin-right values to auto and other values.

     

    Horizontal margins with an 'auto' value will attempt to do two things:

    1. Fill as much horizontal space as possible
    2. If the opposite side also has a margin set to auto, match the size of it

    Pop Quiz

    What do you think vertical margins set to auto do?

Exercises

  1. Make some boxes

    • Create a new folder in your prototypes/ directory
    • Create an index.pug and a style.styl
    • Import the style.styl into the index.pug
    • Create four boxes with the same class
    • Give that class name a width and a height in your style.styl
    • Give that class name a border of your choice
    • Answers:

      link(href='style.styl' rel='stylesheet')
      .box
      .box
      .box
      .box
      .box
        width: 40px
        height: 40px
        border: 3px dashed #f00
      
  2. Link the boxes' width and height

    • Stylus variable documentation
    • Create a stylus variable and set it to a value somewhere between 100px - 400px
    • Set the width of the boxes to your variable
    • Set the height of the boxes equal to half the width. Be sure to use the variable you declared earlier
    • Answers:

      $width = 160px
      .box
        width: $width
        height: ($width / 2)
        border: 3px dashed #f00
      
  3. Create a blog layout

    • Create a new index.pug and a new style.styl in a new folder. Link them.
    • In your index.pug create a #content element
    • Give your #content a 800px width and center it
    • add some .memoir child elements to #content
    • Write these css rules for .memoir
      background-color: #392d40
      color: #fff
    • Give .memoir 20px horizontal padding and 10px vertical padding
    • Make 10px of vertical margin between each .memoir
    • Example final result:

      Answers:

      link(href='style.styl' rel='stylesheet')
      #content
        .memoir.
          Today I ate a carrot
        .memoir.
          Today I pooped a carrot
      
      #content
        width: 800px
        margin: 0 auto
      .memoir
        padding: 10px 20px
        margin: 10px 0
        background-color: #392d40
        color: #fff