CSS 101 - The Box Model
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:
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
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
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.
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.
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."
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
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
examplesSize can be declared as a single value:
#element border: 3px solid #ff5230
#element border: solid #ff5230 border-width: 8px
#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.
Margin is the personal space of the elements. It details how close another element can get to it.
#element margin: 12px
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
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:
- Fill as much horizontal space as possible
- If the opposite side also has a margin set to auto, match the size of it
What do you think vertical margins set to auto do?
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.
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
link(href='style.styl' rel='stylesheet') .box .box .box .box
.box width: 40px height: 40px border: 3px dashed #f00
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
$width = 160px .box width: $width height: ($width / 2) border: 3px dashed #f00
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:
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