Albéric Trancart
Fullstack dev @ Theodo
Tech lead & Coach @Theodo
Meetup organizer @HumanTalksParis
@alberictrancart
Albéric Trancart
.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;
}
.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>
Some properties cascade and others do not
Example: color cascade but padding doesn't
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
Unsupported properties
Example: grid
or position: sticky
with IE11
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
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
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
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?
Relative
Absolute
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
Those CSS rules?
I [learn] them yesterday!
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>
Using a language is conveying an intent
through vocabulary structured by a grammar
calc()
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;
}
Every property that doesn't work as you would expect warrants a deep dive on MDN
.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???
A stacking context is an isolated container which places its child elements on a z-axis facing the user
Inside a stacking context, elements will be stacked in this order (back to front):
z-index
, in the z-index
orderA stacking context is created by:
<html>
elementposition: absolute
or position: relative
and a z-index
position: fixed
or position: sticky
z-index
transform
, filter
, clip-path
...<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;
}
Try to visualize the result in your head
then confront your mental model to reality
Apply concepts to your problems
In this example: boxes/box model, margin vs padding, layout algorithms
Create a whole design system without CSS libraries (such as MaterialUI, Bootstrap...)
Use headless libs such as ReachUI/RadixUI to build accessible components
Investigate lots of diluted information sources
Everything in one place
https://cssdojo.dev
@alberictrancart
Albéric Trancart
By Albéric Trancart