A
zero-config
&zero-dependency
tool for generating accessible CSS themes using color theory.
To install AutoTheme, you can use the following methods:
Manual
install.sh
will detect your system and download the appropriate binary.
For Linux/macOS (or Windows using Git Bash/WSL):
curl -sL https://raw.githubusercontent.com/username/repo/main/install.sh | bash
For Windows (PowerShell):
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/username/repo/main/install.ps1" -OutFile "install.ps1"; ./install.ps1
Download the appropriate binary for your system from the releases page.
GO
NPM
To generate your theme, run the following command in your terminal.
autotheme
By default AutoTheme will output to
src/autotheme.css
using a random color and harmony.
autotheme --color="#FF0000" --harmony="analogous"
Using HTML
Include the generated CSS file in your HTML.
<link rel="stylesheet" href="./src/autotheme.css" />
Using CSS
Include the generated CSS file in your main.
@import "./autotheme.css";
Using A Framework
If you are using a framework like React, Vue, or Angular, you can include the CSS file in your main component.
import "./src/index.css";
If you are planning on changing your theme often, or just want to make sure your theme stays up-to-date with any changes you make. You can add AutoTheme to your build process.
Manually add step to your build process.
Could be as simple as adding
&& autotheme <ARGS>
If you are using Vite.
See AutoTheme Vite Plugin for more information.
- Command to generate the plugin
AutoTheme can be configured using:
CLI Flags
Long | Short | Type | Description |
---|---|---|---|
--color |
-c |
string |
The primary color of the theme. |
--harmony |
-a |
string |
The harmony of the theme. See [Harmonies] for accepted harmony values. |
--output |
-o |
string |
The output file path. (default=./src/autotheme.css) |
--config |
string |
Path to your AutoTheme config file. (default=./autotheme.yml) | |
--preview |
boolean |
Generate a preview.html to preview the theme. | |
--silent |
-s |
boolean |
Suppress all output from AutoTheme. |
--version |
-v |
boolean |
Display version. |
--help |
-h |
boolean |
Display help. |
A config file
# autotheme.yml
color: "#FF0000"
harmony: "analogous"
scalar: 1.618
# Finish this section
# Interactive prompt
autotheme init
# Skip the interactive prompt
autotheme init -y
By default
init
will create aautotheme.yml
in the current directory.
AutoTheme aims to be WCAG 2.1 AAA compliant by default. (See Understanding Contrast (WCAG))
AutoTheme generates a --at-bkgd
background color for light & dark modes.
Contrast ratios for each text color are calculated against the appropriate background color. If the contrast ratio is below 7:1, it will adjust the color until it meets the criteria.
A set of colors related to each other.
Set your harmony using the --harmony
or -a
flag or the harmony
option in the config file.
In addition to the Harmony, each color has a set of tints, shades, and tones. And each of those colors has a set of accessible text colors. See Accessible Colors
Each color in the Harmony consists of:
- 1 primary color
- 5 tints (L1, ..., L5)
- 5 shades (D1, ..., D5)
- 4 tones (G1, ..., G4)
Let's look at some advanced features to create modern and unique themes.
Gradients are a great way to add depth to your site.
Using TailwindCSS (Recommended)
AutoTheme intregrates directly with Tailwind's linear gradients, and extends it with radial gradients.
<div class="bg-gradient-to-br from-primary to-hamony-b"></div>
<div class="bg-radial from-harmony-a"></div>
Tailwind doesn't have built-in support for radial gradients, so AutoTheme adds some utility classes to your tailwind config.
radial-position
- sets the position of the gradient (default: '50% 50%')radial-scale
- sets the scale of the gradient (default: '100% 100%')
<div class="radial-scale-100 radial-position-0-0 bg-radial"></div>
<!-- Or using arbitrary values -->
<div class="radial-scale-[10%_90%] radial-position-[0px_150px] bg-radial"></div>
Basic Usage
AutoTheme provides a some simple utility css classes for creating gradients.
Lets take a look a the
at-linear
class.
<div class="at-linear"></div>
:root {
/* default gradient */
--at-direction: to right;
--at-from: rgb(var(--at-c0) / var(--at-opacity));
--at-from-position: -20%;
--at-to: transparent;
--at-to-position: 120%;
}
.at-linear {
--at-stops: var(--at-from) var(--at-from-position), var(--at-to) var(--at-to-position);
background-image: linear-gradient(var(--at-direction), var(--at-stops));
}
Why are utility classes needed?
You may have noticed that .at-linear
and .at-radial
are the only classes that AutoTheme provides.
That is because if we were to try and use a variable for the gradient (let's say var(--at-linear)
).
<div style="--at-from: rgb(var(--at-c4)); background: var(--at-linear);"></div>
This is because the variable has already been defined before we set the new color.
You can also customize gradients inline using the
style
attribute.
<div
class="at-linear"
style="--at-direction: to bottom; --at-from: var(--at-c1); --at-to: var(--at-c3);"
></div>
Or by creating a new class.
-
Add a new class to pair with the
at-linear
class that defines the gradient properties..your-gradient { --at-direction: 45deg; --at-from: var(--at-c1); --at-from-position: 0%; --at-to: var(--at-c3); --at-to-position: 100%; }
-
Add both classes to your element.
<div class="your-gradient at-linear"></div>
IMPORTANT: The
your-gradient
class must be defined before theat-linear
class.
Radial gradients are customized in the same way except for using the
scale
andposition
variables.
.at-radial {
--at-stops: var(--at-from) var(--at-from-position), var(--at-to) var(--at-to-position);
background-image: radial-gradient(var(--at-scale) at var(--at-position), var(--at-stops));
}
Noise is a great way to add texture to your site.
Include the --at-noise
variable in your CSS. Or if you are using TailwindCSS, you can use the at-noise
class.
.element {
/* Basic Usage */
background-image: var(--at-noise);
}
Combine noise with gradients and blend modes to create unique effects.
.element {
/* Advanced Usage */
background-image: var(--at-noise) linear-gradient(
var(--at-direction),
var(--at-c1),
var(--at-c2)
);
background-blend-mode: overlay screen;
}
To finish integrating support for prefers-color-scheme: dark
, there are a couple more steps.
-
On page load, so generally speaking your
index.html
should initialize dark-mode to prevent flashing unstyled content FOUC- You can either inline the script tag directly
<script> const darkMode = window.matchMedia("(prefers-color-scheme: dark)"); if (localStorage.getItem("darkMode") === "true" || darkMode.matches) { document.documentElement.classList.add("at-dark"); } // If the user's system changes the preferred color scheme darkMode.addEventListener("change", (e) => { if (e.matches) { document.documentElement.classList.add("at-dark"); } else { document.documentElement.classList.remove("at-dark"); } }); </script>
- or load it as an external file
/darkmode.js
instead
<script src="/darkmode.js"></script>
// darkmode.js /** * Init Darkmode * - checks for dark mode preference * - applies `at-dark` class to the root element if dark mode is preferred * - handles OS color-scheme change events */ function initializeDarkMode() { const darkMode = window.matchMedia("(prefers-color-scheme: dark)"); if (localStorage.getItem("darkMode") === "true" || darkMode.matches) { document.documentElement.classList.add("at-dark"); } // This wont set the local storage on change, but it will update the class darkMode.addEventListener("change", (e) => { if (e.matches) { document.documentElement.classList.add("at-dark"); } else { document.documentElement.classList.remove("at-dark"); } }); } initializeDarkMode();
-
Setup your onClick handler
/** * Toggle Dark Mode * - applies `at-dark` class to the root element * - saves the state to local storage */ function toggleDarkMode() { const darkMode = document.documentElement.classList.toggle("at-dark"); localStorage.setItem("darkMode", darkMode.toString()); }
- Add command to CLI for generating the dark mode script.
Now your site is ready to support both light
& dark
color schemes based on user preferences! 🎉
git clone https://github.com/damienbullis/autotheme.git
cd autotheme
make install
See the Makefile for more commands.
make test
make test-watch
Releases are created via the Release
workflow.
To create a new release, manually trigger the release workflow by going to the actions tab in the repo and selecting the Release
workflow.
Enter the new version number when prompted and the workflow will take care of the rest.
- Add on tag push trigger to the release workflow.
Start your commit message with one of the following prefixes if you want to tag your commits in the changelog:
feat - <YOUR_MESSAGE>
for new featuresfix - <YOUR_MESSAGE>
for bug fixeschore - <YOUR_MESSAGE>
for basically everything else