Skip to content
This repository has been archived by the owner on Apr 24, 2024. It is now read-only.

Commit

Permalink
Use OKLCH plugin for black, white & grays
Browse files Browse the repository at this point in the history
  • Loading branch information
MartijnCuppens committed Aug 8, 2023
1 parent 629514f commit a6f73a7
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 19 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Brings OKLCH to Tailwind and introduces these helpful utilities:
- Match utilities that will match the color of a property with another property (e.g. outline color matches the background color), with support for opacity modifiers.
- Lightness offset utilities that darken or lighten colors (e.g. on hover).

You don't need to change your theme colors, since this plugin uses color.js to convert all existing colors.

## Installation

To use this package, install it via npm:
Expand Down Expand Up @@ -54,11 +56,14 @@ The `text-lightness-offset-10` increases the lightness of the text with 10%. Oth

If you prefer to change the threshold when the contrast color switches to black or white, you can adjust the value of `contrastThreshold`. This value should be somewhere between `0` and `1`. The higher the number, the more likely white will be chosen as the contrast color. While I was working on this plugin, I noticed that a contrast threshold of `.6` looked better on different screens than `.5`, since dark colors seem to have lesser contrast then lighter colors in reality.

Precision was added since color.js uses floats to calculate the OKLCH values, which can result in long numbers. Defaults to `6`.

```js
/** @type {import('tailwindcss').Config} */
module.exports = {
plugins: [require('tailwindcss-oklch')({
contrastThreshold: .5,
precision: 8,
})],
}
```
Expand Down
24 changes: 12 additions & 12 deletions examples/dist/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -817,9 +817,9 @@ video {
}

.bg-blue-600 {
--tw-bg-l: 0.5461497233109911;
--tw-bg-c: 0.21520774805039064;
--tw-bg-h: 262.88091714087415;
--tw-bg-l: 0.54615;
--tw-bg-c: 0.215208;
--tw-bg-h: 262.880917;
--tw-bg-l-offset: 0;
--tw-bg-opacity: 1;
background-color: oklch(clamp(0, calc(var(--tw-bg-l) + var(--tw-bg-l-offset)), 1) var(--tw-bg-c) var(--tw-bg-h) / var(--tw-bg-opacity));
Expand Down Expand Up @@ -864,9 +864,9 @@ video {
}

.text-blue-600 {
--tw-text-l: 0.5461497233109911;
--tw-text-c: 0.21520774805039064;
--tw-text-h: 262.88091714087415;
--tw-text-l: 0.54615;
--tw-text-c: 0.215208;
--tw-text-h: 262.880917;
--tw-text-l-offset: 0;
--tw-text-opacity: 1;
color: oklch(clamp(0, calc(var(--tw-text-l) + var(--tw-text-l-offset)), 1) var(--tw-text-c) var(--tw-text-h) / var(--tw-text-opacity));
Expand Down Expand Up @@ -902,9 +902,9 @@ video {
}

.hover\:bg-blue-400:hover {
--tw-bg-l: 0.7137400464544268;
--tw-bg-c: 0.14338050936284802;
--tw-bg-h: 254.62402136543372;
--tw-bg-l: 0.71374;
--tw-bg-c: 0.143381;
--tw-bg-h: 254.624021;
--tw-bg-l-offset: 0;
--tw-bg-opacity: 1;
background-color: oklch(clamp(0, calc(var(--tw-bg-l) + var(--tw-bg-l-offset)), 1) var(--tw-bg-c) var(--tw-bg-h) / var(--tw-bg-opacity));
Expand All @@ -919,9 +919,9 @@ video {
}

.hover\:text-blue-800:hover {
--tw-text-l: 0.42444500037043004;
--tw-text-c: 0.18086883857590272;
--tw-text-h: 265.63771048282496;
--tw-text-l: 0.424445;
--tw-text-c: 0.180869;
--tw-text-h: 265.63771;
--tw-text-l-offset: 0;
--tw-text-opacity: 1;
color: oklch(clamp(0, calc(var(--tw-text-l) + var(--tw-text-l-offset)), 1) var(--tw-text-c) var(--tw-text-h) / var(--tw-text-opacity));
Expand Down
20 changes: 13 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const propertyColors = Object.fromEntries(utilities.map(({ key }) => {
];
}).flat());

export default plugin.withOptions(({ contrastThreshold = 0.6 } = {}) => {
export default plugin.withOptions(({ contrastThreshold = 0.6, precision = 6 } = {}) => {
return ({
matchUtilities, theme, corePlugins, addDefaults,
}) => {
Expand All @@ -34,6 +34,13 @@ export default plugin.withOptions(({ contrastThreshold = 0.6 } = {}) => {
}, {});
};

// Round numbers and turn NaN into 0.
// NaN occurs for the hue gray colors, that also have a chroma of 0,
// so we can safely set the hue to 0 instead of NaN.
const round = (value) => {
return (value || 0).toFixed?.(precision).replace(/\.?0+$/, '') || value;
}

matchUtilities(
{
[key]: (value) => {
Expand All @@ -45,7 +52,7 @@ export default plugin.withOptions(({ contrastThreshold = 0.6 } = {}) => {
catch (error) {
// Some values can be keywords like inherit.

// If the color is a oklch function with custom properties (eg. `oklch(var(--color-primary-l) var(--color-primary-c) var(--color-primary-h))`), parse these custom properties.
// If the color is an oklch function with custom properties (eg. `oklch(var(--color-primary-l) var(--color-primary-c) var(--color-primary-h))`), parse these custom properties.
const match = colorValue.match(/^oklch\((var\(--[a-z0-9-]+?\)) (var\(--[a-z0-9-]+?\)) (var\(--[a-z0-9-]+?\))(?: \/ (.+))?\)$/i);
if (match) {
const [, l, c, h, a] = match;
Expand All @@ -57,13 +64,12 @@ export default plugin.withOptions(({ contrastThreshold = 0.6 } = {}) => {
}
const result = {};

// Exclude `transparent` which has a NaN hue value.
if (color && !Number.isNaN(color.oklch.h)) {
if (color?.oklch && colorValue !== 'transparent') {
const { oklch, alpha } = color;
Object.assign(result, {
[`--tw-${key}-l`]: oklch.l.toString(),
[`--tw-${key}-c`]: oklch.c.toString(),
[`--tw-${key}-h`]: oklch.h.toString(),
[`--tw-${key}-l`]: round(oklch.l),
[`--tw-${key}-c`]: round(oklch.c),
[`--tw-${key}-h`]: round(oklch.h),
[`--tw-${key}-l-offset`]: '0',
...(alpha === 1 && { [`--tw-${base}-opacity`]: alpha.toString() }),
...addProperties(`oklch(clamp(0, calc(var(--tw-${key}-l) + var(--tw-${key}-l-offset)), 1) var(--tw-${key}-c) var(--tw-${key}-h) / ${alpha === 1 ? `var(--tw-${base}-opacity)` : alpha.toString()})`),
Expand Down

0 comments on commit a6f73a7

Please sign in to comment.