tailwindcss: Force tailwind to use compatible rgb syntax? - css

I'm porting an app using tailwindcss to work with IE11. Unfortunately, tailwindcss insists on generating colors using the modern W3C CSS Color Module Level 4 rgb() syntax, which does not appear to be working in IE, e.g. it generates classes like these:
.bg-blue-500 {
--tw-text-opacity: 1;
color: rgb(59 130 246 / var(--tw-bg-opacity));
}
I have tried using postcss-color-rgb in my postcss pipeline to transform this back into the usual syntax to no avail:
postcss([
require('tailwindcss')(twConfig),
require('postcss-color-rgb'),
require('autoprefixer'),
]).process(cssContent, {
from: css,
to: `build/${name}.css.tmp`
})
Tailwind claims to be compatible with any modern browser, which some might dare to classify IE11 as. Any thoughts on getting tailwind to play nicely with IE11 here?

Tailwind will use this syntax when the background opacity utilities are enabled.
If you disable it, it will use the regular hex syntax for colors, so you don't even need the postcss-color-rgb post css plugin anymore!
You can disable this by adding this to your tailwind.config.js:
// tailwind.config.js
module.exports = {
corePlugins: {
// ...
backgroundOpacity: false,
}
}
In my case, I had a similar issue with text and border colors. You might need to experiment and figure out which of these "opacity" utilities are causing you trouble. For my project, I disabled all of them:
// tailwind.config.js
module.exports = {
corePlugins: {
// ...
backdropOpacity: false,
backgroundOpacity: false,
borderOpacity: false,
divideOpacity: false,
ringOpacity: false,
textOpacity: false
}
}

Related

Is there a proper place to put tailwindcss classes that you explicitly need loaded (besides inline comments)?

I have an array of colors gray-200, red-200, blue-200, green-200 that I also need hover: and border- variants (e.g. hover:gray-200).
If I explicitly add a comment (/* ... */) explicating the exhaustive list of permutations (hover:gray-200, border-blue-200, etc.), the styles load properly. Presumably because of (purgeable html?), I can't just dynmically create these on the fly (when I do, the CSS doesn't load).
The inline comment feels like an understandable location, but not the ideal spot to put all that. Is there a "proper" place to do this (like in the config file or something), and if so, how/where?
Forgive the ignorance if this is obvious, I'm new to tailwind.
EDIT: If it matters, I'm using React and NodeJS and yarn.
As you mentioned you cannot build dynamic CSS classes on the fly. In order to work you need to mention somewhere in your app full class name or safelist it. It can be other file, comment or safelist section in Tailwind configuration file
Please note there are no such utility as hover:gray-200 etc as you need to be specific what do you colorize (like text - hover:text-gray-200, background - hover:bg-gray-200 etc)
1. Pass an array of strings
Every part will be compiled as it is
// tailwind.config.js
module.exports = {
safelist: [
'text-gray-200',
'bg-gray-200',
'border-gray-200',
'hover:text-gray-200',
'hover:bg-gray-200',
'hover:border-gray-200',
// ....
],
}
2. In a specific file
Common pattern to create and name file safelist.txt, put in a root of your project and watch its content. The content of the file could be any, extension could be any, name could be any, there are only two rules - it should contain full names of required classes (like in example 1) and this file should be included in content section
// tailwind.config.js
module.exports = {
content: [
// source files,
'./safelist.txt'
]
}
These both methods not ideal as you need to write a lot of classes on your own. However tailwind.config.js is still JS file so you can do something like this
3. Using mapping
Create an array of required color utilities and map them to generate required class names. This way it can be dynamic
// tailwind.config.js
const colors = ['gray-200', 'red-200']
const safelist = colors.map(color => `text-${color} bg-${color} border-${color} hover:text-${color} hover:bg-${color} hover:border-${color}`)
module.exports = {
safelist:,
}
Still not perfect - sometimes thing can be messy and hard to read but it is simple
4. Regular expressions
Finally Tailwind provides you a way to use patterns for safelisting
// tailwind.config.js
module.exports = {
// an array of multiple patterns
safelist: [
{
pattern: /(bg|text|border)-(red|gray)-200/,
variants: ['hover'],
},
],
}
Here we're saying safelist combination of background, color, border-color properties with red-200 and grey-200 utilities plus hover variant for all of them. Variants could be any, if you need you should pass breakpoint variants also and combination of them. Take a look
// tailwind.config.js
module.exports = {
// just as example you can specify multiple patterns for each utility/variant combination
safelist: [
{
pattern: /(bg|text)-(red|gray)-200/,
variants: ['hover'],
},
{
pattern: /border-(red|gray)-500/, // another color
variants: ['hover', 'lg', 'lg:hover']
}
],
}
One last thing about safelisting colors - if you left pattern like this /(bg|text|border)-(red|gray)-200/ it would safelist all color utilities opacity included (bg-gray-200/0, bg-gray-200/5, bg-gray-200/10 and so on).
/** part of compiled CSS file */
.border-gray-200 {
--tw-border-opacity: 1;
border-color: rgb(229 231 235 / var(--tw-border-opacity))
}
.border-red-200 {
--tw-border-opacity: 1;
border-color: rgb(254 202 202 / var(--tw-border-opacity))
}
.border-gray-200\/0 {
border-color: rgb(229 231 235 / 0)
}
.border-gray-200\/5 {
border-color: rgb(229 231 235 / 0.05)
}
/** and so on - many-many classes */
If you are planning not to use opacity variants, finish your pattern with $ dollar sign
// tailwind.config.js
module.exports = {
// an array of multiple patterns
safelist: [
{
pattern: /(bg|text|border)-(red|gray)-200$/, // here is $ - no opacity utilities
variants: ['hover'],
},
],
}
Here - check different types of safelist config and Generated CSS (tab at the bottom - it will show all compiled classes)

TailwindCSS neutral-500 color no longer working after installing daisyUI

I have been using tailwindcss for my react project and would now like to use daisy-ui in addition. I installed it as instructed and added the plugin to my tailwind.config. After doing this some of the designs in the page look off. In particular the ones styled with border-neutral-500, bg-neutral-500 - for these colors I also no longer see the little color indicator in vscode.
I am not using a custom theme but when looking at it it seems daisyUI is specifying its own version of the neutral color. https://daisyui.com/theme-generator/ vs https://tailwindcss.com/docs/customizing-colors - is this the source of the problem? How can I avoid this?
I guess there is really conflict with utilities. DaisyUI extending theme colors with its own
You may reassign neutral color palette again with default Tailwind values like
const colors = require('tailwindcss/colors');
/** #type {import('tailwindcss').Config} */
module.exports = {
content: [],
theme: {
extend: {
colors: {
neutral: colors.neutral,
}
}
},
plugins: [
require("daisyui")
],
}
This way both Tailwind bg-neutral-500 and Daisy btn-neutral (for example) will work

Tailwindcss background-image not working in dark mode

I have my Tailwind classes defined like this:
<section class="dark:bg-gray-900 bg-hero-image bg-fixed">
So in the light version a background image is shown and on the dark version just gray-900 as background color.
The image is defined in tailwind.config.js like this:
theme: {
extend: {
backgroundImage: {
'hero-image': "url('/header.jpg')"
},
But this just doesn't work and still shows the image on dark mode.
You have to add backgroundImage to the variants in tailwind.config.js:
module.exports = {
variants: {
extend: {
backgroundImage: ["dark"],
},
},
ALSO you have to add dark:bg-none for the background-image to be set to none.
<section class="dark:bg-gray-900 dark:bg-none bg-hero-image bg-fixed">
This is also nessessary for things like invert and many other classes. Check the corresponding section in the docs, whether or not the variants are included by default.
By default, only responsive variants are generated for invert utilities.
https://v2.tailwindcss.com/docs/invert#variants

Tailwind cdn and isntallation npm not constistant

To quickly start learning how to use tailwind, I added CDN link to my project. Once I had understood the basics, I decided to configure tailwind with webpack.
I created everything from scratch with all the configuration files and pasted the html code from the previous attempt. When I ran the code, it turned out that the pages do not look identical, after configuring some classes are missing and some elements have different property values.
In both cases I use newest version.
Examples:
/* with cdn */
html {
line-height: 1.5;
}
body {
margin: 0;
}
.p-2\.5 {
padding: .625rem;
}
/* with configuration */
html {
line-height: 1;
}
body {
margin: 8px;
}
.p-2\.5 { /* doesn't exist */ }
My tailwind config file look like this, there is rather not many things that I can made wrong:
/* tailwind.config.js */
module.exports = {
future: {
removeDeprecatedGapUtilities: true,
purgeLayersByDefault: true,
},
purge: [
'./templates/**/*.php',
],
theme: {
extend: {},
},
variants: {},
plugins: [],
}
I also tried with file generated by command, but the result was the same - difference in both pages.
npx tailwindcss init --full
Why there are differences between CDN and configuration. Can I somehow configure my project to make it look like the one using CDN?
Using Tailwind via CDN
Before using the CDN build, please note that many of the features that make Tailwind CSS great are not available without incorporating Tailwind into your build process.
You can't customize Tailwind's default theme
You can't use any directives like #apply, #variants, etc.
You can't enable additional variants like group-focus
You can't install third-party plugins
You can't tree-shake unused styles
To get the most out of Tailwind, you really should install it as a PostCSS plugin.

How to prefix Bootstrap 4 classes to avoid css classes conflict

I am working on building small applications that will live in a website. The website that will host these applications may or may not be using a css framework. I Want to prefix all Bootstrap classes with my own unique prefix.
To avoid "ANY INSTANCE or CHANCE" of conflict I want to prefix all Bootstrap CSS classes with - let's say - "year19-" prefix. So, for example, all the col- classes would now be year19-col- and all the .btn classes would now become .year19-btn, .year19-btn-primary, etc...
I know if I use the sass theme, new classes, then we would get around some of that as we can create our own prefixes using the theming approach, but JS would still remain a source of conflict if two versions of the same framework live on the same page. There was a Github project for Bootstrap 3 with the namespacing feature where you could just add your prefix in the namespace variable then compile the entire code to a CSS and JS package. Bootstrap 4 doesn't seem to have that package yet.
Also, I don't want to wrap the project with a css class. That approach is fine for some things, but not the right approach. I wouldn't even call that namespace. That is just wrapping the classes.
year19-btn-primary {
then this would be whatever the code that already existed there before, not touched.}
I managed to get classes prefixed for Bootstrap 5.1.3. You'll need to make the following changes before compiling Bootstrap yourself. My full implementation is available here: https://github.com/Robpol86/sphinx-carousel/tree/85422a6d955024f5a39049c7c3a0271e1ee43ae4/bootstrap
package.json
"dependencies": {
"bootstrap": "5.1.3",
"postcss-prefix-selector": "1.15.0"
},
Here you'll want to add postcss-prefix-selector to make use of it in postcss.
postcss.config.js
'use strict'
const prefixer = require('postcss-prefix-selector')
const autoprefixer = require('autoprefixer')
const rtlcss = require('rtlcss')
module.exports = ctx => {
return {
map: ctx.file.dirname.includes('examples') ?
false :
{
inline: false,
annotation: true,
sourcesContent: true
},
plugins: [
prefixer({
prefix: 'scbs-', // ***REPLACE scbs- WITH YOUR PREFIX***
transform: function (prefix, selector) {
let newSelector = ''
for (let part of selector.split(/(?=[.])/g)) {
if (part.startsWith('.')) part = '.' + prefix + part.substring(1)
newSelector += part
}
return newSelector
},
}),
autoprefixer({
cascade: false
}),
ctx.env === 'RTL' ? rtlcss() : false,
]
}
}
This is where the CSS will be prefixed. I'm using postcss instead of just wrapping bootstrap.scss with a class/id selector so I can use the Bootstrap 5 carousel component on Bootstrap 4 webpages (which is my use case). This will replace https://github.com/twbs/bootstrap/blob/v5.1.3/build/postcss.config.js
rollup.config.js
// ...
const plugins = [
replace({ // ***COPY/PASTE FOR OTHER BOOTSTRAP COMPONENTS***
include: ['js/src/carousel.js'], // ***YOU MAY NEED TO REPLACE THIS PATH***
preventAssignment: true,
values: {
'CLASS_NAME_CAROUSEL': '"scbs-carousel"', // ***USE YOUR PREFIXES HERE***
'CLASS_NAME_ACTIVE': '"scbs-active"',
'CLASS_NAME_SLIDE': '"scbs-slide"',
'CLASS_NAME_END': '"scbs-carousel-item-end"',
'CLASS_NAME_START': '"scbs-carousel-item-start"',
'CLASS_NAME_NEXT': '"scbs-carousel-item-next"',
'CLASS_NAME_PREV': '"scbs-carousel-item-prev"',
'CLASS_NAME_POINTER_EVENT': '"scbs-pointer-event"',
'SELECTOR_ACTIVE': '".scbs-active"',
'SELECTOR_ACTIVE_ITEM': '".scbs-active.scbs-carousel-item"',
'SELECTOR_ITEM': '".scbs-carousel-item"',
'SELECTOR_ITEM_IMG': '".scbs-carousel-item img"',
'SELECTOR_NEXT_PREV': '".scbs-carousel-item-next, .scbs-carousel-item-prev"',
'SELECTOR_INDICATORS': '".scbs-carousel-indicators"',
}
}),
babel({
// Only transpile our source code
// ...
Lastly rollup replace plugin is used to add the prefixes in the compiled javascript file. I wasn't able to find a way to just prefix the consts so I had to resort to having the entire const replaced and hard-coded with the full class names. This means you'll need to do this for every Bootstrap component that you're including in your final build (for me I just need the carousel so it's not a big deal).

Resources