I read the #102 issue for custom class names. But I found the solution a bit lacking.
disabling an existing module and adding your own plugin
If you want to change one class from a plugin, you need to copy paste the plugin and add the change. And what if you want to change 20 plugins?
So I forked the project and came up with a way to make all classes configurable. https://github.com/davidDuymelinck/tailwindcss
Basically I added a new key to the config object, modifyClassNames. The value of the key is an object which has the module names as keys.
Each module has a prefix and modifier key. The prefix has a string value. The modifier key is an object with a key from the plugin and as value the class name after the prefix.
modifyClassNames: {
whitespace: {
prefix: 'ws-',
modifier: {
normalWord: 'wrap-word-normal'
}
}
}
This example is for the class name that is now generated as break-normal.
For the modifier keys I wanted to stay as close to the style value as possible to make the configuration as easy as possible. An other example of this is the noDecoration key for the current class name no-underline.
I understand this is a nice to have for the maintainers. I just wanted to show the solution I came up with, to find out if there are other people who still want class name configuration included in Tailwind CSS?
Coming from using Tachyons, I like the fact that Tailwind allows you to customize the values since it can cover more bases than Tachyons alone can. However, I think I prefer Tachyons' terse class names over the verbose ones here.
Still, one advantage of not adding this feature is that multiple companies/parties are forced to use the same "language" to refer to the same concepts. If I work at company X who use Tailwind and then start working for company Y who also uses Tailwind, when scanning the code base for company Y, I already know that tracking-<x> refers to the letter spacing. By enabling this feature, Company Y can change it to tr-<x> whereas Company X leaves it as is, thereby removing this one advantage.
I understand that a consistent naming scheme can be an advantage for a framework.
The main reason I wanted a way to configure every class is beyond the realm of naming preferences.
I'm working for a marketing company and I want to give the marketeers as much flexibility as possible. That is why I choose a functional CSS framework. But it's hard to explain tracking-x refers to letter spacing. Another example is padding and margin, as developer you know the difference. But i think inner-spacing and outer-spacing are the names more people will understand.
The possibility to cater the framework class naming to your public can be a big argument to convince people to start using a more technical solution for their problems, without adding too much mental overhead.
The main reason I wanted a way to configure every class is beyond the realm of naming preferences.
I'm working for a marketing company and I want to give the marketeers as much flexibility as possible. That is why I choose a functional CSS framework. But it's hard to explain tracking-x refers to letter spacing. Another example is padding and margin, as developer you know the difference. But i think inner-spacing and outer-spacing are the names more people will understand.
I can see how that would be really helpful for people who aren't developers.
Also, one other question. Let's say I wanted to configure the tracking- related properties to use tr- instead. When we talk about 'configurable' names, do we mean that this is a one-is-replaced-by-another configuration? For example:
.tracking-X { }
becomes
.tr-X { }
Or we are talking about a one-can-be-aliased-by-another relationship?
.tracking-X { }
becomes
.tracking-X, .tr-X { }
The first one implies that only one name can be used throughout the entire code base whereas the second means a developer who is familiar with Tailwind can use p and m whereas a marketeer can use the inner-spacing and outer-spacing names.
Granted, I'm not sure how this second approach would affect performance, nor whether it would cause more problems because now an p element's class string could be class="tracking-X, tr-x"
We might make this possible eventually but it's really low priority.
In the mean time, you could always write a plugin that generates the same CSS as an existing module but with a different class name, and then disable the built-in module in the modules section of your config file:
// ...
modules: {
// ...
- tracking: ['responsive'],
+ tracking: false,
// ...
}
// ...
The plugin itself would look like this:
import _ from 'lodash'
export default function(variants) {
return function ({ addUtilities, config }) {
const utilities = _.map(config('tracking'), (value, modifier) => {
return defineClass(`ls-${modifier}`, {
'letter-spacing': `${value}`,
})
})
addUtilities(utilities, variants)
}
}
@JordanMartinez my solution is of the one-is-replaced-by-another type. The reason is that marketeers don't care about which technology you use, as long as they can be more productive everything is fine.
The only thing that slows down your productivity is that you can't refer to the Tailwind documentation. You have to write your own.
I mentioned that Tailwind provides a way to change classes. But if you have to change a lot of classes, it's too much boilerplate.
I understand the maintainers that a more DX solution is low on the priority list.
I'm going to make an effort to keep my fork up to date, so that other people can use it.
@adamwathan Thanks for the snippet!
@xwero Ah... yeah, that would create problems.
Also, I guess even the name-change decision (type alias or replacement) could be defined for each module.
I think there is some merit to allowing custom class names in Tailwind core that's possibly being overlooked, related to semantic naming.
For example, having semantic text color names like: heading, text, and link would currently generate classes called text-heading, text-text (this one is especially bad), and text-link which seems much less useful than if one could change the text class name to be color.
Then you'd be able to generate classes as such: color-heading, color-text, and color-link, which seems much more comprehensible.
No concrete plans to support this so going to close for now.
Most helpful comment
I think there is some merit to allowing custom class names in Tailwind core that's possibly being overlooked, related to semantic naming.
For example, having semantic text color names like:
heading,text, andlinkwould currently generate classes calledtext-heading,text-text(this one is especially bad), andtext-linkwhich seems much less useful than if one could change thetextclass name to becolor.Then you'd be able to generate classes as such:
color-heading,color-text, andcolor-link, which seems much more comprehensible.