Tech lead & Coach @Theodo

Meetup organizer @HumanTalksParis

      @alberictrancart

Albéric Trancart

Part I

A little horror story

.title {
  font-size: 30px;
  font-family: sans-serif;
  color: #366CC3;
  border: 3px solid #366CC3;
  padding: 15px;
  width: 200px;
  border-radius: 20px;
  vertical-align: middle;
}
<body>
  <div class="title">
    Why<br />
    <strong>C</strong>SS<br />
    <strong>S</strong>ometimes<br />
    <strong>S</strong>ucks<br />
  </div>
</body>
<body>
  <div class="title">
    Why<br />
    CSS<br />
    Sometimes<br />
    Sucks<br />
  </div>
</body>
<body>
</body>
<body>
  <div>
    Why<br />
    CSS<br />
    Sometimes<br />
    Sucks<br />
  </div>
</body>
.title {
  font-size: 30px;
  font-family: sans-serif;
  color: #366CC3;
  border: 3px solid #366CC3;
  padding: 15px;
  width: 200px;
  border-radius: 20px;
}
.title {
  font-size: 30px;
  font-family: sans-serif;
  color: #366CC3;
  border: 3px solid #366CC3;
  padding: 15px;
  width: 200px;
  border-top-left-radius: 20px;
  border-top-right-radius: 20px;
}
.title {
  font-size: 30px;
  font-family: sans-serif;
  color: #366CC3;
  border: 3px solid #366CC3;
  padding: 15px;
  width: 200px;
  border-top-left-radius: 20px;
}
.title {
  font-size: 30px;
  font-family: sans-serif;
  color: #366CC3;
  border: 3px solid #366CC3;
  padding: 15px;
  width: 200px;
}
.title {
  font-size: 30px;
  font-family: sans-serif;
  color: #366CC3;
  border: 3px solid #366CC3;
  padding: 15px;
}
.title {
  font-size: 30px;
  font-family: sans-serif;
  color: #366CC3;
  border: 3px solid #366CC3;
}
.title {
  font-size: 30px;
  font-family: sans-serif;
  color: #366CC3;
}
.title {
  font-size: 30px;
  font-family: sans-serif;
}
.title {
  font-size: 30px;
}

Let's ask for some help

Nice, an answer to my issue!

.container {
  position: relative;
  height: 100vh;
}
.title {
  font-size: 30px;
  font-family: sans-serif;
  color: #366CC3;
  border: 3px solid #366CC3;
  padding: 15px;
  width: 200px;
  border-radius: 20px;
  position: absolute;
  top: 50%;
  -ms-transform: translateY(-50%);
  transform: translateY(-50%);
}
<body>
  <div class="container">
    <div class="title">
      Why<br />
      <strong>C</strong>SS<br />
      <strong>S</strong>ometimes<br />
      <strong>S</strong>ucks<br />
    </div>
  </div>
</body>

CSS is black magic

But magic doesn't exist!

CSS can be frustrating

It's not a fatality!

Why is CSS frustrating?

Is it because it's not intuitive?

Some properties cascade and others do not

Example: color cascade but padding doesn't

CSS

JS

Array indexing

Example : someArray[0] to access the 1st element

Properties interact between each other

Example: position et z-index

Default behaviors are not intuitive

Example: <img> is display: inline

 

Type coercion

"3" - 1  // -> 2
"3" + 1  // -> "31"

Default behaviors are not intuitive

try { return 2; }
finally { return 3; }
// -> returns 3

Why is CSS frustrating?

Unsupported properties

Example: grid or position: sticky with IE11

CSS

JS

Many standards/environments at the same time

Example: CJS vs ESM, npm vs yarn vs pnpm

An infinity of screen sizes to support

It's impossible to test on every device combination

Code must be transpiled

Example: configuring Babel/Typescript is not a trivial task

Is it because we have to support countless devices?

Part II

The real issue with CSS

Is CSS a programming language?

Twitter says no... But is CSS a language?

Is CSS a language?

But what is a language?

A language is a structured form of communication.

The structure of a language is its grammar and the free components are its vocabulary.

Using a language is conveying an intent

through vocabulary structured by a grammar

Intent

Do we know what we want to convey?

You

Normal language

Recipient

Sequence of words with a correct syntax

Computer

Product Owner

Normal language

Computer

Code

Code

You

User Story

Loss of intent

Interpretation

Intent

Do we know what we want to convey?

Designer

Computer

Code

You

Mock up

Product Owner

User Story

CSS

What should be the sidebar width?

Absolute? 200px? 15rem? 10cm?

What is the intent?

Relative? Percentage of the container? Percentage of the viewport?

Should it maintain its aspect ratio?

Intent

Do we know what we want to convey?

?

Relative

Absolute

Vocabulary

Do we know the meaning of the words to use?

Trap #1: some words differ in meaning from the English language (false friends)

Trap #2: some words have multiple meanings (polysemy)

Example: vertical-align do not align vertically a block in its parent box

Example: vertical-align can align an inline box inside its line or align some content in a table cell

Grammar

Do we know how to form correct sentences?

Those CSS rules?

I [learn] them yesterday!

  • Subject, verb and object
  • Nouns and Pronouns
  • Subject-verb agreement
  • Verb tenses
  • Verb aspects (simple/perfect/etc.)
  • Auxiliary verbs
  • Irregular verbs
  • US vs British English
  • Flow layout
  • Box model
  • Block container box
  • Block/inline-level box
  • Anonymous box
  • Block formatting context
  • Inline formatting context
  • Outer/inner display type
span { border: 1px solid black; }
.child { display: inline-block; }
<span>Will you be able to</span>
<span class="child">predict <div>how</div></span>
<span>this code will look like?</span>

Meh, what the hell?!

And no one

told us so!

  • Flow layout
  • Box model
  • Block container box
  • Block/inline-level box
  • Anonymous box
  • Block formatting context
  • Inline formatting context
  • Outer/inner display type

CSS has a grammar...

Grammar

Do we know how to form correct sentences?

Part III

Making peace with CSS

Using mental models

All models are wrong, some are useful

Using a language is conveying an intent

through vocabulary structured by a grammar

Is the intent clear enough?

The code must convey the intent

  • Use variables!
  • Use calc()
  • Stylelint rule declaration-strict-value
// Theme file
$border-color: #444;
$sm-breakpoint: 768px;
$modal-z-index: 7;

// Component file
$select-option-height: 2rem;
.select-dropdown {
  $border-width: 1px;
  border: $border-width solid $border-color;
  max-height: calc(2 * $border-width + 8 * $select-option-height);
}

@media (min-width: $sm-breakpoint) {
  z-index: $modal-z-index;
}
.select-dropdown {
  border: 1px solid #444;
  max-height: 34px;
}

@media (min-width: 768px) {
  z-index: 7;
}

Is the vocabulary well known?

Investigate each property that looks suspicious

Every property that doesn't work as you would expect warrants a deep dive on MDN

Is the grammar clear enough?

A good mental model is better than a list of edge cases

Is the grammar clear enough?

z-index shenanigans...

.menu-options {
  background-color: red;
  position: absolute;
  z-index: 10;
  left: 30px;
}
.content {
  position: relative;
}
.tooltip {
  position: absolute;
  z-index: 1;
  top: 0px;
  left: 50px;
  width: 100px;
  height: 50px;
  background-color: black;
  color: white;
}
<div class="menu disabled">
  Dropdown
  <div class="menu-options">Dropdown options</div>
</div>
<div class="content">
  Content text
  <div class="tooltip">Tooltip</div>
</div>
<div class="menu">
  Dropdown
  <div class="menu-options">Dropdown options</div>
</div>
<div class="content">
  Content text
</div>
<div class="menu">
  Dropdown
  <div class="menu-options">Dropdown options</div>
</div>
<div class="content">
  Content text
  <div class="tooltip">Tooltip</div>
</div>
.menu-options {
  background-color: red;
  position: absolute;
  z-index: 10;
  left: 30px;
}
.menu-options {
  background-color: red;
  position: absolute;
  z-index: 10;
  left: 30px;
}
.content {
  position: relative;
}
.tooltip {
  position: absolute;
  z-index: 1;
  top: 0px;
  left: 50px;
  width: 100px;
  height: 50px;
  background-color: black;
  color: white;
}
.menu.disabled {
  opacity: 0.8;
}

Why is the z-index 10 element
behind everything???

Is the grammar clear enough?

Stacking contexts

A stacking context is an isolated container which places its child elements on a z-axis facing the user

Is the grammar clear enough?

Stacking contexts

Inside a stacking context, elements will be stacked in this order (back to front):

  • Non positioned elements, in the order they appear in the DOM
  • Positioned elements, in the order they appear in the DOM
  • Positioned elements of flex items that have a z-index, in the z-index order

A stacking context is created by:

  • The <html> element
  • An element with position: absolute or position: relative and a z-index
  • An element with position: fixed or position: sticky
  • A child of a flex or grid container with a z-index
  • An element with an opacity different from 1
  • An element with on of those properties: transform, filter, clip-path...

Is the grammar clear enough?

z-index shenanigans...

<div class="menu">
  Dropdown
  <div class="menu-options">Dropdown options</div>
</div>
<div class="content">
  Content text
  <div class="tooltip">Tooltip</div>
</div>
.menu-options {
  background-color: red;
  position: absolute;
  left: 30px;
  z-index: 20;
}
.content {
  position: relative;
}
.tooltip {
  position: absolute;
  top: 0px;
  left: 50px;
  width: 100px;
  height: 50px;
  background-color: black;
  color: white;
  z-index: 1;
}
.menu.disabled {
  opacity: 0.9;
}

Is the grammar clear enough?

Stacking contexts

  1. A stacking context is an isolated container
  2. Elements are placed in the 3rd dimension by a list of rules
  3. It is possible to create new stacking contexts

Is the grammar clear enough?

The main concepts to know

  • Specificity
  • The box model
  • The flow layout
  • Inner/outer display types
  • Stacking contexts
  • then flex and grid

Practicing models and concepts

Tip #1: during the code review

Try to visualize the result in your head

then confront your mental model to reality

Practicing models and concepts

Tip #2: draw your problem

Apply concepts to your problems

In this example: boxes/box model, margin vs padding, layout algorithms

Practicing models and concepts

Tip #3: no CSS framework challenge

Create a whole design system without CSS libraries (such as MaterialUI, Bootstrap...)

Use headless libs such as ReachUI/RadixUI to build accessible components

How to learn CSS concepts?

Some ressources

  • MDN

Investigate lots of diluted information sources

  • The CSS spec
  • Blog articles / StackOverflow questions

Everything in one place

Concepts to understand

Live editors to practice

Recaps to remember

Questions to challenge

A final word...

Let's recap!

CSS can be frustrating...

we didn't even know about their existence!

instead of a list of properties and edge cases

because it relies on rules and concepts

Learning and understanding these concepts

is the guarantee to be able to face any situation

Thank you!

https://cssdojo.dev

      @alberictrancart

Albéric Trancart

Why CSS Sometimes Sucks (IPC Webinale Berlin 2023)

By Albéric Trancart

Why CSS Sometimes Sucks (IPC Webinale Berlin 2023)

  • 199