[wip] CSS for JS developers

Pere Sola - Nov 26 '22 - - Dev Community

Well, I took the leap and bought Josh Comeau's CSS for JS developers course. Marketing works. Also because I read raving reviews and a co-worker spoke highly of it. Here is the list of stuff that I wish to remember, for my future self.

Module 0 - Fundamentals

  • pseudo-classes, they target state: There are many of them. For instance: :hover, :focus, :checked, :first-child (it needs to be the first child within its parent.) / :last-child (it needs to be the last child within its parent.), :first-of-type / :last-of-type.

Example Codepen pseudo-classes

  • pseudo-elements, they target sub elements. They target elements in the DOM that we haven't explicitly created with HTML: ::placeholder, ::before / ::after (they are secret spans, syntactic sugar).

Example Codepen pseudo-elements

  • Combinators (from "combines" multiple elements to create a descendant selector). It's about descendants, no matter how deep they are located: i.e. nav a (space between selectors - targets any descendant), nav > a (great than sign - targets only direct children).

Codepen

  • Colors. 4 representations of color: name, hexadecimal, rgb (red, green, blue) and hsl (hue, saturation, lightness). He recommends hsl, and it is clear why: it's very intuitive. hue is the pigmentation, in a circle, defined by degrees from 0 to 360. Saturation is the x axis and lightness is the y axis, both represented by %s. You can pass a final value, separated with a / for the opacity (between 0 [fully transparent] and 1 [fully opaque]). Like so: rgl(45deg 37% 45% / 0.75)

Image description

Codepen

  • Units: px, em and rem (root em). We all know pixels. em is relative the to font size of the current element. rem is relative to the font size of the html tag.

Codepen

  • Typography. font-weight can be bold or a value between 0 and 1000. line-height value is unitless (i.e. 15, NOT 15px or 15em). As per accessibility guidelines, it should be at least 1.5. This number is multiplied by the font-size of the element.

Codepen

Module 1 - Rendering logic

  • Inheritance. Some properties inherit and other not, an attempt to a list can be found here. The ones that inherit are mostly typography related. You can inherit in properties that do not by explicitly inheriting a property.

Codepen

  • Cascade. It's like spread syntax in JS:


const appliedStyles = {
  ...inheritedStyles,
  ...tagStyles,
  ...classStyles,
  ...idStyles,
  ...inlineStyles,
  ...importantStyles
}


Enter fullscreen mode Exit fullscreen mode

That's a pretty damn good analogy 👏

  • Block and inline directions. Block like Lego blocks, stack vertically. Inline, like people queuing in line, horizontally. Logical properties replace the usual top right bottom left because they offer support for non ltr languages.

  • Box model, like layers of clothes in winter: content (the person), padding (the stuffing), border (the material, which has a color, etc) and margin (personal space). By default box-sizing is content-box, which means that if width is 100% of the parent, this only affects the content of the child. Border, padding and margin are added on top. border-box includes content, padding, border and margin, see Codepen below.

This is a good CSS reset:



*,
*::before,
*::after {
  box-sizing: border-box;
}


Enter fullscreen mode Exit fullscreen mode

Codepen

  • Padding vs outline. padding affects the layout. outline does not, it's a decorative layer on top of the element. outline follows the curve of border-radius except in Safari. It also has an outline-offset to add space between the outline and the element.

Codepen

  • Margins. They can be negative. You can use auto for horizontal margins, which seeks to fill the maximum amount of space available. For vertical margins, it is the same as 0px. And it only works if the element has an explicit width. Margin can also be negative - it will shift the rest of the content. Very cool trip on how to make an image in a blog expand to the edge even though the container has padding, check out the codepen below.

Codepen

  • Flow layout. Default layout mode. 2 type of elements: Block elements (list here) and Inline elements (list here). We can toggle the mode with the display property. Inline elements can have margin left and right, but not vertical. inline-block is a block element that can be inlined in terms of layout but internally acts much more like a block element.

Codepen

  • Width algorithms. Block elements have width auto by default. These elements will grow as much as they can. 100% take the parent width, but if you have margins they are added on top. Keyword values: min-content (takes minimum content, the longest word. So the element is as narrow as it can be), max-content (takes the max, the whole content. So it is as wide as it can be, doesn't care about the available space. If the content is short, it may be narrower than the available space), fit-content fits whatever length, and if content is longer than the available space, it moves to next line - like width: auto.

Codepen

  • Height algorithms. height will shrink to the height of its content, like min-content in width we saw before. Setting height as precise unit is not a good idea. If you want to take 100% of the screen, you need to set the element height to 100% but also the parent one, like so:


html, body {
  height: 100%;
}


Enter fullscreen mode Exit fullscreen mode

Otherwise, having an element being 100% of the parent, which also shrinks to fit the content, doesn't make sense. vh is not recommended because of mobile devices.

Codepen

  • Margin collapse. Only vertical margins collapse. Only in Flow layout. Only adjacent elements. If margins are asymmetrical, the bigger one wins. Nesting doesn't prevent it. Margins only collapse when they are touching. They don't collapse when: there is a padding or border in between, there is a gap, or there is a scroll container. Margins can collapse in the same direction. More than 2 margins can collapse. Negative margins also collapse, with the same rule: the biggest wins i.e. in -40px vs -50px -50px wins.

Codepen

Module 2 - Rendering logic II

  • Positioned layout, the second layout mode we are looking at. The default value for position is static or initial.

  • Relative positioning. Setting position: relative and adjusting with top, right, bottom, left moves the element without impacting the layout of the rest of the elements of the page. This is the difference from the Flow layout and its negative margin. A block element that, without width, would take the available space and gets reduced when margin is applied, it would not change width with relative positioning.

Codepen

  • Absolute positioning. Positioned based on their container, not their in-flow position (that was relative). In terms of layout, the elements doesn't exist anymore ("it's like a ghost, you can stick your hand through it"). So 3 absolute positioned elements in the same position will stack on top of each other. Default placement without top, left, etc. is the place where it would go if it were not positioned or if it was positioned relative. position: absolute makes display property irrelevant. The size is the smallest as it can get. The max it will get is the view port, beyond that it will line wrap. If it can't line wrap, the container will comply but the content will overflow.

Codepen
Codepen 2 - centering trick with position: absolute and margin: auto

  • Containing blocks - in flow layout the containing block is its parent. In positioned elements, its containing block is the closest parent that uses positioned layout. And padding doesn't count. Exercise 2 video in the lesson contains an interesting explanation for using rem and not % for the border-radius.

Codepen
Exercise 1 Codepen
Exercise 2 Codepen

  • Stacking contexts. In Flow layout, the DOM order matters - whatever comes last, is on top. But the content is painted separately from border and background - the content will float on top. Positioned elements will always render on top of non-positioned ones, no matter the DOM order. If all elements are positioned, DOM order wins (last element on top).

Image description

z-index overrides the default behaviour (default behaviour === last DOM element on top). It only works with positioned elements. z-index won't work with the Flow layout.

Image description

A stacking context is created when an element is positioned and it has a z-index value. A stacking context means that the z-index's are compared between the children of this stacking context, they are not global. There are more ways to do so, explained in the lesson and in mdn. If the parent has a stacking context and is below another element, there is nothing a child can do with z-index to override it. So if an element with a high z-index is still below another element, is probably because the element is inside a stacking context. You may want to remove that stacking context so the child can be compared at the same level as the other element.

Codepen

  • isolation: isolate will create a stacking context - no need to position + z-index.

Codepen

  • fixed positioning. Same as absolute but they can only be contained by the view-port and they are immune to scrolling. When not anchored (this is, no top, left, etc. positioning) it sits in its natural position, like absolute. But can't be scrolled ofc. Certain css in the parent components will mess with the fixed positioning, mostly transform and related ones. The lesson has a lot of info on how to deal with this.

Codepen
Bonus Codepen

  • overflow. When content does not fit in the container. visible by default, scroll, auto (recommended - adds a scroll when needed), hidden (truncates everything that overflow). overflow is a shorthand for overflow-x and overflow-y. Windows and Mac have different defaults for scrollbars: Mac vertical, Windows vertical and horizontal, but Mac w mouse shows horizontal as well.

Codepen

Websites / Blog posts I learnt about along the way

Module 0
Module 1
Module 2
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .