Crafting UI

The fundamentals

Agenda

The Cascade

Selectors

Nesting

The Cascade

Selectors

Agenda

Målet for i dag

  1. Blive bedre til CSS

  2. Forstå, hvordan Nesting hjælper med organisering

  3. Blive bedre til at bruge 

  4. Øvelser, øvelser og flere øvelser for at opbygge praktisk erfaring

Nesting

Selectors

Nesting

Agenda

Målet for i dag

  1. Forstå                            bedre

  2. Blive bedre til CSS                     og udvide kendskabet

  3. Forstå, hvordan                   hjælper med organisering

  4. Ø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

  1. Sæt en <h1> ind og centrer den både vertikalt og horisontalt i browser-vinduet
  2. Introducer et par <p>’er. <p>’erne skal have font-family 'system-ui' og <h1> skal have 'monospace'
  3. Sæt tekstfarven til 'gray' for <p>'erne og '#2b2b2b' for <h1>
  4. 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

  1. Tilføj en blå border på 4px til .my-input
  2. Kig i DevTools for at finde fejlen
  3. 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

  1. Blive bedre til CSS

  2. Forstå, hvordan Nesting hjælper med organisering

  3. Blive bedre til at bruge 

  4. Øvelser, øvelser og flere øvelser for at opbygge praktisk erfaring

Nesting

Selectors

  1. Oversæt selectoren (Fronter)

  2. 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

  1. Blive bedre til CSS

  2. Forstå, hvordan Nesting hjælper med organisering

  3. Blive bedre til at bruge 

  4. Ø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