Crafting UI
The fundamentals
Agenda
The Cascade
Selectors
Nesting
The Cascade
Selectors
Agenda
Målet for i dag
-
Blive bedre til CSS
-
Forstå, hvordan Nesting hjælper med organisering
-
Blive bedre til at bruge
-
Øvelser, øvelser og flere øvelser for at opbygge praktisk erfaring
Nesting
Selectors
Nesting
Agenda
Målet for i dag
-
Forstå bedre
-
Blive bedre til CSS og udvide kendskabet
-
Forstå, hvordan hjælper med organisering
-
Øvelser, øvelser og flere øvelser for at opbygge praktisk erfaring
The Cascade
The Cascade
Reset
Mål: Forstå the cascade bedre
Inheritance
Specificity
Cascade Layers

* {
margin: 0;
box-sizing: border-box;
}
img {
display: block;
max-width: 100%;
height: auto;
}
Hvorfor gør vi det?
html {
display: block;
}
head {
display: none;
}
body {
display: block;
margin: 8px;
}
h1 {
display: block;
font-size: 2em;
margin-block-start: 0.67em;
margin-block-end: 0.67em;
font-weight: bold;
}
a:-webkit-any-link {
color: -webkit-link;
cursor: pointer;
text-decoration: underline;
}
Defaults
User Agent Stylesheet
En masse regler er defineret, inden du selv har skrevet en linje CSS
Browser
Defaults

.example {
display: flex;
}
.example > .child {
}
Defaults

.example {
display: flex;
align-items: stretch;
justify-content: normal;
align-content: normal;
align-items: normal;
flex-direction: row;
flex-wrap: nowrap;
}
.example > .child {
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
}


Defaults

* {
border-style: solid;
border-width: 0;
}

* {
border-style: solid;
border-width: 0;
}

:not(progress, meter) {
border-style: solid;
border-width: 0;
}
CSS Reset
Et bedre udgangspunkt
Reset.css
body {
margin: unset;
min-height: 100svh;
}
* {
margin: 0;
box-sizing: border-box;
}
img {
display: block;
max-width: 100%;
height: auto;
}
:not(progress, meter) {
border-style: solid;
border-width: 0;
}
Reset.css
body {
min-height: 100svh /* 100dvh */;
}
...
* {
margin: 0;
box-sizing: border-box;
}
img {
display: block;
max-width: 100%;
height: auto;
}
:not(progress, meter) {
border-style: solid;
border-width: 0;
}
Temaets reset
Øvelse
- Sæt en <h1> ind og centrer den både vertikalt og horisontalt i browser-vinduet
- Introducer et par <p>’er. <p>’erne skal have font-family 'system-ui' og <h1> skal have 'monospace'
- Sæt tekstfarven til 'gray' for <p>'erne og '#2b2b2b' for <h1>
- Sæt et <a> ind under den sidste <p> (skifter farven?)
- Hvordan får vi farven til at være den samme som <p>?
Quiz
specificity & inheritance
:not(.special) a {
color: red;
}
<ul>
<li>
<a>Link</a>
</li>
<li class="special">
<a>Link</a>
</li>
<li>
<a>Link</a>
</li>
</ul>
Quiz
specificity & inheritance
p {
color: green;
}
#context {
color: red;
}
<div id="context">
<p>Some text</p>
</div>
<!DOCTYPE html>
<html lang="da">
<head>...</head>
<body>
<p>Brødtekst <span>her</span>...</p>
</body>
</html>
<p>Brødtekst <span>her</span>...</p>
Inheritance
Brødtekst her...
<span>
body {
color: red;
}
Brødtekst her...
<!DOCTYPE html>
<html lang="da">
<head>...</head>
<body>
<p>Brødtekst <span>her</span>...</p>
</body>
</html>
<p>Brødtekst <span>her</span>...</p>
Inheritance
Brødtekst her...
<!DOCTYPE html>
<html lang="da">
<head>...</head>
<body>
<p>Brødtekst <span>her</span>...</p>
</body>
</html>
<p>Brødtekst <span>her</span>...</p>
Inheritance
body {
color: red;
}
p {
color: blue;
}
Brødtekst her...
<!DOCTYPE html>
<html lang="da">
<head>...</head>
<body>
<p>Brødtekst <span>her</span>...</p>
</body>
</html>
<p>Brødtekst <span>her</span>...</p>
Inheritance
p {
color: blue;
}
span {
color: #000;
}
<!DOCTYPE html>
<html lang="da">
<head>...</head>
<body>
<h1>Heading 1</h1>
<main>
<h2>Heading 2</h2>
<p>Lorem ipsum dolor sit.</p>
<section>
<h3>Hello</h3>
<p>Lorem ipsum dolor sit amet consectetur.</p>
</section>
</main>
</body>
</html>
body {
color: red;
}
Inheritance
<!DOCTYPE html>
<html lang="da">
<head>...</head>
<body>
<h1>Heading 1</h1>
<main>
<h2>Heading 2</h2>
<p>Lorem ipsum dolor sit.</p>
<section>
<h3>Hello</h3>
<p>Lorem ipsum dolor sit amet consectetur.</p>
</section>
</main>
</body>
</html>
main {
color: red;
}
Inheritance
<!DOCTYPE html>
<html lang="da">
<head>...</head>
<body>
<h1>Heading 1</h1>
<main>
<h2>Heading 2</h2>
<p>Lorem ipsum dolor sit.</p>
<section>
<h3>Hello</h3>
<p>Lorem ipsum dolor sit amet consectetur.</p>
</section>
</main>
</body>
</html>
section {
color: red;
}
Inheritance
<!DOCTYPE html>
<html lang="da">
<head>...</head>
<body>
<h1>Heading 1</h1>
<main>
<h2>Heading 2</h2>
<p>Lorem ipsum dolor sit.</p>
<section>
<h3>Hello</h3>
<p>Lorem ipsum dolor sit amet consectetur.</p>
</section>
</main>
</body>
</html>
section p {
color: red;
}
Inheritance
<!DOCTYPE html>
<html lang="da">
<head>...</head>
<body>
<h1>Heading 1</h1>
<main>
<h2>Heading 2</h2>
<p>Lorem ipsum dolor sit.</p>
<section>
<h3>Hello</h3>
<p>Lorem ipsum dolor sit amet consectetur.</p>
</section>
</main>
</body>
</html>
main {
font-size: 1.1rem;
}
section p {
color: red;
}
Inheritance
<!DOCTYPE html>
<html lang="da">
<head>...</head>
<body>
<h1>Heading 1</h1>
<main>
<h2>Heading 2</h2>
<p>Lorem ipsum dolor sit.</p>
<section>
<h3>Hello</h3>
<p>Lorem ipsum dolor sit amet consectetur.</p>
</section>
</main>
</body>
</html>
main {
font-size: 1.1rem;
}
section p {
color: red;
font-size: 1rem;
}
Inheritance
Inheritance
Properties, der nedarves:
-
color
-
font-family
-
font-size
-
font-weight
-
line-height
-
list-style
-
text-align
-
m.m.
html {
color: gray;
line-height: 1.5;
font-family: system-ui, sans-serif;
}
h1,
h2,
h3 {
color: #000;
line-height: 1.1;
font-family: "My Display Font";
}
fra reset?
global.css
Cascade Layers
Mål: Forstå principperne bag

Cascade Layers
Mål: Forstå principperne bag

Reset



Jeres tur
The cascade
- Tilføj en blå border på 4px til .my-input
- Kig i DevTools for at finde fejlen
- Lad den være åben
Quiz
p:not(#id) {
color: green;
}
p.class {
color: red;
}
<p class="class">text</p>
<p id="id">last text</p>
p.test a {
color: green;
}
a:hover {
color: deeppink;
}
<p class="test">
<a href="#0">Hvilken farve?</p>
</p>
Quiz
The cascade
Author styles
0,0,0
0,0,1

🤷♂️
Cascade layers
Layer A
Layer A
Layer C
Cascade layers
Layer A
Layer B
Layer C
input[type="text"] {
border: 1px solid gray;
}
.my-input {
border: 4px solid blue;
}
Højeste prioritet
Laveste prioritet
Cascade layers
Layer A
Layer B
Layer C
input[type="text"] {
border: 1px solid gray;
}
.my-input {
border: 4px solid blue;
}
Højeste prioritet
Laveste prioritet
Cascade layers
Layer A
Layer B
Layer C
input[type="text"] {
border: 1px solid gray;
}
.my-input {
border: 4px solid blue;
}
Højeste prioritet
Laveste prioritet
Cascade layers
@layer reset {
/* ... other reset rules */
input[type="text"] {
border: 1px solid gray;
}
}
@layer components {
/* ... other component rules */
.my-input {
border: 4px solid blue;
}
}
input[type="text"] {
border: 1px solid gray;
}
.my-input {
border: 4px solid blue;
}
Layer A
Layer B
Cascade layers
@layer reset, components, utilities;
@layer reset {
/* ... other reset rules */
input[type="text"] {
border: 1px solid gray;
}
}
@layer components {
/* ... other component rules */
.my-input {
border: 4px solid blue;
}
}
configure up front
Cascade layers
@layer reset, components, utilities;
@layer components {
/* ... other component rules */
.my-input {
border: 4px solid blue;
}
}
@layer reset {
/* ... other reset rules */
input[type="text"] {
border: 1px solid gray;
}
}
1
2
3
configure up front
Cascade layers
@layer a, b;
@layer a {
header#my-header nav#my-nav ul li.link-item:hover {
color: red;
}
}
@layer b {
.link-item {
color: blue;
}
}
Cascade layers
@layer reset, global, components, utilities;
Cascade layers
@layer reset, global, components, utilities;
Hvert projekt
Projektspecifikt?
Projektspecifikt!
One-offs, hvert projekt?
Cascade layers
@layer reset, global, components, utilities;
@layer reset {
ul[class] {
margin: 0;
padding: 0;
list-style: none;
text-align: start;
}
}
@layer utilities {
.flow {
> * + * {
margin-top: 1em;
}
}
}
eksempel
Cascade layers
øvelse
ul[class] {
margin: 0;
padding: 0;
list-style: none;
}

Cascade layers
øvelse
.flow {
> * + * {
margin-top: 1rlh;
}
}



Cascade layers
øvelse
ul[class] {
margin: 0;
padding: 0;
list-style: none;
}
.flow {
> * + * {
margin-top: 1rlh;
}
}



0,1,1
0,1,0
Cascade layers
øvelse

@layer reset, global, components, utilities;
Cascade layers
@layer reset, global, components, utilities;
@import "./reset.css" layer(reset);
@layer global {
...
}
Astro
global.css
Cascade layers
Astro
---
---
<article class="card">
...
</article>
<style>
@layer components.card {
article {
/* component specific styles */
}
}
</style>
The Cascade
Selectors
Agenda
Målet for i dag
-
Blive bedre til CSS
-
Forstå, hvordan Nesting hjælper med organisering
-
Blive bedre til at bruge
-
Øvelser, øvelser og flere øvelser for at opbygge praktisk erfaring
Nesting
Selectors
-
Oversæt selectoren (Fronter)
-
Vi kigger på det i plenum
Øvelser - 30 min
Mål: Blive bedre og udvide kendskabet
li:nth-last-child(odd):first-child
Vælg det første liste-element i rækken, men kun hvis det samtidigt er ulige, hvis man tæller fra slutningen af listen.

:nth-child(2 of .featured)
Vælg det andet element, men kun hvis det er en af de elementer, der har 'featured'-klassen.
:has()
Selectors
Mål: Blive bedre og udvide kendskabet
artcle:has(> img) {}
p:not(article > *) { ... }
article > :is(.class, #id) { ... }
article > :where(.class, #id) { ... }
:is(), :where(), :not()
:has()
article:has(h2) { ... }
article:has(h2, h3) { ... }
article:has(h2):has(h3) { ... }
article:not(:has(h2)) img { ... }
article:has(> :last-child:nth-child(3)) { ... }
:has()
Hvad styler vi her?
:has()
body {
display: grid;
}
body:has(main + aside) {
grid-template-columns: 1fr 300px;
}
:has()
"Kom i gang"-øvelser

:has()
Øvelse 1

50ch
:not(:has(img))
:has()
Øvelse 2



:has()
display: contents;
p:has(img) {
display: contents;
}
<article>
<img>
</article>
<p>
</p>
:has()
display: contents;
p:has(img) {
display: contents;
}
<article>
<img>
</article>
<p>
</p>
:has()
display: contents;
p:has(img) {
display: contents;
}
<article>
<img>
</article>
<p>
</p>
Opfører sig nu som barn af <article>
:has()

:has()
Øvelse 3
Øvelse 3
:has()
Løsning
ul:not(:has(> li:nth-child(5))) {
display: flex;
justify-content: center;
}
:has()
:has()
:has()
:has()
:has()
:root:has(dialog[open]) {
overflow: hidden;
}
:has()
Loading...
The Cascade
Selectors
Agenda
Målet for i dag
-
Blive bedre til CSS
-
Forstå, hvordan Nesting hjælper med organisering
-
Blive bedre til at bruge
-
Øvelser, øvelser og flere øvelser for at opbygge praktisk erfaring
Nesting
Nesting
Mål: Forstå, hvordan det hjælper med organisering
Nesting
section {
border: 2px solid red;
}
section
color: red;
}
h2 {
Nesting
section {
border: 2px solid red;
color: red;
}
h2 {
color: red;
}
Nesting
section {
border: 2px solid red;
color: red;
}
}
&
h2 {
<section>
<h2></h2>
<h3></h3>
<p></p>
<article>
<h2></h2>
</article>
</section>
Nesting
section {
border: 2px solid red;
color: red;
}
}
>
h2 {
<section>
<h2></h2>
<h3></h3>
<p></p>
<article>
<h2></h2>
</article>
</section>
Nesting
section {
border: 2px solid red;
color: red;
}
}
:is( , h3)
h2 {
<section>
<h2></h2>
<h3></h3>
<p></p>
<article>
<h2></h2>
</article>
</section>
Nesting
:is()
:where()
:nth-child()
.
>
+
~
[data-*]
&
Symboler
Nesting
h1,
h2 {
& span {
color: blue;
}
}
& === :is(h1, h2)
Nesting
h1 {
color: red;
& {
color: blue;
}
}
Nesting
h1 {
color: red;
@media (width > 500px) {
color: blue;
}
}
Nesting
h1 {
@media (width > 500px) {
color: blue;
}
color: red;
}
Nesting
h1 {
@media (width > 500px) {
color: blue;
}
color: red;
}
h1 {
color: red; /* hoisted */
@media (width > 500px) {
color: blue;
}
}
1
2
Nesting
h1 {
& {
color: blue;
}
color: red;
}
Nesting
h1 {
article & {
color: red;
}
}
Nesting
h1 {
color: blue;
article & {
color: red;
}
}
if / else
<h1>I'm blue</h1>
<div class="parent">
<h1>I'm red</h1>
</div>
Nesting
h1 {
color: blue;
article & {
color: red;
}
}
if / else
<h1>I'm blue</h1>
<article>
<h1>I'm red</h1>
</article>
Nesting
h2 {
color: blue;
section :nth-last-child(2 of &) {
color: red;
}
}
Nesting
a {
background: red;
&:hover {
background: blue;
}
}
Co-location
Nesting
a {
background: red;
&.btn {
padding: .5rem;
&:hover {
background: blue;
}
}
}
Co-location
Nesting
a {
background: red;
&.btn {
padding: .5rem;
&:is(:hover, :focus-visible) {
background: blue;
}
}
}
Co-location
Nesting
Øvelse

Omskriv til nesting
Nesting

Øvelse
Al logik skal være i .article {}
Slides
Crafting UI: Fundamentals
By Dannie Vinther
Crafting UI: Fundamentals
Crafting UI with css
- 38