Skip to content
This repository has been archived by the owner on Aug 15, 2024. It is now read-only.

Latest commit

Β 

History

History
2583 lines (1731 loc) Β· 72.8 KB

slides.md

File metadata and controls

2583 lines (1731 loc) Β· 72.8 KB
theme: ./theme
drawings:
  persist: false
title: My CSS journey
hideInToc: true
layout: full

BONJOUR


layout: image
hideInToc: true
image: '/images/pixel-perfect-studios.webp'

layout: full
hideInToc: true

produced by

drake

layout: image
hideInToc: true
image: '/images/stars-bg.webp'
In a close galaxy called Milky Way, on a planet named Earth, a tale unfolds β€” a saga of an extraordinary and unassuming guy that you are about to meet.

Our story happens in France, specifically in Montreuil 93 RPZ gang brr-brr skidiki-pap-pap.

Brace yourselves, for the epic journey is about to begin, transcending the ordinary and plunging into the extraordinary, where destinies are forged and legends are born.

layout: full
hideInToc: true
arrows Samuel MARLHENS
humble kind loyal honest cheerful blue eyes super smart polite cute And that's me!
hideInToc: true

My CSS journey

From zero to hero

painter

hideInToc: true

On the menu for this presentation

gordon gordon

What is a web page?


What is HTML?

HTML (HyperText Markup Language) is the most basic building block of the Web. It defines the meaning and structure of web content. Other technologies besides HTML are generally used to describe a web page's appearance/presentation (CSS) or functionality/behavior (JavaScript).

Source: developer.mozilla.org: HTML

tada

[...], for example defining paragraphs, headings, and data tables, or embedding images and videos in the page.

Source: developer.mozilla.org: What is JavaScript


What is CSS?

Cascading Style Sheets (CSS) is a stylesheet language used to describe the presentation of a document written in HTML or XML (including XML dialects such as SVG, MathML or XHTML). CSS describes how elements should be rendered on screen, on paper, in speech, or on other media.

Source: developer.mozilla.org: CSS

tada

CSS is a language of style rules that we use to apply styling to our HTML content, for example setting background colors and fonts, and laying out our content in multiple columns.

Source: developer.mozilla.org: What is JavaScript

  • [...]
  • CSS saves a lot of work. It can control the layout of multiple web pages all at once
  • External stylesheets are stored in CSS files

Source: w3schools.com


What is JavaScript?

JavaScript is a scripting language that enables you to create dynamically updating content, control multimedia, animate images, and pretty much everything else.

Source: developer.mozilla.org: JavaScript

tada

layout: cover

Getting started with HTML & CSS


Anatomy of an HTML document

<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>My test page</title>
  </head>

  <body>
    <!-- content aka HTML Elements -->
  </body>
</html>
  • doctype: It is a required preamble.
  • html: wraps all the content (known as root element)
  • head: all the stuff you want to include on the HTML page that isn't the content (e.g. CSS, fonts, scripts, etc.)
  • body: contains all the content (e.g. text, images, videos, etc.)

Source: developer.mozilla.org: HTML basics


Anatomy of an HTML element (1)

Non-exhaustive list of HTML elements:

  • Headings (<h1>, <h2>, ..., <h6>)
  • Paragraph (<p>)
  • Links (<a>)
  • Lists (<ul>, <ol>, <li>)
  • Images (<img>)
  • Tables (<table>, <tr>, <td>, <th>)
  • Forms (<form>, <input>, <button>, <select>, <textarea>)
  • Div (<div>)
  • Span (<span>)
  • [...]

Anatomy of an HTML element (2)

An attribute should have:

  • A space between it and the element name.
  • The attribute name, followed by an equal sign.
  • An attribute value, wrapped with opening and closing quote marks.

Non-exhaustive list of attributes:

  • class, id, name, type, aria-*, data-*

Starting with some HTML

```html

This is a red title

This is a blue text.

```

This is ugly. How am I going to add style?


How CSS works


What is the DOM?

The DOM (Document Object Model) is an API that represents and interacts with any HTML or XML-based markup language document. The DOM is a document model loaded in the browser and representing the document as a node tree, or DOM tree, where each node represents part of the document (e.g. an element, text string, or comment).

Source: developer.mozilla.org

A real representation

<body>
  <h1>This is a red title</h1>
  <p>This is a blue text.</p>
</body>
BODY
β”œβ”€β”€ H1
β”‚   └── "This is a red title"
└── P
    └── "This is a blue text."

Anatomy of a CSS ruleset

Non-exhaustive list of properties: font-size, color, background-color, padding, margin, border, border-radius, font-family, [...]

Non-exhaustive list of selectors:

Name Selector selects
element p <p>
id #my-id <element id="my-id">
class .my-class <element class="my-class">
attribute [data-color-mode=dark] <element data-color-mode="dark">
pseudo-class a:hover <a> only when mouse pointer is over the link

Styling HTML elements

<h1>This is a red title</h1>
<p>This is a blue text.</p>
h1 {
  color: red;
  font-size: 2.5rem;
  line-height: 1;
}

p {
  color: blue;
}
by polarstar

Where can I write this CSS?


How to load CSS?

<head>
  <style>
    h1 {
      color: red;
      font-size: 5rem;
      line-height: 1;
    }

    p {
      color: blue;
    }
  </style>
</head>
/* main.css */
h1 {
  color: red;
  font-size: 5rem;
  line-height: 1;
}

p {
  color: blue;
}
<head>
  <link href="main.css" rel="stylesheet" />
</head>

Hmmm! How am I going to add style to an entire website? πŸ€¨πŸ§πŸ€”


title: HTML, CSS & JS framework
level: 1

HTML, CSS & JS framework:Bootstrap

Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web.

Source: getbootstrap.com - Bootstrap v3.3 (2014)


How to use Bootstrap?

<head>
  <!-- Local Bootstrap CSS file -->
  <link href="/css/bootstrap.css" rel="stylesheet" />
  <!-- OR using a CDN -->
  <link
    crossorigin="anonymous"
    href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
    integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
    rel="stylesheet"
  />
  <!-- custom local CSS file -->
  <link href="/css/main.css" rel="stylesheet" />
</head>
<button type="button" class="btn btn-default">Default</button>
<button type="button" class="btn btn-primary">Primary</button>
<button type="button" class="btn btn-success">Success</button>
<button type="button" class="btn btn-info">Info</button>
<button type="button" class="btn btn-warning">Warning</button>
<button type="button" class="btn btn-danger">Danger</button>

How to customize Bootstrap?

* using Bootstrap v3.3 back in 2014

  • Use LESS (built with) - (πŸ€” what is it?)
  • Use Sass (official port) - (πŸ€” what is it?)
  • CSS Cascade - default behavior (may not be officially recommended)

Source: getbootstrap.com - Bootstrap v3.3 (2014)

CSS Cascade, you said ?


CSS Cascade algorithm

The cascade is the algorithm for solving conflicts where multiple CSS rules apply to an HTML element. The cascade algorithm is split into 5 distinct stages.

Source: web.dev, developer.mozilla.org

  1. Position and order of appearance
  1. Specificity: an algorithm which determines which CSS selector has the strongest match
  1. Cascade layers: layered style < unlayered style < !important unlayered style < !important layered style
  1. Origin:css cascade origin
what is this important rule
  1. Importance: normal rule (e.g., color) < animation rule < !important rule < transition rule

Source: developer.mozilla.org. Nice blog: 2019.wattenberger.co.


CSS Specificity

Source: css-tricks.com

  • When selectors have an equal specificity value, the latest rule is the one that counts.
  • When selectors have an unequal specificity value, the more specific rule is the one that counts.
  • !important always win, only way to bypass is another !important declared later

Source: smashingmagazine.com


Specificity examples

/* (0,0,1,1,1) */
#myElement input.myClass {
  color: red;
}
/* (0,0,0,2,1) */
[id='myElement'] input.myClass {
  color: yellow;
}
/* (0,0,0,2,1) */
input[type='password']:required {
  color: blue;
}
/* (0,0,0,0,4) */
html body main input {
  color: green;
}

How to override Bootstrap using CSS Specificity?

main.css

html {
  position: relative;
  min-height: 100%;
}

.navbar-default {
  background-color: #eee;
  border-color: #eee;
}

.btn {
  transition: all ease-in-out 0.2s;
}

End of 2 years IT university diploma πŸ‘¨πŸ»β€πŸŽ“

  • Graduation πŸŽ‰
  • Learn so far: HTML, CSS, JavaScript, Bootstrap, jQuery*

Next πŸ‘¨πŸ»β€πŸŽ“ ?

3 years engineering IT work-study program:
Single Page Application*, Angular*, Angular Material, Material Design, Sass

* will not be addressed, see more at: developer.mozilla.org/SPA, api.jquery.com & v7.angular.io/docs


Material Design

Material Design […] is a design language developed by Google in 2014. […], Material Design uses more grid-based layouts, responsive animations and transitions, padding, and depth effects such as lighting and shadows.

Source: wikipedia.org/Material_Design

Material Design is a design system built and supported by Google designers and developers. Material.io includes in-depth UX guidance and UI component implementations for Android, Flutter, and the Web.

Source: m3.material.io

A design language or design vocabulary is an overarching scheme or style that guides the design of a complement of products or architectural settings, creating a coherent design system for styling.

Source: wikipedia.org/Design_language

A Design system is a collection of reusable components and clear standards that can be assembled together to build any number of applications.

Source: InVision


What does Material Design look like?

Source: m2.material.io - Angular Material v2

Source: wikipedia.org/Material_Design - Angular Material v3


M2M3


How to add theme to Angular Material?

Angular Material's theming APIs are built with Sass. This document assumes familiarity with CSS and Sass basics, including variables, functions, and mixins.
You can use Angular Material without Sass by using a pre-built theme, described in Using a pre-built theme below. However, using the library's Sass API directly gives you the most control over the styles in your application.

Source: material.angular.io


CSS preprocessor

A CSS preprocessor is a program that lets you generate CSS from the preprocessor's own unique syntax.

Source: developer.mozilla.org


A few of most popular CSS preprocessors:


Sass

CSS on its own can be fun, but stylesheets are getting larger, more complex, and harder to maintain. This is where a preprocessor can help. Sass has features that don’t exist in CSS yet like nesting, mixins, inheritance, and other nifty goodies that help you write robust, maintainable CSS.

Source: sass-lang.com

How to use?

CLI:

sass --watch input.scss output.css

OR

sass --watch input.sass output.css

πŸ’‘ Fun fact: Sass has two syntaxes!


Sass syntax: SCSSThe Indented Syntax

@mixin button-base() {
  @include typography(button);
  @include ripple-surface;
  @include ripple-radius-bounded;

  /* […] */
  height: $button-height;
  /* […] */

  &:hover {
    cursor: pointer;
  }

  &:disabled {
    color: $mdc-button-disabled-ink-color;
    cursor: default;
    pointer-events: none;
  }
}

The SCSS syntax (.scss) is used most commonly. It’s a superset of CSS [...].

@mixin button-base()
  @include typography(button)
  @include ripple-surface
  @include ripple-radius-bounded

  /* […] */
  height: $button-height
  /* […] */

  &:hover
    cursor: pointer

  &:disabled
    color: $mdc-button-disabled-ink-color
    cursor: default
    pointer-events: none

The indented syntax (.sass) is more unusual: it uses indentation rather than curly braces to nest statements, and newlines instead of semicolons to separate them.

Source: sass-lang.com


Sass variables, partials, modules

// _base.scss
$font-stack: Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}
// styles.scss
@use 'base';

.inverse {
  background-color: base.$primary-color;
  color: white;
}
body {
  font:
    100% Helvetica,
    sans-serif;
  color: #333;
}

.inverse {
  background-color: #333;
  color: white;
}

Other features: extend/inheritance, operators, functions, at-rules (if, each, for), lists, maps.

Source: sass-lang.com/guide, sass-lang.com/documentation


Angular Material theme example

// whatever.scss
@import '~@angular/material/theming';

@include mat-core();

$candy-app-primary: mat-palette($mat-indigo);
$candy-app-accent: mat-palette($mat-pink, A200, A100, A400);

$candy-app-warn: mat-palette($mat-red);

$candy-app-theme: mat-light-theme($candy-app-primary, $candy-app-accent, $candy-app-warn);

@include angular-material-theme($candy-app-theme);

Source: v7.material.angular.io


Angular Material usage

component.html

<button mat-raised-button>Basic</button>
<button mat-raised-button color="primary">Primary</button>
<button mat-raised-button color="accent">Accent</button>
<button mat-raised-button color="warn">Warn</button>
<button mat-raised-button disabled>Disabled</button>
<a mat-raised-button routerLink=".">Link</a>

End of studies πŸ‘¨πŸ»β€πŸŽ“ & start of working life πŸ‘¨πŸ»β€πŸ’»

  • Graduation πŸŽ‰
  • Angular (Material Design) + me = ❀️


Angular MDC

* another Material Design implementation for Angular (!== Angular Material)

Example usage:

<aside class="mdc-snackbar">
  <div class="mdc-snackbar__surface" role="status" aria-relevant="additions">
    <div class="mdc-snackbar__label" aria-atomic="false">Can't send photo. Retry in 5 seconds.</div>
    <div class="mdc-snackbar__actions" aria-atomic="true">
      <button type="button" class="mdc-button mdc-snackbar__action">
        <div class="mdc-button__ripple"></div>
        <span class="mdc-button__label">Retry</span>
      </button>
    </div>
  </div>
</aside>
snackbar

Source: github.com/material-components


Block Element Modifier (BEM)

The Block, Element, Modifier methodology (commonly referred to as BEM) is a popular naming convention for classes in HTML and CSS. […], its goal is to help developers better understand the relationship between the HTML and CSS in a given project.

Source: css-tricks.com

Syntax:

block__element--modifier
  • Block: header, container, menu, checkbox, input, card, button, …
  • Element: title, item, caption, icon
  • Modifier: disabled, highlighted, checked, size, color

Source: getbem.com


An example using BEM

index.html

<button class="button"><span class="button__label">Normal button</span></button>
<button class="button button--success button--large">
  <span class="button__icon"></span><span class="button__label">Success button</span>
</button>
<button class="button button--danger button--outlined">Danger button</button>

main.css

.button {
  /* […] */
}

.button__label {
  /* […] */
}

.button--success {
  /* […] */
}

main.scss

.button {
  /* […] */

  &__label {
    /* […] */
  }

  &--success {
    /* […] */
  }
}

βœ… Pros & ❌ cons of using BEM

  • Modularity:
    • never dependent on other elements (no cascading problem)
    • transfer blocks
  • Reusability:
    • reduces the amount of CSS code to maintain
    • you can build a library of blocks
  • Structure:
    • simple and easy to understand

Source: getbem.com

  • Bundle:
    • without minifying/gzipping can bloat CSS files size

Keep on learning πŸ“š

So far I know (or I thought I know):

  • how to write CSS
  • how to write Sass & use BEM
  • use a CSS Framework (Bootstrap)
  • use a Design System (Material Design)

Next step πŸš€ ?

How to create a design system ?


Atomic design

Atomic design is methodology for creating design systems. There are five distinct levels in atomic design: atoms, molecules, organisms, templates, pages.

Source: bradfrost.com

atomic design


Atomic design: atoms

Atoms are the basic building blocks of matter. Applied to web interfaces, atoms are our HTML tags, such as a form label, an input or a button.

Source: bradfrost.com

atoms

Atomic design: molecules

Molecules are groups of atoms bonded together and are the smallest fundamental units of a compound. These molecules take on their own properties and serve as the backbone of our design systems.

Source: bradfrost.com

molecule

Atomic design: organisms

Organisms are groups of molecules joined together to form a relatively complex, distinct section of an interface.

Source: bradfrost.com

organism

Atomic design: templates

Templates consist mostly of groups of organisms stitched together to form pages. It’s here where we start to see the design coming together and start seeing things like layout in action.

Source: bradfrost.com

template

Atomic design: pages

Pages are specific instances of templates. Here, placeholder content is replaced with real representative content to give an accurate depiction of what a user will ultimately see.

Source: bradfrost.com

page

layout: cover
hideInToc: true

Pause β˜•

pause


New opportunities at

  • 09/2014 - 01/2022: CSS, Bootstrap, Material Design, Sass, BEM, Atomic design
  • UPCITI: utility-first CSS framework tailwindcss, dark mode, theme configuration, CSS variables, CSS-in-JS, CSS layers


title: Utility-first CSS framework
level: 1

Utility-first CSS framework:tailwindcss

tailwindcss example

Traditional approach:

<div class="chat-notification">
  <div class="chat-notification-logo-wrapper">
    <img class="chat-notification-logo" src="/img/logo.svg" alt="ChitChat Logo" />
  </div>
  <div class="chat-notification-content">
    <h4 class="chat-notification-title">ChitChat</h4>
    <p class="chat-notification-message">You have a new message!</p>
  </div>
</div>
.chat-notification {
  /* […] */
}

Source: tailwindcss.com


Utility-first CSS framework:tailwindcss

tailwindcss example

Utility classes approach:

<div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-lg flex items-center space-x-4">
  <div class="shrink-0">
    <img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo" />
  </div>
  <div>
    <div class="text-xl font-medium text-black">ChitChat</div>
    <p class="text-slate-500">You have a new message!</p>
  </div>
</div>

Source: tailwindcss.com


How to use tailwindcss?

// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  /* […] */
  content: ['./src/**/*.{html,js,ts,vue}'],
  /* […] */
};
// index.scss
@tailwind base;
@tailwind components;
@tailwind utilities;
  • Build your CSS using CLI / bundler
  • Import SCSS / CSS in HTML / TS

Source: tailwindcss.com


A unique theme(to rule them all?): 🎨 multi-palettes

// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  /* […] */
  theme: {
    extend: {
      colors: {
        primary: {
          900: 'var(--color-primary-900)',
          // 800, 700, 600, 500, 400, 300, 200, 100, 50
        },
      },
    },
  },
};
// index.scss
.palette-a {
  --color-primary-900: #881337;
  /* […] */
}

.palette-b {
  --color-primary-900: #0c4a6e;
  /* […] */
}

.palette-c {
  --color-primary-900: #064e3b;
  /* […] */
}

Source: tailwindcss.com


CSS variables or custom properties

Custom properties (sometimes referred to as CSS variables or cascading variables) are entities defined by CSS authors that represent specific values to be reused throughout a document.

Source: developer.mozilla.org

How to declare?

/* @property at-rule */
@property --logo-color {
  syntax: '<color>';
  inherits: false;
  initial-value: #c0ffee;
}
/* prefix of two dashes (--) */
section {
  --logo-color: #c0ffee;
}

How to use?

details {
  color: var(--logo-color, #c0ffee);
}

Other features:

  • :root pseudo-class
  • inheritance
  • fallback values

Component using tailwindcss classes

<!-- ButtonPrimary.vue -->
<template>
  <button
    type="button"
    :class="[
      'relative inline-flex items-center rounded-lg border text-sm font-bold focus:outline-none focus:ring-2 focus:ring-offset-2',
      'disabled:cursor-not-allowed disabled:opacity-50',
      'border-transparent bg-primary-900 text-base-50 hover:bg-primary-800 focus:ring-primary-800 dark:border-transparent dark:bg-base-600 dark:text-base-200 dark:hover:bg-base-500 dark:focus:ring-base-200 dark:focus:ring-offset-base-700',
      'px-4 py-2',
    ]"
  ></button>
</template>

⚠️ Maintainability:

  • How to share button common classes?
  • It's not typed-safe (using TypeScript)
  • HTML class size bloat

πŸ’‘ Some ideas to begin with…

Use JavaScript object to share classes:

export const colors = {
  button: {
    common: 'relative inline-flex items-center rounded-lg border text-sm font-bold focus:outline-none […]',
    spacing: 'px-4 py-2',
    disabled: 'disabled:cursor-not-allowed disabled:opacity-50',
    // […]
  },
};

But still:

<!-- ButtonPrimary.vue -->
<template>
  <button
    type="button"
    :class="[colors.button.common, colors.button.disabled, colors.button.primary, colors.button.spacing]"
  ></button>
</template>

A persistent problem πŸ€”

  • I need to create one Vue component per variant (button example: primary, secondary, outlined, success, warning, info, error)
  • How to split set of classes for a component ? (like modifiers?)
  • Same issues with headlessui (unstyled, fully accessible UI components)

Presentation of a CSS-in-JS tool: Pinceau

CSS-in-JS

CSS-in-JS is a styling technique by which JavaScript is used to style components. When this JavaScript is parsed, CSS is generated (usually as a <style> element) and attached into the DOM. It enables the abstraction of CSS to the component level itself, using JavaScript to describe styles in a declarative and maintainable way.

Source: en.wikipedia.org

* State of CSS 2023 Plenty of tools: CSS modules, styled-components, Emotion, Stitches, JSS Other tools: Panda

Source: 2023.stateofcss.com

Note: Meta open-sourced its CSS-in-JS tool early in December 2023: stylex.

state of css 2023 css-in-js

CSS modules

A CSS Module is a CSS file in which all class names and animation names are scoped locally by default.

Source: github.com/css-modules

Usage with Vite:

/* example.module.css */
.red {
  color: red;
}
// index.js
// .apply-color -> applyColor
import { red } from './example.module.css';

document.getElementById('foo').className = red;
βœ… Pros: no deps, no config, easy to use ❌ Cons: write (S)CSS, write default theme as global

Usage in Vue Single-File Component (SFC):

<template>
  <p :class="classes.red">red</p>
</template>

<style module="classes">
.red {
  color: red;
}
</style>

βœ… Pros:

  • no deps, no config, easy to use

❌ Cons:

  • write (S)CSS
  • write default theme as global
  • Does not work in Functional Components/render functions

🐼 Panda

Panda is a new CSS-in-JS engine that aims to solve the challenges of CSS-in-JS in the server-first era. It provides styling primitives to create, organize, and manage CSS styles in a type-safe and readable manner.

Source: panda-css.com

panda bubble tea

How to install?

// panda.config.js
import { defineConfig } from '@pandacss/dev';

export default defineConfig({
  preflight: true,
  presets: [], // <-- import custom preset
  include: ['./src/**/*.{js,jsx,ts,tsx,vue}'],
  outdir: 'styled-system',
});
panda codegen
/* src/index.css */
@layer reset, base, tokens, recipes, utilities;
<!-- src/App.vue -->
<script setup lang="ts">
import { css } from '../styled-system/css';

const classes = css({
  fontSize: '5xl',
  fontWeight: 'bold',
});
</script>

<template>
  <div :class="classes">Hello 🐼!</div>
</template>

CSS Cascade Layers

* c.f. CSS Cascade algorithm

Cascade layers are most relevant when you're working with CSS from multiple sources when there are conflicting CSS selectors and competing specificities, or when you're considering using !important.

Source: developer.mozilla.org

/* unlayered author style: specificity is used */
.overly#powerful .framework.widget {
  color: maroon;
}

/* add some IDs to this ??? */
.my-single_class {
  /* add !important ??? */
  color: rebeccapurple;
}

Source: css-tricks.com

@layer framework {
  .overly#powerful .framework.widget {
    color: maroon;
  }
}

@layer site {
  .my-single_class {
    color: rebeccapurple;
  }
}

Other features: nested layers, anonymous layers, import styles based on conditions (media/feature queries), etc.


Design Tokens

Design tokens are a methodology for expressing design decisions in a platform-agnostic way so that they can be shared across different disciplines, tools, and technologies. They help establish a common vocabulary across organisations.

Source: Design Tokens Format Module from W3C

Design tokens are the platform-agnostic way to manage design decisions in your application or website. It is a collection of attributes that describe any fundamental/atomic visual style. Each attribute is a key-value pair.

Source: panda-css.com


Tokens in panda

/* panda.config.js */
import { defineConfig } from '@pandacss/dev';

export default defineConfig({
  theme: {
    // πŸ‘‡πŸ» Define your tokens here
    tokens: {
      colors: {
        primary: { value: '#0FEE0F' },
        secondary: { value: '#EE0F0F' },
      },
      fonts: {
        body: { value: 'system-ui, sans-serif' },
      },
    },
  },
});
<!-- HelloWorld.vue -->
<template>
  <p :class="classes">Hello World</p>
</template>

<script setup lang="ts">
import { css } from '../styled-system/css';

const classes = css({
  color: 'primary',
  fontFamily: 'body',
});
</script>

Source: panda-css.com


What is a preset

By default, any configuration you add in your own panda.config.js file is smartly merged with the default configuration, allowing your override or extend specific parts of the configuration.

Source: panda-css.com

What does it contain?

  • Include base preset
  • Define colors, breakpoints, tokens (sizes, animations, line-heigths etc.), utilities, fonts, global style, etc.
  • Conditions: dark / light mode, multiple themes

Custom preset

import { definePreset } from '@pandacss/dev';
import pandaPreset from '@pandacss/preset-panda';

const basePreset = definePreset({
  presets: [pandaPreset],
  theme: {
    extend: {
      breakpoints: {
        xs: '475px',
        '3xl': '1920px',
      },
      tokens: {
        sizes: {
          '8xl': { value: '85rem' },
          '9xl': { value: '90rem' },
        },
      },
    },
  },
});
import { definePreset } from '@pandacss/dev';

export const orgPreset = definePreset({
  presets: [basePreset],
  conditions: {
    light: '',
    dark: '.dark &',
    orgTheme: '.org &',
  },
  theme: {
    extend: {
      /**
       * colors > org > 900 > value
       * fonts > inter > value
       */
      tokens: {},
      semanticTokens: {},
    },
  },
});

Define multiple theme

const config = {
  conditions: {
    light: '[data-color-mode=light] &',
    dark: '[data-color-mode=dark] &',
    pinkTheme: '[data-theme=pink] &',
    blueTheme: '[data-theme=blue] &',
  },
};
<template>
  <div data-theme="pink" data-color-mode="dark">
    <h1 :class="classes">Hello World</h1>
  </div>
</template>
<script setup lang="ts">
import { css } from '../styled-system/css';

const classes = css({
  color: 'text',
});
</script>
const theme = {
  // ...
  semanticTokens: {
    colors: {
      text: {
        value: {
          _pinkTheme: {
            base: '{colors.pink.500}',
            _dark: '{colors.pink.300}',
          },
          _blueTheme: {
            base: '{colors.blue.500}',
            _dark: '{colors.blue.300}',
          },
        },
      },
    },
  },
};

Source: panda-css.com


πŸ“œ Recipes

A recipe is a way to write CSS-in-JS with better performance, developer experience, and composability. One of its key features is the ability to create multi-variant styles with a type-safe runtime API.

Source: panda-css.com

Atomic recipes are a way to create multi-variant atomic styles with a type-safe runtime API.

Source: panda-css.com

Config recipes are extracted and generated just in time, this means regardless of the number of recipes in the config, only the recipes and variants you use will exist in the generated CSS.

Source: panda-css.com


βš›οΈ Atomic recipeβš™οΈ Config recipe

Config recipe Atomic recipe (cva)
Can both use any theme tokens, utilities or conditions βœ… yes βœ… yes
Are generated just in time (JIT) based on usage βœ… yes, only the recipe variants found in your code will be generated ❌ no, all variants found in your cva recipes will always be generated
Can be shared in a preset βœ… yes, you can include it in your preset.theme.recipes ❌ no
Can be colocated in your markup code ❌ no, they must be defined or imported in your panda.config βœ… yes, you can place it anywhere in your app
Generate atomic classes ❌ no, a specific className will be generated using your recipe.className βœ… yes

Source: panda-css.com


Define and use a recipe

import { cva } from '../styled-system/css';

const button = cva({
  base: {
    display: 'flex',
  },
  variants: {
    visual: {
      solid: { bg: 'red.200', color: 'white' },
      outline: {
        borderWidth: '1px',
        borderColor: 'red.200',
      },
    },
    size: {
      sm: { padding: '4', fontSize: '12px' },
      lg: { padding: '8', fontSize: '24px' },
    },
  },
});

Atomic recipe example

<!-- ButtonPrimary.vue -->
<template>
  <button :class="classes"></button>
</template>

<script setup lang="ts">
import { button } from '<path>/button.recipe.ts';

const classes = button({
  visual: 'solid',
  size: 'lg',
});
</script>

Source: panda-css.com


Storybook is a frontend workshop for building UI components and pages in isolation. Thousands of teams use it for UI development, testing, and documentation.

Source: storybook.js.org

A documentation tool is a tool for documenting design tokens usage. For example: Storybook.

Source: Design Tokens Format Module from W3C


Button recipe usage

<template>
  <button :class="classes" title="Save" @click="submit">Save</button>
</template>
<script setup lang="ts">
import { button } from '@scope/design-system';

const classes = button({ variant: 'primary', size: 'md' });
</script>

Button component usage

<template>
  <ButtonComponent visual="primary" size="md" title="Save" @click="submit">Save</ButtonComponent>
  <ButtonComponent visual="error" rounded="none" title="Delete" @click="delete">Delete</ButtonComponent>
</template>
<template>
  <ButtonComponent visual="outline" content="icon" title="Export file to CSV" @click="export">
    <IconComponent class="h-5 w-5" :icon="faFileExport" />
  </ButtonComponent>
</template>

Monorepo structure

A monorepo is a single repository containing multiple distinct projects, with well-defined relationships.

Source: monorepo.tools

.
└── packages/
    β”œβ”€β”€ preset-panda/
    β”œβ”€β”€ design-system/
    β”‚   β”œβ”€β”€ public/
    β”‚   β”‚   └── fonts/
    β”‚   β”œβ”€β”€ recipes/
    β”‚   β”œβ”€β”€ components/
    β”‚   └── stories/
    └── app/
        β”œβ”€β”€ node_modules/
        β”‚   └── @scope/styled-system
        └── src/
            β”œβ”€β”€ components/
            └── pages/
  • preset-panda: export your base / project / organization specific preset.
  • design-system: export the content you need to use your design system (e.g. static files + recipes + components)
  • @scope/styled-system: generated panda CSS Utilities (such as css function) & types based on preset & buildinfo from design-system.
  • app/src: contains your custom application pages/components that are specific to your context

Summary

Notions: HTML & CSS basics, CSS Specificity, CSS Frameworks, CSS preprocessor, CSS Variables, CSS-in-JS, CSS Cascade Layers

Glossary: Design system, Design tokens

Methodologies: BEM, Atomic Design

CSS frameworks: Bootstrap, Material Components, tailwindcss, panda

Tools: Storybook

What's next ? : web-components, WASM, Rust


layout: cover
hideInToc: true

Thanks for listening!

Do you have any questions?

questions