Themes
Skeleton leans into Tailwind's best practices when implementing themes. This includes support for color opacity and dark mode. Themes also enable Skeleton's design tokens system.
CSS Custom Properties
Skeleton themes are generated using a number of CSS Custom Properties, also known as as CSS variables.
CSS Property | Description |
---|---|
--theme-font-family-base | Set the font family for your default base text. |
--theme-font-family-heading | Set the font family for your heading text. |
--theme-font-color-base | Set the default text color for light mode. |
--theme-font-color-dark | Set the default text color for dark mode. |
--theme-rounded-base | Set the border radius for small elements, such as buttons, inputs, etc. |
--theme-rounded-container | Set the border radius for large elements, such as cards, textfields, etc. |
--theme-border-base | Set the default border size for elements, including inputs. |
--on-[color] | Set an accessible overlapping text or fill color per each theme color. |
--color-[color]-[shade] | Defines each color and shade value for your theme. |
Overwriting Properties
Similar to variables in other languages, CSS properties can be overwritten. By adding the following snippet in /src/app.postcss
, you can overwrite the base and container border radius styles for your active theme.
/* NOTE: set your target theme name (ex: skeleton, wintry, modern, etc) */
:root [data-theme='skeleton'] {
--theme-rounded-base: 20px;
--theme-rounded-container: 4px;
}
Likewise, you can override base and heading font family settings as shown below.
/* NOTE: set your target theme name (ex: skeleton, wintry, modern, etc) */
:root [data-theme='skeleton'] {
--theme-font-family-base: 'MyCustomFont', sans-serif;
--theme-font-family-heading: 'MyCustomFont', sans-serif;
}
For deeper customization, consider cloning Skeleton's preset themes, modifying each as desired, then implementing as a custom theme. Follow the theme generator implementation guide for more information.
CSS-in-JS Format
New in v2Skeleton now defines theme settings via the CSS-in-JS format. This allows themes to be easily registered within the Skeleton Tailwind plugin, rather than relying on additional stylesheet imports.
Tailwind Plugin Settings
New in v2Themes are configured via Skeleton's Tailwind plugin in your tailwind.config.[ts|js|cjs]
, found in your
project root.
Register Themes
Skeleton provides a number of preset themes out of the box. You'll need to register at least one theme to load them and make them available to use.
plugins: [
skeleton({
themes: {
// Register each theme within this array:
preset: [ "skeleton", "modern", "crimson" ]
}
})
]
Open /src/app.html
and define the active theme to display using the data-theme
attribute.
You can modify this attribute to dynamically switch between any registered theme.
<body data-theme="skeleton">
Enhancements
Preset themes may sometimes include additional optional features, such as: heading font weights, background mesh gradients, and more.
To enable these settings, include enhancements
as shown below.
plugins: [
skeleton({
themes: {
preset: [
// Enable 'enhancements' per each registered theme:
{ name: "skeleton", enhancements: true }
]
}
})
]
Custom Themes
View the theme generator for more information about implementing custom themes. Note that it is possible to mix and match preset and custom themes.
Dark Mode
By default Tailwind opts for light mode. If you wish to default to dark mode, append the following class to the html
element within /src/app.html
. View
Tailwind's documentation for more information.
<html class="dark">
Note that Skeleton also provides a Lightswitch utility if you wish to toggle between light and dark modes.
Backgrounds
The background color of your application is automatically set using one of Skeleton's design token styles. By default, this utilizes --color-surface-50
for light mode and --color-surface-900
for dark mode. Use your global stylesheet app.postcss
to modify this.
/* Default setting: */
body { @apply bg-surface-50-900-token; }
/* --- */
/* Example: primary color via a design token: */
body { @apply bg-primary-50-900-token; }
/* Example: secondary color via Tailwind: */
body { @apply bg-secondary-50 dark:bg-secondary-900; }
/* Example: using vanilla CSS: */
body { background: red; }
.dark body { background: blue; }
Images and Gradients
You may optionally provide a background image, including the use of a CSS mesh gradient. Replace the static color values with theme color properties to create a fully adaptive gradient background.
html, body { @apply h-full; }
body {
background-image:
radial-gradient(at 0% 0%, rgba(var(--color-secondary-500) / 0.33) 0px, transparent 50%),
radial-gradient(at 98% 1%, rgba(var(--color-error-500) / 0.33) 0px, transparent 50%);
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
Custom Fonts
Fonts may be installed from a local or remote source. For GDPR compliance and optimal performance we recommend installing the fonts locally. For this guide we'll demonstrate this process using free fonts from Google Fonts.
1. Download a Font
Select a font on Google Fonts, then tap the "Download Family" button near the top-right of the page.
2. Add the Font Files
Unzip the downloaded file, then copy all font files to the /static/fonts
directory in the root of your
SvelteKit project. When available we recommend using variable fonts as they require only a single file. Otherwise copy all
static font file assets to the /static/fonts
directory.
/static/fonts/Inter-VariableFont_slnt,wght.ttf
3. Apply @font-face
At the top of your global stylesheet /src/app.postcss
append the @font-face settings per each font. The font-family
assigns the font's reference name, while src
points to the font file(s) in your /static/fonts
directory.
@font-face {
/* Reference name */
font-family: 'Inter';
/* For multiple files use commas, ex: url(), url(), ... */
src: url('/fonts/Inter-VariableFont_slnt,wght.ttf');
}
4. Set the Font Family.
Use CSS Property overrides or open your custom theme to set the font family for base and heading properties. Be sure to use the same reference name set above or your font will not work.
/* NOTE: set your target theme name (ex: skeleton, wintry, modern, etc) */
:root [data-theme='skeleton'] {
--theme-font-family-base: 'Inter', sans-serif;
--theme-font-family-heading: 'Inter', sans-serif;
/* ... */
}
5. Handle Font Flickering.
To avoid your page flickering during hydration, consider using the font-display
descriptor for the
@font-face
at-rule that determines how a font face is displayed based on whether and when it is downloaded and ready to use.
Replace your @font-face
at-rule with the following:
@font-face {
/* Reference name */
font-family: 'Inter';
/* For multiple files use commas, ex: url(), url(), ... */
src: url('/fonts/Inter-VariableFont_slnt,wght.ttf');
/* Gives the font face an extremely small block period and an infinite swap period. */
font-display: swap;
}