.card:has(img) {
  display: grid;
  grid-template-columns: 2fr 3fr;
}

:is(h1, h2, h3) {
  color: red;
  text-wrap: balance;
  
  &:hover {
    color: blue;
  }
}

CSS Selectors

Reset.css

Nesting

Cascade Layers

Øvelser

Grid & Flexbox

I går

  1. Forstå (og mestre) CSS Selectors

  2. Anvende Reset.css for at sikre en ensartethed

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

  4. Vide, hvordan vi håndterer kompatibilitetsudfordringer

  5. Forstå og anvende principperne bag Cascade Layers

  6. Mestre Grid & Flexbox for at skabe designstrukturer

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

I går

Nåede vi, hvad vi skulle?

  1. Forstår (og mestrer) du CSS Selectors?

  2. Ser du værdien i et Reset.css?

  3. Har du godt greb om Nesting?

  4. Ved du, hvordan du håndterer kompatibilitetsudfordringer?

  5. Ser du værdien i Cascade Layers?

  6. Har du nogenlunde styr på Grid & Flexbox?

  7. Føler du, du har lært noget?

Grid & Flexbox

CSS Selectors

Reset.css

Nesting

Cascade Layers

@layer theme {
  html {
    --color: oklch(80% 2 220);
  }

  * {
    text-box-trim: both;
    text-box-edge: cap alphabetic;
  }
}

@layer component {
  div {
    margin-trim: block;
    padding: 2rlh;

    :is(article):has(&) {
      --rainbow-gradient: in oklch longer hue, red 0 0;
      
      padding-inline: max(1rem, (100% - 800px) / 2);
      background: linear-gradient(45deg var(--rainbow-gradient));
      container: div / inline-size;
    }

    :is(article) & {
      border: 2px solid color(display-p3 1 none 1);
      background: oklch(80% .37 220 / 25%);

      @container div (inline-size > 35rem) {
        font-size: calc(1rem * pow(1.25, 1));
      }
    }

    :is(aside) {
      container: aside / sticky;
      position: sticky;
      inset-block-start: 0;
      
      @container aside state(stuck) {
        & h2 {
          background: red;
        }
      }
    }

    :is(h2, h3) {
      inline-size: 17ch;
      text-wrap: balance;
    }

    > h2 {
      background: hsl(from var(--color) h s calc(l + 10%));
    }

    :not(article) & :nth-child(2 of .paragraph) {
      &:first-letter {
        initial-letter: 3;
        margin-inline-end: 1ch;
      }
    }

    & section {
      max-inline-size: 400px;

      > p {
        text-wrap: pretty;
      }

    }
  }
}

Grid & Flexbox

Mål: Mestre for at skabe designstrukturer

Øvelser

Skal du centrere noget?

Layout

Layout

.container {
  display: grid;
  place-content: center;
  width: 300px;
  height: 300px;
}

Skal du centrere noget?

Layout

.container {
  display: grid;
  place-content: center start;
  width: 300px;
  height: 300px;
}

Skal du centrere noget?

Skal du centrere noget?

Layout

.container {
  display: grid;
  place-content: end center;
  width: 300px;
  height: 300px;
}

Placér tekst ovenpå et <img>?

Layout

.container {
  display: grid;
  place-items: center;

  > * {
    grid-area: 1 / 1;
  }
}
<div class="container">
  <img src="...">
  <h3>...</h3>
</div>

Skal elementer automatisk wrappe?

Layout

.container {
  display: flex;
  flex-flow: wrap;
}

Skal elementer automatisk wrappe?

Layout

.container {
  display: flex;
  flex-flow: wrap;
  justify-content: center;
}

Skal elementer automatisk wrappe?

Layout

.container {
  display: flex;
  flex-flow: wrap;
}

.child {
  flex: 1;
}

Skal layoutet wrappe med grid?

Layout

.container {
  display: grid;
  grid-template-columns:
    repeat(auto-fit, minmax(200px, 1fr));
}

Elementerne skal

  • a) være lige bredde; dog mindst 200px,
  • b) fylde hele containeren,
  • og c) wrappe, når der ikke er plads til flere på en række

600-799px

Skal layoutet wrappe med grid?

Layout

.container {
  display: grid;
  grid-template-columns:
    repeat(auto-fit, minmax(200px, 1fr));
}

400-599px

Skal layoutet wrappe med grid?

Layout

.container {
  display: grid;
  grid-template-columns:
    repeat(auto-fit, minmax(200px, 1fr));
}

200-399px

Gotchas

Grid & Flex

1fr = minmax(auto, 1fr)
grid images = align-self: start;
flex images = align-self: stretch;

Crafting UI

w/ CSS (part 2)

Frontend, 3. semester

UI Components

UI Components

Subgrid

Container Queries

Cascade Layers

Øvelser

Subgrid

Container Queries

Cascade Layers

Øvelser

  1. Forstå, hvordan Subgrid hjælper med komplekse layouts

  2. Anvende Container Queries for at lave responsive komponenter

  3. Forstå og anvende principperne bag Cascade Layers

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

UI Components

Målet for i dag

Subgrid

Container Queries

Cascade Layers

Øvelser

Målet for i dag

  1. Forstå, hvordan Subgrid hjælper med komplekse layouts

  2. Anvende Container Queries for at lave responsive komponenter

  3. Forstå og anvende principperne bag Cascade Layers

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

UI Components

Subgrid

Mål: Forstå, hvordan det hjælper med komplekse layouts

Grid

.grid {
  align-items: last baseline;
  grid-template-columns: subgrid;
}

Nye funktionaliteter

Baseline alignment

Subgrid

Loading...

Subgrid

Loading...

.subgrid {
  display: grid;
  grid-template-rows:
    [system-status] 3.5rem
    [primary-nav] 3rem
    [primary-header] 4rem
    [main] auto
    [footer] 4rem
    [system-gestures] 2rem;
  grid-template-columns:
    [fullbleed-start] 1rem
    [main-start] auto
    [main-end] 1rem
    [fullbleed-end];
}

Subgrid

nav {
  grid-area: primary-nav / fullbleed;
  
  display: grid;
  grid-template-columns: subgrid;
}

nav > .content {
  grid-area: main;
}

Subgrid

Full-bleed grid

.container {
  display: grid;
  grid-template-columns:
    1fr minmax(0, 1200px) 1fr;
  column-gap: 1rem;
  
  > * {
    grid-column: 2;
  }
  
  .full-bleed {
    grid-column: 1 / -1;
  }
}

Navngiv grid-linjerne

   1fr          minmax(0, 1200px)          1fr

Full-bleed grid

.container {
  display: grid;
  grid-template-columns:
    [full-start] 1fr [main] minmax(0, 1200px) 1fr [full-end];
  column-gap: 1rem;
  
  > * {
    grid-column: main;
  }
  
  .full-bleed {
    grid-column: full;
  }
}

Navngiv grid-linjerne

 full-start          main               full-end

Full-bleed grid

Børnebørn følger ikke bredden

.container {
  display: grid;
  grid-template-columns:
    [full-start] 1fr [main] minmax(0, 1200px) 1fr [full-end];
  column-gap: 1rem;
  
  > * {
    grid-column: main;
  }
  
  .full-bleed {
    grid-column: full;
  }
}
 full-start          main               full-end

Common pattern

Subgrid

Subgrid-øvelse

.cards {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 1rem;
}

🤷‍♂️

Subgrid-øvelse

💩

Øvelse

Subgrid-øvelse

Ressourcer

Subgrid

truly flexible

Container Queries

Mål: Lave responsive componenter

Container Queries

Container queries kan ikke lade sig gøre

?

Container Queries

?

Container Queries

Hvis containerens bredde er > 400px, så sæt containerens bredde til 300px

🤷‍♂️

Hvis containerens bredde er 300px, så sæt containerens bredde til 600px

Container Queries

Løsningen? Containment

I praksis betyder det: en ekstra <div>

Container Queries

Løsningen? Containment

I praksis betyder det: en ekstra <div>

Container Queries

Container queries

vs media queries

Container queries

Container queries

@container (width > 640px) {
  .card {
    flex-direction: column;
  }
}
@media (width > 640px) {
  ...
}

Container queries

.card-wrapper {
  container-type: inline-size;
}

@container (width > 640px) {
  .card {
    flex-direction: column;
  }
}

Den ekstra div

Container queries

Container queries

:has() + Container queries

:has() + Container queries

Øvelse

> 600px

< 600px

  1. Kortet med billedet skal først tildeles et grid med to kolonner (2fr 3fr), når .card-wrapper er større end 600px
    • @container (width > 600px)
  2. .card-wrapper skal have containter-typen "inline-size"
    • container-type: inline-size; */

:has() + Container queries

Øvelse

> 600px

< 600px

  1. Kortet med billedet skal først tildeles et grid med to kolonner (2fr 3fr), når .card-wrapper er større end 600px
    • @container (width > 600px)
  2. .card-wrapper skal have containter-typen "inline-size"
    • container-type: inline-size; */

Container queries

Container queries

.card-wrapper {
  container-type: inline-size;
  container-name: main;
}

@container main (width > 640px) {
  .card {
    flex-direction: column;
  }
}

Container queries

.card-wrapper {
  container: main / inline-size;
}

@container main (width > 640px) {
  .card {
    flex-direction: column;
  }
}

Øvelse

> 600px

Container queries

< 400px

main

.card-wrapper

.card-wrapper {
  container: card / inline-size;
}

Container query units

.card-wrapper {
  container: card / inline-size;
}

.card {
  font-size: clamp(1.45rem, 6cqw, 1.75rem);
}

cqw, cqh, cqi, cqb, cqmin, cqmax

6 % af bredden

Container query units

Øvelse

Container query units

h2 {
  font-size: clamp(1.25rem, 5cqw, 2.5rem);
}

Container queries

Øvelse

Recap and beyond

Nåede vi, hvad vi skulle?

  1. Forstå, hvordan Subgrid hjælper med komplekse layouts

  2. Anvende Container Queries for at lave responsive komponenter

  3. Forstå og anvende principperne bag Cascade Layers

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

Crafting UI with CSS (part 2)

By Dannie Vinther

Crafting UI with CSS (part 2)

  • 71