What is Baleada Linear Numeric?
Updated on August 22, 2024Source code
Baleada Linear Numeric is a function that returns configurations for Tailwind default plugins, aliasing all class names to use a linear numeric naming convention.
By default, it produces class names like the following:
.text-4instead of.text-base.font-1instead of.font-hairline.mt-8,.mt-9, and.mt-10, instead of.mt-10,.mt-12, and.mt-16
It can be customized to produce classes like .text-40 or .text-400 instead of .text-4.
If you're familiar with the concept of a linear numeric naming convention in Tailwind, you can jump to the Installation section. Otherwise, the next section has some helpful background info!
WTF is a "linear numeric naming convention"?
Tailwind uses several different naming conventions for its utility classes.
Some classes, like transition duration, use literal values from the underlying design system:
duration-75for75msduration-100for100msduration-150for150ms
Other classes use "T-shirt sizes" in their class names. For example, here are the default font size classes:
.text-xs.text-sm.text-base.text-lg.text-xl.text-2xl- etc.
Other classes, like the ones for font weight, use more semantic words:
.font-hairline.font-thin.font-light.font-normal.font-medium.font-semibold.font-bold.font-extrabold.font-black
Spacing utilities (margin, padding, width, height, and gap), use proportional numeric names. This means that the classes are suffixed with numbers that are proportional to the underlying values.
Spacing utilities multiply the underlying rem value by 4 to derive the class name. Here are a few examples from the padding utilities:
.p-1for0.25rem.p-5for1.25rem.p-24for6rem.p-64for16rem
And finally, Tailwind's color utilities use a linear numeric naming convention. This means that all class suffixes are numbers that increment linearly from one value to the next:
.bg-blue-100.bg-blue-200.bg-blue-300.bg-blue-400.bg-blue-500.bg-blue-600.bg-blue-700.bg-blue-800.bg-blue-900
Literal, T-shirt, semantic, proportional numeric, and linear numeric—all of these naming conventions have their pros and cons. Baleada Linear Numeric will help you explore the pros and cons of linear numeric class names in your own projects.
Installation
Baleada Linear Numeric can be installed from NPM:
npm i @baleada/tailwind-linear-numeric --save-dev
Usage
To get started, require @baleada/tailwind-linear-numeric in your Tailwind config file. The default export is a function, which we'll call getLinearNumeric in this example.
// tailwind.config.js
const getLinearNumeric = require('@baleada/tailwind-linear-numeric')
The getLinearNumeric function returns configurations for the following properties of the theme object in your config file:
colorsspacingblurborderRadiusborderWidthboxShadowdropShadowflexGrowflexShrinkfontSizefontWeightletterSpacinglineHeightmaxWidthoutlineOffsetoutlineWidthringOffsetWidthringWidthtextDecorationThicknesstextUnderlineOffsettransitionDurationtransitionDelay
The linearNumeric function does not configure the following properties, because their default configurations coincidentally follow all the rules in Baleada Linear Numeric's naming convention:
maxHeightminHeightminWidth
The function accepts one parameter: an object with options (none of which are required). Here's a full breakdown of that object:
onlyIndicates which properties' configurations should be returned by linearNumeric.
When only is an Array, linearNumeric will return a config object with a key for each item in the array.
When only is a String, linearNumeric will directly return the config object for that property.
increment100Determines how much the class name is incremented for each step up in size.
For example, if you pass 1 as the increment, you'll get class names like .text-4 and .text-5 instead of the default .text-400 and .text-500.
If you want to use linear numeric naming for all of these properties, simply spread the output of linearNumeric into your config file.
// tailwind.config.js
const linearNumeric = require('@baleada/tailwind-linear-numeric')
module.exports = {
theme: {
...linearNumeric() // Overrides the default theme (only the properties listed above)
}
}
If you only want to use linear numeric naming for some properties, use the only option to restrict your list.
// tailwind.config.js
const linearNumeric = require('@baleada/tailwind-linear-numeric')
module.exports = {
theme: {
...linearNumeric({ only: ['spacing', 'minHeight'] }) // Overrides the default theme's spacing and minHeight values, but you'll still get default classes (e.g. .shadow-md) for other properties
}
}
To customize the increment that gets used in your class names, use the increment option.
// tailwind.config.js
const linearNumeric = require('@baleada/tailwind-linear-numeric')
module.exports = {
theme: {
...linearNumeric({ increment: 10 }) // Produces classes like .text-40 and .text-50 instead of the default .text-4 and .text-5
}
}
You can call linearNumeric as many times as you want, so feel free to use the only and increment options to fine tune class names for individual properties.
// tailwind.config.js
const linearNumeric = require('@baleada/tailwind-linear-numeric')
module.exports = {
theme: {
...linearNumeric({ only: ['fontSize'] }), // .text-4, .text-5, etc.
...linearNumeric({ only: ['fontWeight'], increment: 100 }) // .font-400, .font-500, etc.
}
}
Almost all configurations returned by linearNumeric are plain JavaScript objects, so you can typically spread them out alongside any additional custom values you want to add.
If you're using linearNumeric to add new values inside of one existing property, you can pass a String to the only property to make sure that it directly returns the config object for that property:
// tailwind.config.js
const linearNumeric = require('@baleada/tailwind-linear-numeric')
module.exports = {
theme: {
borderWidth: {
'55': '3px',
...linearNumeric({ only: 'borderWidth', increment: '10' }), // Spreads in all the default borderWidth values
}
}
}
To expand on that concept: linearNumeric returns a full colors object for the colors property. If you want to access a single color, you can pass colors to the only option, and tack on the color name right after your function call:
// tailwind.config.js
const linearNumeric = require('@baleada/tailwind-linear-numeric')
module.exports = {
theme: {
colors: {
blue: linearNumeric({ only: 'colors', increment: 100 }).blue, // .bg-blue-100, .bg-blue-200, etc.
gray: {
...linearNumeric({ only: 'colors' }).gray, // .bg-gray-1, .bg-gray-2, etc.
'10': 'hsla(217, 30%, 8%, 1.0)',
},
// Also, don't forget to add black, white, and transparent, if you need them!
}
}
}
Also, be aware that Baleada Linear Numeric does include Tailwind's default standalone colors, black, white, and transparent:
// tailwind.config.js
const linearNumeric = require('@baleada/tailwind-linear-numeric')
module.exports = {
theme: {
colors: {
// These colors don't increment, so they are unaffected by the increment option
black: linearNumeric({ only: 'colors' }).black,
white: linearNumeric({ only: 'colors' }).white,
transparent: linearNumeric({ only: 'colors' }).transparent,
}
}
}
Naming convention rules
Ok, so Baleada Linear Numeric uses linear numeric names—but where does the numbering start? How are "default" classes handled?
Baleada Linear Numeric follows the rules below, in their exact order, to answer those questions individually for each property:
Properties that already have linear numeric names (just color, at the moment) are not changed from their original naming scheme, except to support different increments using
linearNumeric'sincrementoption. Colors, for example, are only changed to support different increments.Anything with an underlying value of
0ornone(e.g..tracking-normalandshadow-none) is named with the number0.If a the property has a
0class, Baleada Linear Numeric aliases other class names so that they increment linearly from the0class (or decrement, if the property can have negative values).If the Tailwind team clearly and explicitly intends certain values to be "in-between" the core set of values, Baleada Linear Numeric respects that categorization, and increments (or decrements) the class names by half.
For example, Tailwind 2.0 introduced
0.5,1.5,2.5, and3.5classes to the spacing scale, intending for those values to be used only when1,2,3, and4aren't quite precise enough. Rather than starting from0and assigning1to Tailwind's0.5,2to Tailwind's1,3to Tailwind's1.5, and so on, Baleada Linear Numeric stays true to Tailwind's intention of those being in-between values, and matches those names exactly.If there is no
0value for the property, but there is a value assigned to aDEFAULT,normal, orbasekey, Baleada Linear Numeric renames DEFAULT/normal/base with4. This follows the CSS convention of using400for normal font weight.Then, Baleada Linear Numeric increments in both directions from the
4class. Note that this sometimes results in certain properties (e.g.borderWidth) having4classes, but not having classes for1,2, or3.Tailwind's
.shadow-inneris treated as a default negative shadow, and is assigned a key of-4(which produces the class.-shadow-4).Proportions (e.g.
full: 100%,screen: 100vh), key words (e.g.autoandoutline), and screen breakpoints (applicable formax-widthutilities) are left unchanged.If a default Tailwind property includes a secondary set of values with different units, the Baleada Linear Numeric follows all the above rules to name those secondary values' classes, and finally includes the unit (and an extra hyphen) in the middle of the class name.
For example, default
lineHeightvalues include both relative values (e.g.1,1.25, etc.) and fixed values usingremunits (e.g.1rem,1.25rem, etc.). Baleada Linear Numeric follows all the above naming rules to name the relative and fixed values, then, to avoid naming collisions, adds-rem-to the middle of the class name for allremvalues.This produces classes like
.leading-3(relative line height of1.375) and.leading-rem-3(fixed line height of0.75rem).Note that this also happens with
spacingwhich produces classes likew-pxusing Tailwind's default config. In Baleada Linear Numeric, that class becomesw-px-1.
Once you get used to the naming convention, you'll find that classes become very easy to guess without visiting your config file or these docs.
But, if you have any doubts, check out the class references to see classes are being generated for each property, how they match up with the original Tailwind classes, and what the underlying values are.
Language, compilation, browser support, and dependencies
Baleada Linear Numeric is written in modern JavaScript, exported using CommonJS modules, and is not compiled. It's not designed to be used in the browser, but instead will most often be used in the Node environment where you are configuring Tailwind.
Baleada Linear Numeric has no dependencies, although it does require Tailwind as a peer dependency.
Semantic versioning conventions
In Baleada Linear Numeric, the only thing that will ever trigger a new major version is a change to the underlying naming convention outlined above.
From time to time, Tailwind's default config file changes, usually to support new properties, and sometimes to expand the design system and add values for existing properties. When this happens, any necessary updates to Baleada Linear Numeric will be released as a new minor version, even if the linear numeric naming convention gets applied in a different way.
For example, Tailwind 1.2 introduced a new value for the borderRadius property, between two existing values, and it also added the transitionDuration and strokeWidth properties (among others). In response, Baleada Linear Numeric was updated in the following ways:
- Baleada Linear Numeric's
borderRadius.5was changed toborderRadius.6, and the new value was inserted asborderRadius.5. - The
transitionDurationandstrokeWidthproperties were added to the config object returned by Baleada Linear Numeric - Baleada Linear Numeric released a new minor version
After Tailwind 1.2 was released, anyone using the .rounded-5 class generated by Baleada Linear Numeric would have had to change all occurrences of that class to .rounded-6 in their code.
This kind of impact is characteristic of a breaking change and a new major version. However, since it was a Tailwind design system change and not a change to the rules of the linear numeric naming convention, only a new minor version was released.