TailwindCSS + NextJS: Integrating with PostCSS and IE11 support (custom properties) - next.js

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',
}

Related

PurgeCSS and Markdown output, how to whitelist element selectors?

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: [],
}

Why Webpack's sass-loader is minimizing CSS in production mode?

I was setting the Webpack loaders config for .css and .scss files, I noticed that when using --mode production I'm getting minimized CSS as the final output without even using a minimizer explicitly, here's my loaders config:
{
// Match .css or .scss
test: /\.s?css$/,
use: [
isProd
// In production extract the CSS into separate files
? {
loader: MiniCssExtractPlugin.loader,
options: {
hmr: !isProd
}
}
// In development inject the styles into the DOM
: 'style-loader',
{
loader: 'css-loader'
},
{
loader: 'sass-loader',
options: {
sourceMap: false
}
}
]
}
I'm using sass-loader with node-sass and mini-css-extract-plugin to extract the CSS into separate files, which suggests using optimize-css-assets-webpack-plugin for minimizing the CSS by overriding optimization.minimizer, but I'm already getting minimized output without installing this plugin.
To find what's causing this behavior I tried processing CSS files with and without sass-loader and I found out that sass-loader might be causing this behavior but it doesn't have any option for minimizing the CSS.
So what's causing this behavior? And do I even still need optimize-css-assets-webpack-plugin if my CSS files are minimized?
Option outputStyle in sass-loader options determines the output format of the final CSS style. Default: nested.
For more detailed https://github.com/sass/node-sass#outputstyle
To disable minification, set this option to expanded:
{
loader: 'sass-loader',
options: {
sassOptions: {
outputStyle: 'expanded'
}
}
}
For minify css i reccomend plugin css-nano. It is flexible in settings. It's good work with postcss-loader.
According to the webpack docs,
webpack v4+ will minify your code by default in production mode.
So it's not sass-loader doing the minification, it's just that removing that means webpack isn't processing your SCSS into CSS and therefore not creating a file to be minified.
I'd say if you're happy with simple minification the default is probably fine for production. Other tools might give you more control over the final output including things like source maps, removing duplicate rules, dumping old prefixes, etc.

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.

sass with create react app

Can someone please tell me if it is worth using Sass/SCSS with React?
I finally set up SCSS to work with Create-React-App without ejecting, but it doesn't seem to work well since it is recommended to use CSS modules with each component.
How would I go about sharing variables, mixins, etc. Is it better just to use CSS?
Any help would be greatly appreciated.
The 2. version of create-react-app supports Sass now. Install node-sass (e.g. npm install node-sass) to enable it. For further instructions, check out the documentation. If you need an example, check out this application's Navigation component.
I highly recommend using scss, as you can still use CSS-Modules with SCSS.
I'm not familiar with the create react app setup, but usually you'd configure webpack with style-loaders like so:
{
test: /\.scss$/,
loaders: [
'style-loader',
{ loader: 'css-loader', options: { modules: true } },
'sass-loader',
],
exclude: [srcDir + '/assets/scss/']
},
The loaders will execute backwards, starting with the sass-loader which will transpile your scss to normal css, then with the css-loader and the option "modules: true" these styles will be made available to use as modules.
Of course it could look a bit different but that would be the basic approach to use css modules with scss.
To share variables and mixins I always use a global scss file, which will be required in the app (e.g. in the app.js). However you'll still have to import that file/s in every component-scss where you need the variables and mixins.
// GLOBAL STYLES
{
test: /\.scss$/,
loaders: [
'style-loader',
'css-loader',
'sass-loader',
],
include: [srcDir + '/assets/scss/']
},
Alternatively you could use PostCSS-Properties to make your components even more flexible (e.g. to provide different themes for your app, without explicitly importing the files in your component styles) but afaik those are not supported by IE and would require you to add specific postcss loaders.
see http://cssnext.io/features/#custom-properties-var
The flexibility and maintainability that SASS provides is very useful for big projects especially with react.
However, don't let yourself be influenced by my or the opinion of others - you're free to use the things you're most comfortable with and should always question the way things are done.
create-react-app V2 corresponding section doc: (support out of the box)
https://facebook.github.io/create-react-app/docs/adding-a-sass-stylesheet#docsNav
Using Sass/SCSS is pretty much completely unlinked to React. Sass is compiled to regular CSS, and then you use it as such within your HTML or React.
As for sharing variables, when you use #import it basically just takes everything from the file your importing and pastes it in, so you could just make a _variables.sccs file and import it into each file where you want to use your global variables.
//variables.scss
$primary: red;
$secondary: blue;
//main.scss
#import 'variables';
body {
background-color: $primary;
color: $secondary;
}

Resources