Kurs HTML i CSS · Moduł 9: Nowoczesny CSS

CSS Functions - matematyka w stylu egipskich skrybów

8 min czytania ·
W tej lekcji11

Witaj w Nekropolii Gizy matematyki CSS! Podobnie jak starożytni egipcy używali zaawansowanej matematyki do budowy piramid, tak my możemy używać CSS Functions do tworzenia dynamicznych, responsywnych i elastycznych stylów. Poznaj funkcje matematyczne, które rewolucjonizują sposób pisania CSS!

Czym są CSS Functions?

CSS Functions to wbudowane funkcje, które wykonują obliczenia i zwracają wartości. Pozwalają na tworzenie dynamicznych stylów bez JavaScript!

Najważniejsze funkcje matematyczne:

  • calc() - podstawowe obliczenia
  • min() - najmniejsza wartość
  • max() - największa wartość
  • clamp() - wartość w zakresie
  • minmax() - dla CSS Grid

Analogia egipska: To jak egipski skryba wykonujący precyzyjne obliczenia dla budowy piramidy - matematyka wbudowana bezpośrednio w plany!

calc() - podstawowe obliczenia

calc() pozwala na wykonywanie matematycznych operacji z różnymi jednostkami:

Podstawowa składnia

.element {
  /* Dodawanie */
  width: calc(100% - 50px);

  /* Odejmowanie */
  height: calc(100vh - 80px);

  /* Mnożenie */
  font-size: calc(16px * 1.5);

  /* Dzielenie */
  padding: calc(20px / 2);

  /* Kombinacje */
  margin: calc((100% - 960px) / 2);
}

Ważne zasady:

  • Spacje wokół + i - są WYMAGANE: calc(100% - 50px), calc(100%-50px)
  • Spacje wokół * i / są opcjonalne
  • Można mieszać jednostki (%, px, rem, vh, etc.)
  • Można zagnieżdżać calc()

Praktyczne przykłady calc()

1. Layout z sidebar

.container {
  display: flex;
}

.sidebar {
  width: 250px;
  flex-shrink: 0;
}

.main-content {
  /* Szerokość = 100% minus sidebar minus gap */
  width: calc(100% - 250px - 20px);
}
.main {
  /* 100vh minus wysokość header (80px) i footer (60px) */
  min-height: calc(100vh - 80px - 60px);
}

3. Responsywne padding

.section {
  /* Padding rośnie z rozmiarem ekranu */
  padding: calc(20px + 2vw);
  /* Na 320px: 20px + 6.4px = 26.4px */
  /* Na 1920px: 20px + 38.4px = 58.4px */
}

4. Grid z gap

.grid {
  display: grid;
  grid-template-columns: repeat(3, calc((100% - 40px) / 3));
  gap: 20px;
  /* 3 kolumny, 2 gaps po 20px = 40px total gap */
}

5. Aspect ratio box (przed aspect-ratio property)

.aspect-16-9 {
  width: 100%;
  /* 9/16 = 0.5625 = 56.25% */
  padding-bottom: calc(9 / 16 * 100%);
  position: relative;
}

.aspect-16-9 > * {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

min() - najmniejsza wartość

min() zwraca najmniejszą wartość z podanych. Idealne do ustawiania maksymalnych limitów!

.element {
  /* Nigdy więcej niż 800px, ale może być mniejszy */
  width: min(800px, 100%);

  /* Równoważne: */
  width: 100%;
  max-width: 800px;
}

Praktyczne przykłady min()

1. Responsywny max-width

.container {
  /* Maksymalnie 1200px, ale 90% na małych ekranach */
  width: min(1200px, 90%);
  margin: 0 auto;
}

2. Responsywny font-size

h1 {
  /* Maksymalnie 48px, ale skaluje się z ekranem */
  font-size: min(48px, 5vw);
}

3. Padding z limitem

.section {
  /* Padding rośnie, ale maksymalnie 80px */
  padding: min(80px, 5vw);
}

4. Multi-column z min()

.grid {
  display: grid;
  /* Kolumny minimum 250px, maksimum równe części */
  grid-template-columns: repeat(auto-fit, min(250px, 100%));
  gap: 20px;
}

max() - największa wartość

max() zwraca największą wartość z podanych. Idealne do ustawiania minimalnych limitów!

.element {
  /* Nigdy mniejszy niż 200px, ale może być większy */
  width: max(200px, 50%);

  /* Równoważne: */
  width: 50%;
  min-width: 200px;
}

Praktyczne przykłady max()

1. Responsywny min-width

.card {
  /* Minimum 300px, ale może rosnąć */
  width: max(300px, 30%);
}

2. Font-size z minimum

body {
  /* Minimum 16px, ale rośnie z ekranem */
  font-size: max(16px, 1vw);
}

3. Spacing z minimum

.section {
  /* Minimum 20px padding, nawet na małych ekranach */
  padding: max(20px, 3vw);
}

4. Grid columns z minimum

.grid {
  /* Kolumny minimum 200px */
  grid-template-columns: repeat(auto-fit, minmax(max(200px, 25%), 1fr));
}

clamp() - wartość w zakresie

clamp() to najpo tężniejsza funkcja - zwraca wartość ograniczoną do zakresu!

Składnia: clamp(minimum, preferowana, maksimum)

.element {
  /* Minimum 16px, preferowane 2vw, maksimum 32px */
  font-size: clamp(16px, 2vw, 32px);
}

Jak działa:

  1. Jeśli preferowana < minimum → zwróć minimum
  2. Jeśli preferowana > maksimum → zwróć maksimum
  3. W przeciwnym razie → zwróć preferowaną

Praktyczne przykłady clamp()

1. Fluid typography - NAJLEPSZE UŻYCIE

h1 {
  /* Font size od 24px do 64px, skaluje się płynnie */
  font-size: clamp(24px, 4vw + 1rem, 64px);
}

h2 {
  font-size: clamp(20px, 3vw + 1rem, 48px);
}

h3 {
  font-size: clamp(18px, 2.5vw + 1rem, 36px);
}

p {
  font-size: clamp(16px, 1vw + 0.5rem, 20px);
}

/* Jeden system typografii dla wszystkich ekranów! */

2. Container width

.container {
  /* Od 320px do 1200px, płynnie skaluje */
  width: clamp(320px, 90%, 1200px);
  margin: 0 auto;
}

3. Spacing system

:root {
  /* Płynne spacing od małych do dużych ekranów */
  --spacing-xs: clamp(0.5rem, 1vw, 1rem);
  --spacing-sm: clamp(1rem, 2vw, 1.5rem);
  --spacing-md: clamp(1.5rem, 3vw, 2.5rem);
  --spacing-lg: clamp(2rem, 4vw, 4rem);
  --spacing-xl: clamp(3rem, 6vw, 6rem);
}

.section {
  padding: var(--spacing-lg);
  margin-bottom: var(--spacing-md);
}

4. Line height

p {
  font-size: clamp(16px, 1vw + 0.5rem, 20px);
  /* Line height też płynny! */
  line-height: clamp(1.5, 0.5vw + 1.3, 1.8);
}

5. Grid gap

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  /* Płynny gap */
  gap: clamp(1rem, 2vw, 3rem);
}

6. Button padding

.button {
  /* Padding rośnie z rozmiarem ekranu */
  padding: clamp(0.5rem, 1vw, 1rem) clamp(1rem, 2vw, 2rem);
  font-size: clamp(14px, 1.5vw, 18px);
}

Zaawansowane kombinacje

calc() + min/max/clamp

.element {
  /* Szerokość z dynamicznym padding */
  width: calc(min(1200px, 100%) - 2rem);

  /* Wysokość z minimum i dynamicznym offset */
  height: calc(max(400px, 50vh) - 80px);

  /* Padding proporcjonalny z limitami */
  padding: calc(clamp(1rem, 3vw, 3rem) * 0.5);
}

Zagnieżdżone funkcje

.container {
  /* Maksymalnie 1400px, ale minimum 90%, z padding */
  width: calc(min(1400px, 90%) - clamp(1rem, 3vw, 3rem) * 2);
}

CSS Variables + Functions

:root {
  --base-spacing: 1rem;
  --multiplier: 2;
  --max-spacing: 4rem;
}

.element {
  /* Dynamiczne spacing z variables */
  padding: clamp(
    var(--base-spacing),
    calc(var(--base-spacing) * var(--multiplier)),
    var(--max-spacing)
  );
}

Kompletny system Fluid Typography

:root {
  /* Viewport units dla skalowania */
  --fluid-min-width: 320;
  --fluid-max-width: 1920;

  /* Font sizes */
  --fluid-xs: clamp(0.75rem, 0.5vw + 0.5rem, 0.875rem);
  --fluid-sm: clamp(0.875rem, 0.75vw + 0.625rem, 1rem);
  --fluid-base: clamp(1rem, 1vw + 0.75rem, 1.125rem);
  --fluid-md: clamp(1.125rem, 1.5vw + 0.75rem, 1.5rem);
  --fluid-lg: clamp(1.5rem, 2vw + 1rem, 2rem);
  --fluid-xl: clamp(2rem, 3vw + 1.25rem, 3rem);
  --fluid-2xl: clamp(2.5rem, 4vw + 1.5rem, 4rem);
  --fluid-3xl: clamp(3rem, 5vw + 2rem, 5rem);
}

body {
  font-size: var(--fluid-base);
  line-height: clamp(1.5, 0.3vw + 1.4, 1.7);
}

h1 {
  font-size: var(--fluid-3xl);
  line-height: 1.1;
}

h2 {
  font-size: var(--fluid-2xl);
  line-height: 1.2;
}

h3 {
  font-size: var(--fluid-xl);
  line-height: 1.3;
}

.small {
  font-size: var(--fluid-sm);
}

.large {
  font-size: var(--fluid-lg);
}

Inne użyteczne CSS Functions

attr() - pobierz atrybut

.tooltip::after {
  content: attr(data-tooltip);
  /* Użyj wartości atrybutu jako content */
}

var() - CSS Variables

:root {
  --primary-color: #3498db;
  --spacing: 20px;
}

.element {
  color: var(--primary-color);
  padding: var(--spacing);

  /* Z fallback */
  background: var(--secondary-color, #2ecc71);
}

rgb(), rgba(), hsl(), hsla()

.element {
  /* RGB */
  color: rgb(52, 152, 219);

  /* RGBA z alpha */
  background: rgba(52, 152, 219, 0.5);

  /* HSL (Hue, Saturation, Lightness) */
  color: hsl(204, 70%, 53%);

  /* HSLA */
  background: hsla(204, 70%, 53%, 0.5);
}

url() - zasoby zewnętrzne

.element {
  background-image: url('pyramid.jpg');
  list-style-image: url('hieroglyph.svg');
}

Performance i wsparcie przeglądarek

Wsparcie przeglądarek:

  • calc() - wszędzie (od 2013)
  • min(), max() - Chrome 79+, Firefox 75+, Safari 11.1+ (2020)
  • clamp() - Chrome 79+, Firefox 75+, Safari 13.1+ (2020)

Performance:

  • Funkcje są obliczane TYLKO gdy wartości się zmieniają
  • Lepsze niż JavaScript dla prostych obliczeń
  • GPU-accelerated gdy używane z transform

Fallbacks dla starych przeglądarek:

.element {
  /* Fallback */
  font-size: 20px;

  /* Modern browsers */
  font-size: clamp(16px, 2vw, 32px);
}

/* Lub z @supports */
@supports (font-size: clamp(16px, 2vw, 32px)) {
  .element {
    font-size: clamp(16px, 2vw, 32px);
  }
}

Best Practices

  1. Używaj clamp() dla fluid typography - jeden system dla wszystkich ekranów
  2. Kombinuj z CSS Variables - łatwiejsze utrzymanie
  3. Testuj na różnych rozdzielczościach - szczególnie edge cases
  4. Dodawaj fallbacks - dla starszych przeglądarek
  5. Dokumentuj zakresy - komentarze pomocne dla innych
/* Dobrze udokumentowane */
h1 {
  /* 24px @ 320px → 64px @ 1920px */
  font-size: clamp(24px, 1.5rem + 2.5vw, 64px);
}

Podsumowanie

CSS Functions - zastosowania:

  • calc() - podstawowe obliczenia, mixing units
  • min() - maksymalne limity (max-width bez max-width)
  • max() - minimalne limity (min-width bez min-width)
  • clamp() - wartości w zakresie, fluid typography

Zalety:

  • Dynamiczne wartości bez JavaScript
  • Automatyczna responsywność
  • Mniej media queries
  • Płynne skalowanie

Najlepsze use cases:

  • Fluid typography system
  • Responsive spacing
  • Container widths
  • Layout calculations
Kod do tej lekcji: index.html
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>accent-color</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1>accent-color - stylowanie kontrolek</h1>
    <form class="egyptian-form">
        <fieldset>
            <legend>Wybierz swiatyni</legend>
            <label><input type="checkbox" checked> Karnak</label>
            <label><input type="checkbox"> Luxor</label>
            <label><input type="checkbox"> Abu Simbel</label>
        </fieldset>
        <fieldset>
            <legend>Ulubiony bog</legend>
            <label><input type="radio" name="god" checked> Ra</label>
            <label><input type="radio" name="god"> Anubis</label>
            <label><input type="radio" name="god"> Isis</label>
        </fieldset>
        <fieldset>
            <legend>Poziom wiedzy</legend>
            <label>Poczatkujacy <input type="range" min="0" max="100" value="50"> Ekspert</label>
            <label>Postep: <progress value="65" max="100">65%</progress></label>
        </fieldset>
    </form>
</body>
</html>

Pamiętaj: CSS Functions to jak matematyka egipskich skrybów - precyzyjne obliczenia wbudowane bezpośrednio w arkusze stylów, pozwalające na tworzenie dynamicznych, responsywnych designów bez JavaScript!

Hasła z dokumentacji w tej lekcji

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Co umożliwia funkcja calc() w CSS?

  2. 2. Co zwraca funkcja min(800px, 100%)?

To 2 z 3 pytań do tej lekcji. Pozostałe rozwiążesz w grze.

Zadania praktyczne w grze

  • Układanie w poziomie

    Ułóż argumenty funkcji clamp() w jednej linii w poprawnej kolejności:

Przydatne artykuły