Table of Contents
Episode One: The Box Model
Episode Links
CSS Tricks Box Model
W3C Box Model Module
Adam's Box Model Codepen
In CSS every element is just a rectangular box. That's easy right, its just boxes we move around the screen. Well, sort of, but its really about the content thats in the box that can affect the rest of the box. Notice above the margin, outline, and box shadow are striked-through to show that they do not affect the size of the box itself. They do however, affect content around the box. The first part to think about when understanding the box model is how the sizing is determined, intrinsic or extrinsic.
Intrinsic vs Extrinsic Sizing
Extrinsic is when the box size is predefined and content is put inside of it. We would explicitly set the height and the width of the box and force what's inside to stay within its given area. Intrinsic is when the size of the box is dynamic to the content put inside of it. In this style we would allow whatever our content is to determine the size of our box.
Boxes Everywhere
Once we figure out whether the content box size is predefined or dynamic, we then have the padding box and then the border box outside of that. These 3 boxes determine the size of the box.So the size of the box is calculated like so:
width = width + padding-left + padding-right + border-left + border-right
height = height + padding-top + padding-bottom + border-top + border-bottom
Outside of the border, we have the margin, outline, and box-shadow boxes. As I said before, these don't affect the inner size of the box. They are painted on after the box size is calculated. You can see this when adding a border to an element versus adding an outline. A border is going to change the size of the box, which the outline will not change the placement of the element. It is important to note that margin is affected by the size of the content and affects the space between elements. It also belongs to the element with which it is added, except in the case of gap where it then belongs to the parent grid (or flex soon) that called it.
User Agent Stylesheet
Occasionally, you may notice elements automatically have padding or margin applied to them. Such as a list item being indented with padding. These styles are provided by the user agent, or browser, that you are using. To avoid running into issues with this, it is common to use a normalize css or reset css file. There are many versions out there or you can tweak them to your liking.
Scrollbars
Scrollbars are interesting in CSS. They live in the same box as the padding box.
Episode Two: Selectors
Episode Links
CSS Tricks Selectors
W3C Selectors
Selec-tors
Selectors are a syntax used to find elements (aka subjects)in the DOM tree. CSS then uses the selector to bind the styles to subjects. A CSS rule consists of the selector and all the style declarations applied to it. They can be combined together into compound selectors to create more specific rules or be defined singularly.
Simple Selectors
Universal Selector - The most general selector will add styles to every element in a document. It is represented by an asterisk
(*)
.Type Selectors - A base element in the DOM is considered a type selector. Eg.
div, p, img
Class Selectors - The most versatile selector because they are well supported, can be added to any element, and can have each element can have multiple classes. Most commonly used with period notation or full stop
(.)
.ID Selector - There should be only one id selector per document and is the strongest, most specific selector. It is represented by the hashtag or pound
(#)
. An element can have stacked or multiple ids on it and the same id can also be repeated on an element for a quirky specificity hack.Attribute Selectors - Have the same specificity value as classes, but add functionality by having the attribute plus a value you can select by. These attributes can be elements, classes, data, languages, or even with regex, plus many more.
Pseudo Selectors - These come in 2 forms pseudo-elements and pseudo-classes. A pseudo-element is a structural selector, targeting things around a DOM element usually with
::before
or::after
. A pseudo-class targets more dynamically or states based on the DOM, but cannot be expressed with simple selectors. Some examples are:nth-child()
,last-child
,:hover
,:active
.Complex Selectors - Look for a relationship between elements. It has a cascade downward, descendant, relationship where the parent cannot be styled, but the children and siblings can. Different types of combinators describe the relationship between the selectors.
Descendent combinator - These can look like
ul li
which would apply the styles only to list items in an unordered list. This also gets applied recursively or on top of one another. So, if an unordered list with an indentation had another unordered list inside of it, then it would be indented twice as much.Child combinator - This type of combinator breaks up the recursive nature of the descendent relationship. It is made with a greater than
(>)
, likeul>li
and this will only target the first unordered list.Sibling combinator - Also known as the next sibling combinator, applies to the next sibling of the first element. It is made with a plus
(+)
, likediv+p
would target a paragraph tag next to a div, not within in. They are adjacent to each other under the same parent. A popular use of this is the lobotomized owl created by Heydon Pickering, and it only selects elements that have a sibling adjacent to them skipping the first of that type.* + * { margin-top: 1.5em; }
Subsequent-sibling combinator - Often used to target the state of a check box. It is made with a tilde
(~)
, likeinput[type=checkbox]:checked ~ div
would target the div adjacent and under the same parent as the check box.
Episode Three: Specificity
Episode Links
Diagram by Estelle Weyl
Specificity Calculator
What happens when a subject is being targeted by multiple rules? The rule with the highest amount of points, or specificity, wins out. Specificity is how the browser decides which styles should be applied to an item. A weight or in this example points are given to each selector based on their ranking of least to most specific. Here's the game, we start at 0 and add up the number of points for each selector. If there is a tie, the last rule in the stylesheet wins. And no cheating by duplicating extra classes to your css 😜!
Points | Selectors |
---|---|
0 | Universal/Not * /:not |
1 | Element/Pseudo-element h1 /::before |
10 | Class/Pseudo-class ``./:focus |
100 | ID # |
1000 | Inline style |
Game Time
- 1. *
- 2. p
- 3. main .header
- 4. #nav ul li
- 5. a:active
- 6. a:not(:active)
- 7. article a.outbound:not(:visited)
- 8. a.lol.lol.lol.lol
Check your scores in the specificity calculator. How did you do? Hopefully, this article helped you learn a little more about how to calculate specificity and apply it in your CSS!
Episode Four: The Cascade
MDN on Cascade and Inheritance
CSS Cascade Interactive Article
The "C" in CSS stands for cascade. Basically, this means that location and order matter when you are writing CSS rules. If rules have the same specificity, the one that is used last in the stylesheet will be used. The cascade is made up of 4 phases:
- 1. Position - The position of a rule with the same specificity in a stylesheet or where it is linked in the html matters. The one that appears last with the most specificity wins. An embedded style tag in the html and inline style are more specific than the stylesheets. You can think about their proximity to the code they are affecting; inline is the closest, then style tag, then linked styles, then browser.
- 2. Origin - Where the rules are coming from, 1st link tags, 3rd party link tags, embedded styles, inline-styles, browser (user-agent styles), client set styles
- 3. Specificity - user agent, client styles, your styles, your !important, client !important, user-agent !important
- 4. Importance - Depends on the type of rule and is in order from least to most specific; normal, animation, !important, transitions.