PurgeCSS and Markdown output, how to whitelist element selectors? - css

starting to use tailwindcss i was soon confronted with the need for PurgeCSS in order to wipe of (a lot of) superfluous css from my stylesheets. Next to being a great tool in general, PurgeCSS can become a cat-and-mouse-game for wanted and unwanted selectors, especially after deploying tree-shaken-minified-nano-purged production code.
In order to prevent PurgeCSS from being to tidy it has some possibilities to whitelist selectors from being purged: using whitelist, whitelistPatterns, whitelistPatternsChildren or /* purgecss start and stop ignore */ directly in stylesheets.
Usually i'd protect some selectors regexp in the options and some whole imported stylesheets by comments (see example below). But especially selectors which have been created dynamically such as Markdown converted to HTML. All the <p>, <blockquote>, <h1>, <h2>, <a>, … would be purged because they have not been present in the .md files.
This concerns mostly element selectors, so: is there a way or a regexp to whitelist all selectors which are not a class?
I tried some regexp for whitelistPatterns, like ^(?!\.).+, ^(?!\.)\w+, …, but they either did not work or whitelisted all selectors, including classes.
Thanks for any help.
// postcss.config.js
const whitelist = /^(\.|p|ul|ol|h\d+|pre|code|carousel|flickity|spinner)/
const purgecss = require("#fullhuman/postcss-purgecss")({
// …
whitelistPatterns: [whitelist],
whitelistPatternsChildren: [whitelist]
});
// styles.css
/*! purgecss start ignore */
#import "admin.css";
/*! purgecss end ignore */

Tailwind runs a pretty forgiving purge by default, as mentioned here. Keeping the default works for me, but if I configure purge mode "all", I start to lose styles exactly as you describe - Because the elements don't appear in my Markdown files.
To fix this, you can pass a list of whitelisted elements through to PurgeCSS from your Tailwind config file.
First, make sure you are using the optional configuration file:
npx tailwindcss init
You can then configure it something like below. Here, I am using the more aggressive purge but also whitelisting specific elements. Here's an example which parses 11ty layouts:
module.exports = {
// Purge is executed only when NODE_ENV=production
purge: {
mode: 'all',
content: [
'site/_includes/**/*.njk'
],
options: {
whitelist: [
'body',
'html',
'a',
'h1',
'h2',
'h3',
'h4',
'p'
]
}
},
theme: {
extend: {},
},
variants: {},
plugins: [],
}

Related

How to configure minimum development environment for Tailwindcss v3 to utilize #import

The goal is to configure a development environment for Tailwindcss v3 that supports #import and the removal of unused custom CSS classes.
I am not using a bundler. The project depends on just HTML, CSS, and JS i.e. no frameworks. If it's important, I use VS Code.
This is what I've tried.
Project's configuration:
// tailwind.config.js
const defaultTheme = require('tailwindcss/defaultTheme');
module.exports = {
content: [
'./src/**/*.{html,js}',
],
darkMode: 'media',
theme: {
extend: {
fontFamily: {
primary: '"Inter", sans-serif',
mono: ['"DM Mono"', ...defaultTheme.fontFamily.mono]
}
},
},
variants: {
extend: {}
},
plugins: [
// ...
]
};
// postcss.config.js
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
require('cssnano')
]
/* styles.css*/
#import "tailwindcss/base";
#import "./custom-base-styles.css";
#import "tailwindcss/components";
#import "./custom-components.css";
#import "tailwindcss/utilities";
#import "./custom-utilities.css";
And this is my commend line:
$ npx tailwindcss -i ./src/css/styles.css -o ./css/styles.css --watch
Running just the above command, the setup does not inline the custom*.css files.
To achieve inlining, I also have to execute below, which on the surface, seems as if it should not be necessary.
$ npx postcss-cli './src/css/styles.css' -o './css/styles.css' -w
The end result is, Tailwindcss is not removing my unused custom styles, even when wrapped in the required #layer {}.
Step 5 here (Using PostCSS) just says to start your build process and does not offer any details.
Step 4 here (Tailwind CLI) only says to start the Tailwind CLI process.
So, what am I missing?
Do I need to use a bundler? If so, my preferred one is Rollup.
Other details:
autoprefixer:^10.4.0
cssnano:^5.0.10
postcss-cli:^9.0.2
postcss-import:^14.0.2
tailwindcss: "^3.0.7
Your intuition is correct. You do not need to run post-cli. PostCSS will execute once you update your Tailwind command.
You are missing the --postcss parameter.
Assuming that postcss.config.js is in your project's root, copy this to the script section of your package.json:
"tw": "tailwindcss -i ./src/css/styles.css -o ./css/styles.css --postcss postcss.config.js --watch"
Then from the command line at the project's root, run:
npm run tw
Note: with the above command, Tailwind will not rebuild the output file after the HTML file has been saved. You'll need to edit and save one of the CSS source files to initiate a rebuild. (Perhaps I still have a configuration problem?)
One other item, how are you testing for the removal of unused custom classes?
The mistake I made was just commenting out the HTML utilizing the custom class and then looking at the CSS output to see if the class was removed. But Tailwind (as documented somewhere) won't remove a class if the class appears anywhere in the markup, even in a commented line. If you're testing your build process, rename the class in the markup to anything, and then Tailwind will drop the custom class from the CSS output.

TailwindCSS + NextJS: Integrating with PostCSS and IE11 support (custom properties)

According to the docs, tailwind states it supports ie11.
...yet it uses custom properties that are not supported by ie11.
We're attempting to use this in a minimal nextjs project with the following postcss.config.js:
module.exports = {
plugins: [
'postcss-import',
'tailwindcss',
'autoprefixer',
['postcss-custom-properties', { preserve: false }]
]
};
The only css file we're importing:
#import 'tailwindcss/base';
#import 'tailwindcss/components';
#import 'tailwindcss/utilities';
The line ['postcss-custom-properties', { preserve: false }] appears to not be doing anything. Both with the defaults and that one.
Obviously, since ie 11 doesn't support custom properties, stuff like the transform utility are completely ignored.
Anyone have any suggestions for this? I've been spending way too much time on trying to get this to work :|
I'm still experimenting which is the best value but the target attribute in your postcss.config.js is the responsible, set it to ie11 and all the custom css properties will be removed.
The target property isn't documented but I've found this issue explaining the situation. If you are using browserlist, try using
module.exports = {
target: 'browserslist',
}

Add hash to images in css webpack

Is there a way to add hash values to images that are referenced in CSS when you compile using Webpack?
I'm using React, and have separate scss files for each component file (e.g header.js & header.scss). Within some of the scss files, I have a background image. However, my server has super high caching levels, and is caching the images within the compiled css files.
What I'd like to do is, during the css compilation, add a hash value to each image reference, which would update on every build. So for example, it would compile to this:
.background-class {
background-image: url('images/my-image.jpg?0adg83af0');
}
I've tried to use the url-loader, but because these images aren't being referenced in the JS files, I don't think they're being picked up?
I ended up using a combination of PostCSS and PostCSS CacheBuster. If anyone wants to add this to their webpack setup, you need to run npm i postcss-loader postcss-cachebuster, then in your webpack.config.js, add const PostCssCacheBuster = require('postcss-cachebuster'); to the top of your file, and add the following loader config in between css-loader and sass-loader (obviously if you use this setup):
loader: 'postcss-loader',
options: {
sourceMap: true,
plugins: () => [
PostCssCacheBuster({
imagesPath: "/src/Frontend",
cssPath: "/" + distributionPath,
supportedProps: [
'background',
'background-image'
],
paramName: 'v='
})
]
}
},

How to use SASS to rewrite custom CSS methods from an external Vue module?

I'm using a third-party module in our Vue project called vue-cal, which is for rendering a calendar. You can customise how your date cells look and such, using their custom css like this.
<style>
.vuecal--month-view .vuecal__cell-content {justify-content: flex-start;}
.vuecal__cell.selected {background-color: red;}
</style>
However, we use sass for our project, and I tried rewriting it like below but now the <style> isn't being applied at all. How can I rewrite this in sass correctly, or is there no way to rewrite external libraries' custom methods like these in non-css syntax?
<style lang="sass" scoped>
.vuecal--month-view
.vuecal__cell-content
justify-content: flex-start
.vuecal__cell.selected
background-color: red
</style>
Sorry if this is a basic question - still a beginner to Vue, CSS and front-end in general.
[EDIT] Forgot to mention an important detail. We already use sass-loader#7.1.0, and I've already written some other code in sass for other components. Those are being rendered fine. That's why I'm wondering if it has to do with vue-cal-specific methods.
You need to use vue-loader to pre-process the SASS into native CSS
Step 1:
npm install -D sass-loader sass
Step 2, in your webpack config file, make sure to have:
module.exports = {
module: {
rules: [
// ... other rules omitted
// this will apply to both plain `.scss` files
// AND `<style lang="scss">` blocks in `.vue` files
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
]
}
]
},
// plugin omitted
}
This is the barebones needed. For further information see:
vue-loader documentation
[SOLVED]
It turned out that the problem was not sass, but the fact that the style was scoped. Scoped styles are only applied to the component itself, but vue-cal is an external module so the styles weren't applied. Removing scoped immediately fixed the issue.

Tailwind Grid Plugin Not Installing

I'm new to Tailwind CSS and I'm having some trouble trying to implement the CSS Grid Plugin available here: https://www.npmjs.com/package/tailwindcss-grid
I was able to run the install through Gulp and get the package in place. It is sitting in my node-modules folder. I then tried adding the plugin to my plugins code block in the tailwind.js file:
plugins: [
require('tailwindcss/plugins/container')({
// center: true,
// padding: '1rem',
}),
require('tailwindcss-grid/index.js')({
grids: [12],
gaps: {
0: '0'
},
variants: ['responsive'],
}),
require('tailwindcss-object-fit/index.js')(['responsive']),
require('tailwindcss-object-position/index.js')(['responsive'])
],
When I make changes to my css and tailwind processes the css file, it doesn't return any errors, but when I look at the CSS output, none of the utilities for the CSS frid or the object fit and position plugins are being output to the file. Like I said, I'm new to Tailwind, so can anyone tell me what I'm missing? I'm not what I'm doing wrong with the plugin import.
Nevermind. I sorted it out. I don't think it had actually processed the style sheet yet. The styles are there now though.

Resources