Lecture 8 More Foundational Concepts of CSS

Topics for today

Inheritance

Notes
  • Notice how the p, em, mark elements have the same font family, font size, and color that we set on their ancestor, body
  • What happens if we add a border to the body? Does it get inherited too?

Takeaway Some properties are inherited, and some aren’t. Why? It's a heuristic.

What kinds of properties inherit?

background font border text-decoration display color padding white-space margin text-shadow box-shadow box-sizing outline --*

Inherited Not inherited

Components of the Cascade

Where does inheritance fit in?

Notes

Inherited properties have lower precedence than any values directly applying to the element, regardless of origin, specificity, or order.

Takeaway Q: Where does inheritance sit in the cascade?
A: The very bottom

Takeaway inherit is an explicit value that makes any property inherit

Values & Units

width: 400px;

width: 50%;

width: 400px;

width: 400px;

<length>

Notes
Read more about lengths

<length> units

Absolute

Same measurement everywhere

Examples: px, cm, mm, in, pt

Relative

Dependent on another factor

  • Font-relative units scale with the text size
    Examples: em, ch, rem, ex
  • Viewport-relative units scale with the viewport
    Examples: vh, vw, vmin, vmax
Notes
  • Some useful units are:
    • em is relative the current font size
    • rem is relative to the current font size of the html element
    • ch represents the width of the "0" glyph in the current font. This is useful in monospaced fonts where every character has the same width.
    • vw is a percentage of the viewport width (100vw = viewport width)
    • vh is a percentage of the viewport height (100vh = viewport height)
  • Font-relative units are useful in making components that scale by changing one property (the font-size).
  • Viewport-relative units are useful in making layouts that scale nicely with the viewport size.

Font relative units

button {
	background: yellowgreen;
	border: 1px solid olivedrab;
	padding: 15px;
	border-radius: 6px;
	font-size: 32px;
	line-height: 32px;
}
button {
	background: yellowgreen;
	border: 1px solid olivedrab;
	padding: .5em;
	border-radius: .2em;
	font-size: 32px;
	line-height: 1em;
}
Notes

Why are font-relative units useful? Let’s look at an example. Put your caret on the font-size and press

Shift +

to increase the font size fast. Note that the rest of the styling (padding, line-height, border-radius etc) becomes disproportionately small. If we use font-relative units, we can make everything adapt!

Our button is now nicely scalable by changing only one parameter. We can even set font-size itself to font-relative units, if we want it to adapt to the surrounding font size!

Viewport relative units

h1 {
	font-weight: 300;
	font-size: 4em;
}
h1 {
	font-weight: 300;
	font-size: 12vw;
}
Notes
  • Viewport scalable units allow us to scale text to the viewport size.
  • calc allows us to perform calculations with different units. The type returned depends on the units that participate in the calculation.
  • min, clamp and max allow us to create upper and lower bounds for our values, and can participate in calc() expressions too.
  • All these functions can of course be combined, e.g. min can be used inside calc and vice versa.
  • Note that unlike Python or most other programming languages, these calculations are re-evaluated every time anything changes (e.g. the viewport or font size)

width: 50%;

Percentages

Each property defines whether percentages are allowed and what they represent

margin-left: 10%;

margin-top: 10%;

border: .3em steelblue;

outline: auto;

margin: auto;

overflow: auto;

Lorem Ipsum dolor sit amet

CSS-wide keywords

Other datatypes

opacity: 0.5;

transform: rotate(10deg);

background-color: hsl(10, 100%, 40%);

background: url(img/chocolate-mousse.png) center / cover, linear-gradient(teal 60%, gold);

background: conic-gradient(teal 50%, gold);

Notes
Percentages do not always resolve to lengths. E.g. in conic gradients, they resolve to angles, since color stops are placed along a gradient circle.

Shorthands & Longhands

Shorthands & Longhands

Notes
A shorthand is a CSS property that represents multiple other properties, its longhands, or constituent properties. Setting a shorthand is equvalent to setting all of its longhands.

border: .3em dotted steelblue;

Disambiguation
Shorthands often accept their arguments in either order, but only iff disambiguation is possible.

border: dotted .3em steelblue;

border: steelblue .3em dotted;

Longhands can be shorthands too

Different shorthands can resolve to the same longhands

Notes
What happens if we set both the shorthand and some of its longhands?
Notes
What happens if we set the same properties in a different order? Do you understand why we got the result we did?

Often they evolve over time

CSS 1 CSS 2.1 CSS Backgrounds & Borders Level 3 CSS Backgrounds & Borders Level 4

Naming is not always consistent

Notes

What happens if we swap the order of these two declarations? Why??

⚠️

A shorthand always sets all of its longhands, whether values have been provided for them or not

Notes
Any value not explicitly provided is set to initial.

padding: .2em .5em .1em .5em;

Top
Right
Bottom
Left
🕐

background: url(foo.png) 50% 50% / 100% auto no-repeat gold;

Notes

Some shorthands have a mixed syntax: their longhands can be mostly specified in any order, but some values need to come after other values, for disambiguation. In this case, background-size can only follow background-position (separated from it with a slash)

background: gold no-repeat 50% 50% / 100% auto url(foo.png);

font: 120%/1.5 Helvetica Neue, sans-serif;

Notes
Some shorthands require at least some values to be specified to be valid. Here, [`font`](https://developer.mozilla.org/en-US/docs/Web/CSS/font) requires at least a value for `font-size` and `font-family`.

Shorthand usability

background: url(cat.jpg)
            0 10% / 100% 100%
            no-repeat
            content-box border-box
            fixed;
background-image: url(cat.jpg);
background-position: 0 10%;
background-size: 100% 100%;
background-repeat: no-repeat;
background-origin: content-box;
background-clip: border-box;
background-attachment: fixed;
Notes
Computer languages are also interfaces, they are just text-based interfaces. The same usability dimensions apply. When it comes to CSS shorthands and longhands, which of these is more learnable? Which of these is more efficient?

Don’t
Repeat
Yourself

DRY Principle

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system

The Pragmatic Programmer, Andy Hunt and Dave Thomas

A big part of writing good code is avoidingcodeknowledgeduplication

def right_triangle_perimeter(a, b, c):
	return a + b + c

# ... later on
p = right_triangle_perimeter(3, 4, 5)
Notes
  • Here, you can see a contrived example of WET Python code. c is dependent on a and b, so providing it is superfluous.
  • Not only is this an example of poor efficiency (both to write and to read), but also poor safety, since we may inadvertently provide arguments that are inconsistent.
from math import sqrt

def right_triangle_perimeter(a, b):
	return a + b + sqrt(a**2 + b**2)

# ... later on
p = right_triangle_perimeter(3, 4)
Notes

Keeping CSS DRY

Avoid presentational class names

Presentational class

<button class="red-button">
	Continue
</button>
.red-button {
	background: hsl(0, 80%, 90%);
}

Semantic class

<button class="primary-button">
	Continue
</button>
.primary-button {
	background: hsl(0, 80%, 90%);
}

Keeping CSS DRY

Use font-relative units

button {
	border-radius: 5px;
	padding: 5px 12px 6px;
	font-size: 24px;
	line-height: 24px;
}
button.large { font-size: 46px; }
button {
	border-radius: .2em;
	padding: .2em .5em .25em;
	font-size: 100%;
	line-height: 1;
}
button.large { font-size: 200%; }

Keeping CSS DRY

Use shorthands wisely

Hardcover
Paperback
Audiobook
.tab {
	border-radius: .3em .3em 0 0;
	padding: .1em .5em .1em .5em;
	margin: 0 .1em 0 .1em;
}
Hardcover
Paperback
Audiobook
.tab {
	border-radius: .3em;
	border-bottom-left-radius: 0;
	border-bottom-right-radius: 0;
	padding: .1em .5em;
	margin: 0 .1em;
}
Notes
Note that the DRY version has more code. Short code is not the goal, maintainability is.

Overgeneralization

Rule of three Three strikes and you refactor

Duplication is far cheaper than the wrong abstraction

Sandy Metz

Pseudo-elements

TakeawayPseudo-elements allow us to style parts of an element

Notes
  • Similar to how certain pseudo-classes represent additional state information not directly present in the document tree, a pseudo-element represents an element not directly present in the document tree. They are used to create abstractions about the document tree beyond those provided by the markup.
  • Specification on pseudo-elements

Examples

List markers

li::marker {
	color: red;
}
­

Input placeholders

input::placeholder {
	color: slategray;
}
­

Text selection

::selection {
	background: rebeccapurple;
	color: white;
}
Notes

Note that some pseudo-elements can be very limited in what properties they support. E.g. try applying filter on ::marker or ::selection.

Notes

TakeawayPseudo-elements also allow us to insert content

CSS Variables / Custom properties

Notes
  • CSS variables (aka Custom Properties) start with -- and behave like normal CSS properties.
  • We read their value via the var() function and we can use that anywhere (including inside calc()), except inside url().
  • They are dynamic, and can be set in the inline style or even via JavaScript!
  • They help reduce repetition, and thus make code more maintainable. They also help encapsulation: Other people can use your components and style them via the variables you have exposed, without having to know and override the internal structure of your CSS.
  • Notice the repetition here: We have to repeat the button color 3 times! And changing it requires repeating so much code. How can CSS variables help us reduce this repetition and create themes more easily?
1