DevToolBoxZA DARMO
Blog

Zaawansowane Właściwości Niestandardowe CSS: Motywy, Warianty Komponentów

10 minby DevToolBox

Właściwości niestandardowe CSS wykroczyły daleko poza proste zamienianie kolorów. Ten przewodnik bada zaawansowane wzorce czyniące je jedną z najpotężniejszych funkcji nowoczesnego CSS.

Podstawy właściwości niestandardowych

Właściwości niestandardowe są definiowane z prefiksem -- i dostępne przez funkcję var().

/* CSS Custom Properties — Fundamentals */

/* Define properties on :root for global scope */
:root {
  --color-primary: #0066cc;
  --color-primary-dark: #0052a3;
  --spacing-unit: 8px;
  --font-size-base: 1rem;
  --border-radius: 4px;
}

/* Use with var() */
.button {
  background-color: var(--color-primary);
  padding: calc(var(--spacing-unit) * 1.5) calc(var(--spacing-unit) * 3);
  border-radius: var(--border-radius);
  font-size: var(--font-size-base);
}

/* Override at component scope (not global) */
.button.danger {
  --color-primary: #cc0000;  /* Only affects this button */
  --color-primary-dark: #990000;
}

/* Fallback value (second argument to var) */
.card {
  background: var(--card-bg, white);
  color: var(--card-text, var(--color-text, #333));  /* nested fallback */
  padding: var(--card-padding, var(--spacing-unit, 8px));
}

Systemy themingowe z tokenami projektowymi

Najpotężniejsze zastosowanie właściwości niestandardowych to budowanie kompletnego systemu tokenów projektowych.

/* Multi-Theme System with CSS Custom Properties */

/* Light theme (default) */
:root {
  --color-bg: #ffffff;
  --color-surface: #f8f9fa;
  --color-border: #e2e8f0;
  --color-text-primary: #1a202c;
  --color-text-secondary: #718096;
  --color-accent: #3182ce;
  --color-accent-hover: #2c5282;
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
  --transition-fast: 150ms ease;
}

/* Dark theme — override only what changes */
[data-theme="dark"] {
  --color-bg: #1a202c;
  --color-surface: #2d3748;
  --color-border: #4a5568;
  --color-text-primary: #f7fafc;
  --color-text-secondary: #a0aec0;
  --color-accent: #63b3ed;
  --color-accent-hover: #90cdf4;
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
}

/* High-contrast theme */
[data-theme="high-contrast"] {
  --color-bg: #000000;
  --color-text-primary: #ffffff;
  --color-accent: #ffff00;
  --color-border: #ffffff;
}

/* System preference auto-detection */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-bg: #1a202c;
    --color-text-primary: #f7fafc;
    /* ... more overrides */
  }
}

/* Components use semantic tokens — never raw colors */
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  color: var(--color-text-primary);
  box-shadow: var(--shadow-md);
  transition: box-shadow var(--transition-fast);
}

Warianty komponentów z właściwościami niestandardowymi

Właściwości niestandardowe umożliwiają bardziej elastyczne systemy wariantów komponentów.

/* Component Variant System */

/* Button component with custom property API */
.btn {
  /* Default values (the component's "API") */
  --btn-bg: var(--color-accent);
  --btn-bg-hover: var(--color-accent-hover);
  --btn-color: white;
  --btn-border: transparent;
  --btn-shadow: var(--shadow-sm);
  --btn-size: 1rem;
  --btn-padding-y: 0.5em;
  --btn-padding-x: 1em;
  --btn-radius: var(--border-radius);

  background: var(--btn-bg);
  color: var(--btn-color);
  border: 1px solid var(--btn-border);
  box-shadow: var(--btn-shadow);
  font-size: var(--btn-size);
  padding: var(--btn-padding-y) var(--btn-padding-x);
  border-radius: var(--btn-radius);
  transition: background var(--transition-fast);
}

.btn:hover {
  background: var(--btn-bg-hover);
}

/* Variants — only override what changes */
.btn-danger {
  --btn-bg: #e53e3e;
  --btn-bg-hover: #c53030;
}

.btn-outline {
  --btn-bg: transparent;
  --btn-bg-hover: var(--color-accent);
  --btn-color: var(--color-accent);
  --btn-border: var(--color-accent);
}

.btn-sm {
  --btn-size: 0.875rem;
  --btn-padding-y: 0.375em;
  --btn-padding-x: 0.75em;
}

.btn-lg {
  --btn-size: 1.125rem;
  --btn-padding-y: 0.75em;
  --btn-padding-x: 1.5em;
}

/* Caller overrides — no need for a new variant class */
.special-hero .btn {
  --btn-bg: gold;
  --btn-color: black;
  --btn-radius: 50px;
}

Interoperacyjność JavaScript

Właściwości niestandardowe płynnie łączą CSS i JavaScript.

// JavaScript <-> CSS Custom Properties

// 1. Read a custom property value
const root = document.documentElement;
const primaryColor = getComputedStyle(root)
  .getPropertyValue('--color-primary')
  .trim();
console.log(primaryColor); // '#0066cc'

// 2. Set a custom property from JavaScript
root.style.setProperty('--color-primary', '#ff6600');

// 3. Remove a custom property
root.style.removeProperty('--color-primary');

// 4. Theme switcher
function setTheme(theme) {
  document.documentElement.dataset.theme = theme;
  localStorage.setItem('theme', theme);
}

// 5. Animate with custom properties (requires @property)
// CSS:
// @property --progress {
//   syntax: '<number>';
//   initial-value: 0;
//   inherits: false;
// }
// .progress-bar {
//   width: calc(var(--progress) * 1%);
//   transition: --progress 1s ease;
// }

// JavaScript:
function animateProgress(el, from, to) {
  el.style.setProperty('--progress', from);
  requestAnimationFrame(() => {
    el.style.setProperty('--progress', to);
  });
}

// 6. Reactive properties with ResizeObserver
const observer = new ResizeObserver(entries => {
  for (const entry of entries) {
    const { width, height } = entry.contentRect;
    entry.target.style.setProperty('--el-width', `${width}px`);
    entry.target.style.setProperty('--el-height', `${height}px`);
  }
});
observer.observe(document.querySelector('.responsive-component'));

Często zadawane pytania

Czy właściwości CSS niestandardowe to to samo co zmienne SASS?

Nie, są fundamentalnie różne. Zmienne SASS są kompilowane w czasie budowania.

Czy właściwości CSS niestandardowe mogą być animowane?

Tak, z @property (Houdini).

Co to jest wartość zastępcza w var()?

Drugi argument var() to wartość zastępcza gdy właściwość nie jest zdefiniowana.

Czy działają we wszystkich nowoczesnych przeglądarkach?

Tak, pełna obsługa od 2017 roku.

Powiązane narzędzia

𝕏 Twitterin LinkedIn
Czy to było pomocne?

Bądź na bieżąco

Otrzymuj cotygodniowe porady i nowe narzędzia.

Bez spamu. Zrezygnuj kiedy chcesz.

Try These Related Tools

🌈CSS Gradient Generator🎨Color Converter

Related Articles

Zmienne CSS (Właściwości niestandardowe): Kompletny przewodnik

Opanuj właściwości niestandardowe CSS. Składnia, zakres, wartości domyślne i motyw ciemny.

CSS Grid Mastery: Kompletny Przewodnik z Przykładami 2026

Opanuj CSS Grid Layout 2026: grid-template areas, auto-placement, subgrid i responsywne układy.

Wzorce Komponentów Tailwind CSS: Budowanie Wielokrotnego Użytku UI w 2026

Zaawansowane wzorce komponentów Tailwind CSS 2026: tokeny projektowe, komponenty złożone i system projektowania bez CSS-in-JS.