CSS Custom Properties (proměnné)

CSS proměnné (formálně custom properties) jsou jednou z nejdůležitějších moderních CSS funkcí. Umožňují definovat hodnoty na jednom místě a použít je kdekoliv — a změna na jednom místě se propaguje celým dokumentem.

/* Definice: vždy začínají dvěma pomlčkami -- */
:root {
  --color-primary: #7C3AED;
  --color-text: #1A1814;
  --spacing-md: 16px;
  --radius: 8px;
  --transition: 0.25s ease;
}

/* Použití: funkce var() */
.button {
  background: var(--color-primary);
  padding: var(--spacing-md);
  border-radius: var(--radius);
  transition: all var(--transition);
}

/* Záložní hodnota (fallback) */
color: var(--color-text, #333);

/* Přepis v konkrétním kontextu */
.card-dark {
  --color-primary: #A78BFA; /* lokální přepis */
}

/* JavaScript může číst a zapisovat */
const root = document.documentElement;
root.style.setProperty('--color-primary', '#C8622A');
const val = getComputedStyle(root).getPropertyValue('--color-primary');

🎮 Interaktivní demo — měňte CSS proměnné v reálném čase

Interaktivní karta

CSS proměnné se aplikují okamžitě na celý design systém.

💡
Design systém v :root — definujte barvy, spacing, typografii a stíny jako proměnné na začátku projektu. Pak stačí změnit jednu hodnotu a celý web se přizpůsobí. Tohle je základ každého profesionálního projektu.

🧠 Kvíz: Jak přepíšete CSS proměnnou --barva pouze pro elementy uvnitř .tema-tmave?

Kapitola 1 / 8 Další: Transition →

Transition — plynulé přechody

transition animuje změnu CSS vlastnosti z jednoho stavu do druhého — typicky při hoveru, focusu nebo přidání třídy přes JS.

/* Syntaxe: vlastnost | trvání | easing | zpoždění */
transition: background 0.3s ease;
transition: all 0.25s ease-in-out;
transition: transform 0.3s ease, opacity 0.2s ease 0.1s;

/* Vždy definujte na výchozím stavu, NE na :hover! */
.button {
  background: blue;
  transition: background 0.3s ease, transform 0.2s ease;
}
.button:hover {
  background: darkblue;
  transform: translateY(-2px); /* jemný lift */
}

Najeďte myší na ukázky — všechny efekty jsou čistě CSS transition:

opacity
scale (bounce)
color + radius
translateX
Výkon animací: Animujte pouze transform a opacity — tyto vlastnosti jsou zpracovávány GPU a nezpůsobují reflow. Animace width, height, margin, top/left jsou výkonnostně drahé.
Živý editor — Transition
Kapitola 2 / 8 Další: Easing →

Easing — křivky průběhu animace

Easing určuje, jak rychle/pomalu animace probíhá v různých fázích. Správný easing dělá animaci přirozenou nebo dramatickou.

HodnotaPrůběhPoužití
linearKonstantní rychlostRotace, progress bary
easePomalý start, rychlý střed, pomalý konecVýchozí — většina animací
ease-inPomalý start, rychlý konecElementy "odlétající" z obrazovky
ease-outRychlý start, pomalý konecElementy "přilétající" na obrazovku
ease-in-outPomalý start i konecPřechody stránek, modaly
cubic-bezier()Vlastní křivkaBounce, spring efekty
/* Bounce efekt pomocí cubic-bezier */
transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
/* Hodnoty >1 způsobují "přestřelení" (overshoot) */

/* Spring efekt */
transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);

/* Nástroj: cubic-bezier.com pro vizuální tvorbu */
Kapitola 3 / 8 Další: @keyframes →

@keyframes — vlastní animace

Zatímco transition animuje přechod mezi dvěma stavy, @keyframes definuje sekvenci libovolného počtu kroků:

/* Definice animace */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Procenty pro přesnou kontrolu */
@keyframes pulse {
  0%   { transform: scale(1); box-shadow: 0 0 0 0 rgba(124,58,237,0.4); }
  70%  { transform: scale(1.05); box-shadow: 0 0 0 12px rgba(124,58,237,0); }
  100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(124,58,237,0); }
}

@keyframes shimmer {
  from { background-position: -200% center; }
  to   { background-position: 200% center; }
}

Živé ukázky @keyframes — vše čistým CSS:

pulse
spin
bounce
shake

Vlastnost animation

Vlastnost animation propojuje @keyframes s elementem a dává animaci časování, opakování a chování:

/* Shorthand: name duration easing delay iteration direction fill-mode */
animation: fadeIn 0.5s ease-out 0s 1 normal forwards;

/* Jednotlivé vlastnosti */
.element {
  animation-name: fadeIn;
  animation-duration: 0.5s;
  animation-timing-function: ease-out;
  animation-delay: 0.2s;       /* zpoždění startu */
  animation-iteration-count: infinite | 3;
  animation-direction: normal | reverse | alternate | alternate-reverse;
  animation-fill-mode: forwards; /* zachová konečný stav */
  animation-play-state: running | paused; /* JS kontrola */
}

/* Více animací najednou */
animation: fadeIn 0.5s ease, pulse 2s ease infinite 0.5s;

/* Staggered animace — různé delay pro sourozence */
.item:nth-child(1) { animation-delay: 0.0s; }
.item:nth-child(2) { animation-delay: 0.1s; }
.item:nth-child(3) { animation-delay: 0.2s; }
Živý editor — Staggered animace

🧠 Kvíz: Co způsobí animation-fill-mode: forwards?

Pseudotřídy a pseudoelementy

CSS pseudotřídy a pseudoelementy umožňují stylovat prvky na základě jejich stavu nebo přidávat virtuální elementy bez HTML.

Stavové pseudotřídy

a:link    { color: blue; }     /* nenavštívený odkaz */
a:visited { color: purple; }   /* navštívený */
a:hover   { color: red; }      /* najetí myší */
a:active  { color: orange; }   /* kliknutí */
input:focus { outline: 2px solid blue; }  /* aktivní input */
input:focus-visible { /* pouze klávesnice, ne myš */ }
button:disabled { opacity: 0.5; cursor: not-allowed; }
input:valid   { border-color: green; }
input:invalid { border-color: red; }

Strukturální pseudotřídy

li:first-child  { font-weight: bold; }
li:last-child   { border-bottom: none; }
li:nth-child(2) { background: #f0f0f0; }
li:nth-child(odd)  { background: #fafafa; } /* liché */
li:nth-child(even) { background: #f0f0f0; } /* sudé */
li:nth-child(3n)   { color: red; }          /* každý třetí */
p:not(.special)    { color: gray; }         /* negace */

Pseudoelementy ::before a ::after

/* Přidají virtuální element před/za obsah */
.badge::before {
  content: "🔥 ";  /* povinný atribut */
}

/* Dekorativní linka pod nadpisem */
h2::after {
  content: "";
  display: block;
  width: 40px;
  height: 3px;
  background: var(--accent);
  margin-top: 8px;
}

/* ::placeholder, ::selection, ::first-line */
input::placeholder { color: #aaa; font-style: italic; }
::selection { background: #7C3AED; color: white; }
Živý editor — pseudoelementy

🧠 Kvíz: Jaký je rozdíl mezi :nth-child(2) a :nth-of-type(2)?

Kapitola 6 / 8 Další: Cvičení →

Praktické cvičení

Vytvořte animovanou landing page sekci s: CSS proměnnými v :root, staggered fade-in animací pro tři feature karty, hover efektem na kartách (lift + shadow), a dekorativní linkou pod nadpisem pomocí ::after.

📋
Checklist: :root s proměnnými pro barvy a spacing, @keyframes fadeInUp s opacity + translateY, animation-delay 0s/0.15s/0.3s pro tři karty, transition na hover, h2::after s dekorativní linkou.
Vaše řešení
🏅

Odznak: Animační Kouzelník

Zvládáte CSS proměnné, transition, @keyframes a pseudoelementy.

Kapitola 7 / 8 Další: Taháček →

Taháček — rychlá reference

CSS Proměnné

:root { --color: #7C3AED; --spacing: 16px; }
.el  { color: var(--color); padding: var(--spacing); }
.dark { --color: #A78BFA; } /* lokální přepis */

Transition

/* VŽDY na výchozím stavu, ne na :hover */
.el { transition: transform 0.3s ease, opacity 0.2s ease; }
.el:hover { transform: translateY(-4px); }
/* Animujte jen: transform, opacity (GPU) */

@keyframes + animation

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}
.el {
  animation: fadeIn 0.4s ease-out forwards;
  /* forwards = zachová konečný stav */
}

Pseudotřídy — přehled

:hover :focus :active :disabled :checked
:first-child :last-child :nth-child(n) :nth-child(odd/even)
:not(.class) :is(h1,h2,h3) :where()
::before ::after ::placeholder ::selection
Lekce 4 dokončena! Lekce 5: Responzivita →