Figure: Custom property overview
Q: Why all this? A: Authoring styles from UI point of view is guard railed and robust. Themes can be switched and all of the components adapt to the new theme without any changes required from the usage point of view. This greatly simplifies adding themes and also makes the usage of style related variables consistent.
--button-variant-1-hover: var(--foobar);
--hover: var(--foobar);
inside .btn.primary
--hover-primary: var(--foobar);
(not restricted to buttons only).At the moment I think option 3 is the way to go.
Theming is based on prefers-color-scheme
. If more complex theming setup is required, then Javascript based theming is needed on top of prefers-color-scheme
query. One solid way is to use custom data-attribute on the root element and then hook styles to that. E.g.:
:root:not([data-theme='light']),
[data-theme='dark'] {...}
/*
* Cito Custom Properties
* Version 1.6.0
* Author: ilkka.kuivanen@me.com
*/
/*
* Ideas for property groups, but not included by default:
- border-radius
*/
/** Private API: use only within this file. */
:root {
--cito-custom1-100: oklch(96% 0.0192 269.78);
--cito-custom1-200: oklch(89% 0.0673 269.78);
--cito-custom1-300: oklch(77% 0.1118 269.78);
--cito-custom1-400: oklch(67% 0.1218 269.78);
--cito-custom1-500: oklch(59% 0.1318 269.78);
--cito-custom1-600: oklch(48% 0.1418 269.78);
--cito-custom1-700: oklch(37% 0.1518 269.78);
--cito-custom1-800: oklch(26% 0.1618 269.78);
--cito-custom1-900: oklch(19% 0.1718 269.78);
--cito-blue-100: oklch(96% 0.0192 243);
--cito-blue-200: oklch(89% 0.0673 243);
--cito-blue-300: oklch(77% 0.1118 243);
--cito-blue-400: oklch(67% 0.1218 243);
--cito-blue-500: oklch(59% 0.1318 243);
--cito-blue-600: oklch(48% 0.1418 243);
--cito-blue-700: oklch(37% 0.1518 243);
--cito-blue-800: oklch(26% 0.1618 243);
--cito-blue-900: oklch(19% 0.1718 243);
--cito-red-100: oklch(96% 0.0192 6.18);
--cito-red-200: oklch(89% 0.0673 6.18);
--cito-red-300: oklch(77% 0.1673 6.22);
--cito-red-400: oklch(67% 0.1673 6.22);
--cito-red-500: oklch(59% 0.1673 6.22);
--cito-red-600: oklch(48% 0.1673 6.22);
--cito-red-700: oklch(37% 0.1673 6.22);
--cito-red-800: oklch(26% 0.1618 6.18);
--cito-red-900: oklch(19% 0.1718 6.18);
--cito-yellow-100: oklch(96% 0.0192 73.67);
--cito-yellow-200: oklch(89% 0.0673 73.67);
--cito-yellow-300: oklch(77% 0.1437 73.67);
--cito-yellow-400: oklch(67% 0.1398 74.11);
--cito-yellow-500: oklch(59% 0.1273 64.8);
--cito-yellow-600: oklch(48% 0.1267 56.11);
--cito-yellow-700: oklch(37% 0.1071 56.11);
--cito-yellow-800: oklch(26% 0.0783 73.67);
--cito-yellow-900: oklch(19% 0.068 73.67);
--cito-green-100: oklch(96% 0.0192 141.41);
--cito-green-200: oklch(89% 0.0673 141.41);
--cito-green-300: oklch(77% 0.1118 141.41);
--cito-green-400: oklch(67% 0.1218 141.41);
--cito-green-500: oklch(59% 0.1318 141.41);
--cito-green-600: oklch(48% 0.1418 141.41);
--cito-green-700: oklch(37% 0.1518 141.41);
--cito-green-800: oklch(26% 0.1618 141.41);
--cito-green-900: oklch(19% 0.1718 141.41);
--cito-gray-100: oklch(96% 0.0192 255.78);
--cito-gray-200: oklch(89% 0.0192 255.78);
--cito-gray-300: oklch(77% 0.0192 255.78);
--cito-gray-400: oklch(67% 0.0192 255.78);
--cito-gray-500: oklch(59% 0.0192 255.78);
--cito-gray-600: oklch(48% 0.0192 255.78);
--cito-gray-700: oklch(37% 0.0192 255.78);
--cito-gray-800: oklch(26% 0.0192 255.78);
--cito-gray-900: oklch(19% 0.0192 255.78);
}
/** Public API for theme "Light" */
@media (prefers-color-scheme: light) {
:root {
--cito-white: oklch(98% 0 0);
--cito-black: oklch(10% 0 0);
--cito-upfront-color: var(--cito-gray-900);
--cito-background-color: var(--cito-white);
--cito-primary-100: var(--cito-custom1-100);
--cito-primary-200: var(--cito-custom1-200);
--cito-primary-300: var(--cito-custom1-300);
--cito-primary-400: var(--cito-custom1-400);
--cito-primary-500: var(--cito-custom1-500);
--cito-primary-600: var(--cito-custom1-600);
--cito-primary-700: var(--cito-custom1-700);
--cito-primary-800: var(--cito-custom1-800);
--cito-primary-900: var(--cito-custom1-900);
--cito-secondary-100: var(--cito-gray-100);
--cito-secondary-200: var(--cito-gray-200);
--cito-secondary-300: var(--cito-gray-300);
--cito-secondary-400: var(--cito-gray-400);
--cito-secondary-500: var(--cito-gray-500);
--cito-secondary-600: var(--cito-gray-600);
--cito-secondary-700: var(--cito-gray-700);
--cito-secondary-800: var(--cito-gray-800);
--cito-secondary-900: var(--cito-gray-900);
--cito-tertiary-100: var(--cito-cyan-100);
--cito-tertiary-200: var(--cito-cyan-200);
--cito-tertiary-300: var(--cito-cyan-300);
--cito-tertiary-400: var(--cito-cyan-400);
--cito-tertiary-500: var(--cito-cyan-500);
--cito-tertiary-600: var(--cito-cyan-600);
--cito-tertiary-700: var(--cito-cyan-700);
--cito-tertiary-800: var(--cito-cyan-800);
--cito-tertiary-900: var(--cito-cyan-900);
--cito-success-100: var(--cito-green-100);
--cito-success-200: var(--cito-green-200);
--cito-success-300: var(--cito-green-300);
--cito-success-400: var(--cito-green-400);
--cito-success-500: var(--cito-green-500);
--cito-success-600: var(--cito-green-600);
--cito-success-700: var(--cito-green-700);
--cito-success-800: var(--cito-green-800);
--cito-success-900: var(--cito-green-900);
--cito-warning-100: var(--cito-yellow-100);
--cito-warning-200: var(--cito-yellow-200);
--cito-warning-300: var(--cito-yellow-300);
--cito-warning-400: var(--cito-yellow-400);
--cito-warning-500: var(--cito-yellow-500);
--cito-warning-600: var(--cito-yellow-600);
--cito-warning-700: var(--cito-yellow-700);
--cito-warning-800: var(--cito-yellow-800);
--cito-warning-900: var(--cito-yellow-900);
--cito-danger-100: var(--cito-red-100);
--cito-danger-200: var(--cito-red-200);
--cito-danger-300: var(--cito-red-300);
--cito-danger-400: var(--cito-red-400);
--cito-danger-500: var(--cito-red-500);
--cito-danger-600: var(--cito-red-600);
--cito-danger-700: var(--cito-red-700);
--cito-danger-800: var(--cito-red-800);
--cito-danger-900: var(--cito-red-900);
--cito-info-100: var(--cito-blue-100);
--cito-info-200: var(--cito-blue-200);
--cito-info-300: var(--cito-blue-300);
--cito-info-400: var(--cito-blue-400);
--cito-info-500: var(--cito-blue-500);
--cito-info-600: var(--cito-blue-600);
--cito-info-700: var(--cito-blue-700);
--cito-info-800: var(--cito-blue-800);
--cito-info-900: var(--cito-blue-900);
--cito-link-100: var(--cito-blue-100);
--cito-link-200: var(--cito-blue-200);
--cito-link-300: var(--cito-blue-300);
--cito-link-400: var(--cito-blue-400);
--cito-link-500: var(--cito-blue-500);
--cito-link-600: var(--cito-blue-600);
--cito-link-700: var(--cito-blue-700);
--cito-link-800: var(--cito-blue-800);
--cito-link-900: var(--cito-blue-900);
--cito-text-100: var(--cito-secondary-100);
--cito-text-200: var(--cito-secondary-200);
--cito-text-300: var(--cito-secondary-300);
--cito-text-400: var(--cito-secondary-400);
--cito-text-500: var(--cito-secondary-500);
--cito-text-600: var(--cito-secondary-600);
--cito-text-700: var(--cito-secondary-700);
--cito-text-800: var(--cito-secondary-800);
--cito-text-900: var(--cito-secondary-900);
--cito-ui-000: var(--cito-secondary-100);
--cito-ui-100: var(--cito-secondary-100);
--cito-ui-200: var(--cito-secondary-200);
--cito-ui-300: var(--cito-secondary-300);
--cito-ui-400: var(--cito-secondary-400);
--cito-ui-500: var(--cito-secondary-500);
--cito-ui-600: var(--cito-secondary-600);
--cito-ui-700: var(--cito-secondary-700);
--cito-ui-800: var(--cito-secondary-800);
--cito-ui-900: var(--cito-secondary-900);
/** Component specific exceptions */
--cito-alert-danger-bgColor: var(--cito-danger-700);
--cito-alert-danger-borderColor: var(--cito-danger-600);
--cito-alert-danger-color: var(--cito-danger-100);
}
}
/** Public API for theme "Dark" */
@media (prefers-color-scheme: dark) {
:root {
--cito-white: oklch(98% 0 0);
--cito-black: oklch(10% 0 0);
--cito-upfront-color: var(--cito-gray-900);
--cito-background-color: var(--cito-white);
--cito-primary-100: var(--cito-blue-900);
--cito-primary-200: var(--cito-blue-800);
--cito-primary-300: var(--cito-blue-700);
--cito-primary-400: var(--cito-blue-600);
--cito-primary-500: var(--cito-blue-500);
--cito-primary-600: var(--cito-blue-400);
--cito-primary-700: var(--cito-blue-300);
--cito-primary-800: var(--cito-blue-200);
--cito-primary-900: var(--cito-blue-100);
--cito-secondary-100: var(--cito-gray-900);
--cito-secondary-200: var(--cito-gray-800);
--cito-secondary-300: var(--cito-gray-700);
--cito-secondary-400: var(--cito-gray-600);
--cito-secondary-500: var(--cito-gray-500);
--cito-secondary-600: var(--cito-gray-400);
--cito-secondary-700: var(--cito-gray-300);
--cito-secondary-800: var(--cito-gray-200);
--cito-secondary-900: var(--cito-gray-100);
--cito-tertiary-100: var(--cito-cyan-900);
--cito-tertiary-200: var(--cito-cyan-800);
--cito-tertiary-300: var(--cito-cyan-700);
--cito-tertiary-400: var(--cito-cyan-600);
--cito-tertiary-500: var(--cito-cyan-500);
--cito-tertiary-600: var(--cito-cyan-400);
--cito-tertiary-700: var(--cito-cyan-300);
--cito-tertiary-800: var(--cito-cyan-200);
--cito-tertiary-900: var(--cito-cyan-100);
--cito-success-100: var(--cito-green-900);
--cito-success-200: var(--cito-green-800);
--cito-success-300: var(--cito-green-700);
--cito-success-400: var(--cito-green-600);
--cito-success-500: var(--cito-green-500);
--cito-success-600: var(--cito-green-400);
--cito-success-700: var(--cito-green-300);
--cito-success-800: var(--cito-green-200);
--cito-success-900: var(--cito-green-100);
--cito-warning-100: var(--cito-yellow-900);
--cito-warning-200: var(--cito-yellow-800);
--cito-warning-300: var(--cito-yellow-700);
--cito-warning-400: var(--cito-yellow-600);
--cito-warning-500: var(--cito-yellow-500);
--cito-warning-600: var(--cito-yellow-400);
--cito-warning-700: var(--cito-yellow-300);
--cito-warning-800: var(--cito-yellow-200);
--cito-warning-900: var(--cito-yellow-100);
--cito-danger-100: var(--cito-red-900);
--cito-danger-200: var(--cito-red-800);
--cito-danger-300: var(--cito-red-700);
--cito-danger-400: var(--cito-red-600);
--cito-danger-500: var(--cito-red-500);
--cito-danger-600: var(--cito-red-400);
--cito-danger-700: var(--cito-red-300);
--cito-danger-800: var(--cito-red-200);
--cito-danger-900: var(--cito-red-100);
--cito-info-100: var(--cito-blue-900);
--cito-info-200: var(--cito-blue-800);
--cito-info-300: var(--cito-blue-700);
--cito-info-400: var(--cito-blue-600);
--cito-info-500: var(--cito-blue-500);
--cito-info-600: var(--cito-blue-400);
--cito-info-700: var(--cito-blue-300);
--cito-info-800: var(--cito-blue-200);
--cito-info-900: var(--cito-blue-100);
--cito-link-100: var(--cito-blue-900);
--cito-link-200: var(--cito-blue-800);
--cito-link-300: var(--cito-blue-700);
--cito-link-400: var(--cito-blue-600);
--cito-link-500: var(--cito-blue-500);
--cito-link-600: var(--cito-blue-400);
--cito-link-700: var(--cito-blue-300);
--cito-link-800: var(--cito-blue-200);
--cito-link-900: var(--cito-blue-100);
--cito-text-100: var(--cito-secondary-100);
--cito-text-200: var(--cito-secondary-200);
--cito-text-300: var(--cito-secondary-300);
--cito-text-400: var(--cito-secondary-400);
--cito-text-500: var(--cito-secondary-500);
--cito-text-600: var(--cito-secondary-600);
--cito-text-700: var(--cito-secondary-700);
--cito-text-800: var(--cito-secondary-800);
--cito-text-900: var(--cito-secondary-900);
--cito-ui-000: var(--cito-secondary-100);
--cito-ui-100: var(--cito-secondary-100);
--cito-ui-200: var(--cito-secondary-200);
--cito-ui-300: var(--cito-secondary-300);
--cito-ui-400: var(--cito-secondary-400);
--cito-ui-500: var(--cito-secondary-500);
--cito-ui-600: var(--cito-secondary-600);
--cito-ui-700: var(--cito-secondary-700);
--cito-ui-800: var(--cito-secondary-800);
--cito-ui-900: var(--cito-secondary-900);
/** Component specific exceptions */
--cito-alert-danger-bgColor: var(--cito-danger-100);
--cito-alert-danger-borderColor: var(--cito-danger-200);
--cito-alert-danger-color: var(--cito-danger-900);
}
}
/** Public API for Typography */
:root {
--cito-font-sans-serif: "Gill Sans", "Helvetica Neue", system-ui,
-apple-system, sans-serif;
--cito-font-serif: Georgia, "Times New Roman", Times, serif;
--cito-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas,
"Liberation Mono", "Courier New", monospace;
/** Major Second scale */
--cito-font-size-000: 0.625rem; /* 10.00 */
--cito-font-size-100: 0.702rem; /* 11.24 */
--cito-font-size-200: 0.79rem; /* 12.64 */
--cito-font-size-300: 0.889rem; /* 14.22 */
--cito-font-size-400: 1rem; /* 16.00 */
--cito-font-size-500: 1.125rem; /* 18.00 */
--cito-font-size-600: 1.266rem; /* 20.25 */
--cito-font-size-700: 1.424rem; /* 22.78 */
--cito-font-size-800: 1.602rem; /* 25.63 */
--cito-font-size-900: 1.802rem; /* 28.83 */
--cito-font-size-1000: 2.027rem; /* 32.44 */
--cito-font-size-1100: 2.281rem; /* 36.49 */
--cito-font-size-1200: 2.566rem; /* 41.05 */
--cito-font-size-1300: 2.887rem; /* 46.18 */
--cito-font-size-1400: 3.247rem; /* 51.96 */
--cito-font-size-1500: 3.653rem; /* 58.45 */
}
/** Public API for Box shadow */
:root {
--cito-box-shadow-100: oklch(0% 0 0 / 5%) 0 0.0625rem 0.125rem 0;
--cito-box-shadow-200: oklch(0% 0 0 / 10%) 0 0.0625rem 0.1875rem 0,
oklch(0% 0 0 / 6%) 0 0.0625rem 0.125rem 0;
--cito-box-shadow-300: oklch(0% 0 0 / 10%) 0 0.25rem 0.375rem
calc(-1 * 0.0625rem),
oklch(0% 0 0 / 6%) 0 0.125rem 0.25rem calc(-1 * 0.0625rem);
--cito-box-shadow-400: oklch(0% 0 0 / 10%) 0 0.625rem 0.9375rem
calc(-1 * 0.1875rem),
oklch(0% 0 0 / 5%) 0 0.25rem 0.375rem calc(-1 * 0.125rem);
--cito-box-shadow-500: oklch(0% 0 0 / 10%) 0 1.25rem 1.5625rem
calc(-1 * 0.3125rem),
rgba(0, 0, 0, 0.04) 0 0.625rem 0.625rem calc(-1 * 0.3125rem);
--cito-box-shadow-600: oklch(0% 0 0 / 25%) 0 1.5625rem 3.125rem
calc(-1 * 0.75rem);
--cito-box-shadow-inset-100: oklch(0% 0 0 / 6%) 0 0.125rem 0.25rem 0 inset;
--cito-box-shadow-border-100: oklch(0% 0 0 / 5%) 0 0 0 0.0625rem;
--cito-box-shadow-border-200: oklch(0% 0 0 / 2%) 0 0.0625rem 0.1875rem 0,
rgba(27, 31, 35, 0.15) 0 0 0 0.0625rem;
}
/** Public API for box shadow inset */
:root {
--cito-box-shadow-inset-100: oklch(0% 0 0 / 6%) 0 0.125rem 0.25rem 0 inset;
}
/** Public API for box shadow border */
:root {
--cito-box-shadow-border-100: oklch(0% 0 0 / 5%) 0 0 0 0.0625rem;
--cito-box-shadow-border-200: oklch(0% 0 0 / 2%) 0 0.0625rem 0.1875rem 0,
rgba(27, 31, 35, 0.15) 0 0 0 0.0625rem;
}
/** Public API for transitions */
:root {
--cito-transition-fast: 0.1s;
--cito-transition-default: 0.25s;
}