How to customise Bulma variables via Nuxt/Buefy? - sass

How can I customise Bulma variables when using Nuxt and Buefy?
It seems Nuxt is loading Bulma/Buefy before it loads my Sass vars, where I set my custom values.
nuxt.config.js:
export default {
target: 'static',
head: {},
css: [
'~/assets/bulma-vars.sass'
],
plugins: [],
components: true,
buildModules: [
'#nuxt/typescript-build',
],
modules: [
['nuxt-buefy', {css: true}],
],
build: {}
}
bulma-vars.sass:
$danger: orange
How can I set my vars before Bulma/Buefy is initiated?
[--- UPDATE ---]
Following #kissu's idea of doing this via a plugin, I set to work on this.
nuxt.config.js:
plugins: [
'~/plugins/set-bulma-vars.js'
],
plugins/set-bulma-vars.js
#import '~/assets/set-bulma-vars.sass'
assets/set-bulma-vars.sass
$danger: #00f
...but it doesn't seem to the variables in a scope such that Bulma can inherit them, and subsequently my vars are ignored (though the plugin CSS is loaded.)
So the only way I've solved this so far is via my own answer, below.

I have created a /assets/scss/custom_buefy.scss file with variables like this
#import "~bulma/sass/utilities/_all";
// the line above is important
$primary: hsl(168, 59%, 47%);
$link: hsl(24, 94%, 66%);
$info: hsl(200, 100%, 75%);
...
To customize our application.
Then created a /plugins/vue-buefy.js file to import it
import '~/assets/scss/custom_buefy.scss'
And then, imported it into our nuxt.config.js file
plugins: [
{ src: '#/plugins/vue-buefy', mode: 'client' },
],
Working good so far. Maybe not the best configuration, but flexible enough for customizing the CSS and also importing some specific components on demand (and not the whole library).
My starting point was not the CLI tho (I do use the buefy package), so YMMV.

In the end, this is what I did.
First, disable auto-loading of Buefy in nuxt.config.js > modules:
modules: [
['nuxt-buefy', {css: false}],
]
This solves the problem of Buefy (and Bulma) loading before we have chance to set any theme variables.
Next, create a Sass file e.g. bulma-vars.css:
$danger: orange
#import "~bulma/bulma"
#import "~buefy/src/scss/buefy"
(~bulma/bulma and ~buefy/src/scss/buefy are the relative paths to the main Bulma Sass file and Buefy SCSS file, respectively, within node_modules.)
Add this to nuxt.config.js > css:
css: [
'~/assets/bulma-vars.sass'
]
There's probably better ways (I've seen references to doing this via the Nuxt style-resources module, or via a custom plugin - see #kissu's answer) but this at least works.

Related

Configure SASS Load Path in Nuxt 3

I have my SCSS partials in my Nuxt 3 project's assets/css directory (e.g. assets/css/_cards.scss). I can import them in my components using the full path (#use '~/assets/css/cards';), but I'm having trouble getting the load path working so that I can import like #use 'cards';
From what I've seen, the Nuxt config should look like this to enable that, but this and similar variations are not working for me.
export default defineNuxtConfig({
vite: {
css: {
preprocessorOptions: {
scss: {
loadPaths: ['#/assets/css'],
},
},
},
},
});
This approach is not working for me either. However, my use case is that I wanted some global styles imported, as opposed to every component on its own.
What worked for me was to use css property directly inside defineNuxtConfig object.
export default defineNuxtConfig({
css: ["#/assets/css/_variables.scss"]
});
The correct key to use is includePaths which is documented here. I tried this key before, but the reason it did not work was that I used #/assets/css for the path. The # alias does not work in this option, so I needed to use ./assets/css for the path. Here is the corrected config:
export default defineNuxtConfig({
vite: {
css: {
preprocessorOptions: {
scss: {
includePaths: ['./assets/css'],
},
},
},
},
});

Tailwind + Jekyll: including partial css files doesn't work?

I'm trying to migrate from the now dead Tachyons framework to Tailwindcss. However, there's one block I haven't figured out how to overcome.
I use the jekyll-postscss Gem to enable postscss processing during jekyll build. Things appear to work well with the following setup:
assets/css/styles.css:
---
---
#import "tailwindcss/base";
#import "tailwindcss/components";
#import "tailwindcss/utilities";
postcss.config.js:
module.exports = {
parser: 'postcss-scss',
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
...(process.env.JEKYLL_ENV == "production"
? [require('cssnano')({ preset: 'default' })]
: [])
]
};
tailwind.config.js:
module.exports = {
purge: [
'./_includes/**/*.html',
'./_layouts/**/*.html',
'./_posts/*.md',
'./*.html',
],
darkMode: false,
theme: {
extend: {},
},
variants: {},
plugins: [
require('#tailwindcss/typography'),
],
}
With a jekyll build command, I can see the correctly generated styles.css file under _site/assets/css.
However, it doesn't work when I try to import other css or scss files. For example, if I modify the styles.css file into the following
assets/css/styles.scss:
---
---
#import "tailwindcss/base";
#import "tailwindcss/components";
#import "tailwindcss/utilities";
#import "test.css"
where test.css is in the same directory as styles.scss (assets/css/), postcss-import throws an exception
Error: Failed to find './test.css'
in [
/project
]
at /project/node_modules/postcss-import/lib/resolve-id.js:35:13
at async LazyResult.runAsync (/project/node_modules/postcss/lib/lazy-result.js:396:11)
I'm a bit confused as to why postcss-import does not see this file.
Because the css resource you imported is not in the resolved path, the default resolved path includes: root directory, node_modules, etc. Other paths can refer to the official documentation link.
You can try the following methods to solve this problem:
Modify the postcss configuration file postcss.config.js
module.exports = {
...
require('postcss-import')({
addModulesDirectories: ["assets/css"]
}),
...
};
Modify the main style file assets/css/styles.css
#import "assets/css/test.css"
I used a similar solution to what Donnie suggests, but I set the path instead of the addModulesDirectories, which resolved the issue for me. I didn't try the addModulesDirectories, so I don't know whether that might have also worked.
module.exports = {
...
require('postcss-import')({
path: ["assets/css"]
}),
...
};

Sapper - imported scss styles disappear

I have a strange problem which may be related toe tree-shaking. I build a sapper app and in my rollup config, I use the svelte-preprocess package and configure it like this:
const preprocessOptions = {
scss: {
data: `#import '${join(process.cwd(), "src/styles/main.scss")}';`,
includePaths: ["node_modules", "src"],
},
postcss: {
plugins: [
require("autoprefixer"),
require("cssnano")({
preset: "default",
}),
],
minimize: !isDevelopment,
sourceMap: isDevelopment,
},
};
Via the scss plugin I copy the global stylesheet main.scss. All of the styles out of it seem to get applied, except for the styles of the body. Somehow these get ignored, because when I check the body styles in the dev console, it is empty. Can't you access the body in Sapper or is there maybe a special way to do this?
The problem is that with Sapper the body is part of the template.html file. That means there's no component with a body element. Svelte will remove styles that are not used in your component unless they are explicitly marked as global. The global preprocessor can help with this. I think in your case I would just get the bundler to create a separate css file for the template.html and include it explicitly like the global.css:
...
%sapper.base%
<link rel='stylesheet' href='global.css'>
...

Gatsby fails after using Sass files with '#use 'sass:color'

I'm setting up a Gatsby Project with gatsby-plugin-sass.
my gatsby-config.js file:
module.exports = {
plugins: [
'gatsby-plugin-resolve-src',
'gatsby-plugin-sass',
'gatsby-plugin-react-helmet',
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/assets/images`,
},
},
],
}
I have the following styles file structure:
|
|src
|-styles
|--base
|--- _variables.scss
|--components
|--- _Buttons.scss
|--- ...
|--main.scss
Im my _Buttons.scss file I'm importing like this:
#import '../base/variables';
#use 'sass:color as *;
When I'm trying to use the sass color functions like this (as specified on https://sass-lang.com/documentation/modules)
%buttons-focus {
background-color: color.adjust($primary-color, $alpha: -0.5);
}
I get the following Error:
Invalid CSS after "...nd-color: color": expected expression (e.g. 1px, bold), was ".adjust($primary-co"
In my main.scss I'm importing styles like this:
#import './components/Buttons';
Am I overseeing something?
I've tried changing up #use with #import, with no luck. For me it seems like the gatsby-sass-plugin is not aware of sass modules.
gatsby-plugin-sass uses node-sass under the hood. But in order to support built-in modules with #use, you need to configure gatsby-plugin-sass to use dart-sass instead. See below.
Built-In Modules - sass-lang
Only Dart Sass currently supports loading built-in modules with #use. Users of other implementations must call functions using their global names instead.
Alternative Sass Implementations - gatsby-plugin-sass
By default the node implementation of Sass (node-sass) is used. To use the implementation written in Dart (dart-sass), you can install sass instead of node-sass and pass it into the options as the implementation:
npm install --save-dev sass
gatsby-config.js
plugins: [
{
resolve: `gatsby-plugin-sass`,
options: {
implementation: require("sass"),
},
},
]

Importing external stylesheets globally with CSS modules

I'm struggling to add SASS with an external stylesheet (Bulma) to my React application. So far I have set up Parcel with CSS modules via postcss. This is my .postcssrc config:
{
"modules": true,
"plugins": {
"autoprefixer": {
"grid": true
},
"postcss-modules": {
"generateScopedName": "[name]_[local]_[hash:base64:5]"
}
}
}
I have installed node-sass and successfully added a .scss file to one of my components. External (Bulma) styles are added via #import "~bulma/bulma"; and are correctly resolved.
Unfortunately, imported styles are not applied globally and instead the class names are modified similarly to local definitions, e.g.:
/*! bulma.io v0.8.0 | MIT License | github.com/jgthms/bulma */
#-webkit-keyframes container_spinAround_28_Bz {
from {
transform: rotate(0deg); }
to {
transform: rotate(359deg); } }
#keyframes container_spinAround_28_Bz {
from {
transform: rotate(0deg); }
to {
transform: rotate(359deg); } }
Note the added prefixes and suffixes.
Ideally, I would like to import the stylesheet globally and do not modify their names. I'd like to continue using CSS modules and I think I also have to use SASS in order to globally modify Bulma stylesheet by overriding SASS variables.
Anyway, things I've tried so far:
Using postcss-nested and wrapping the import with :global block:
:global {
#import "~bulma/bulma";
}
However, this throws an exception:
main.scss:5018:5: Missing whitespace before :global
Creating a separate scss file included directly in HTML file via <link> rather than imported in a jsx/tsx file to avoid using CSS modules.
This seems to break Parcel entirely, as it fails to link correct files in the compiled HTML files, i.e. <LONG-HASH>.css instead of generated main.<HASH>.css.
Using postcss-import.
Either my setup is incorrect or it has no effect on SASS files.
You can define regular expressions to mark matched files as global stylesheets with the globalModulePaths setting.
"postcss-modules": {
"globalModulePaths": [
".*\\.global\\..*"
]
}
The example above would mark all files with .global. in their name, e.g. main.global.css.
Managed to figure it out while writing the question.
The only solution that worked for me to load global CSS styles from rollup (when applying preserveModules: true) was using the 'rollup-plugin-styles' plugin and the following configuration:
// rollup.config.js
plugins: [
styles({
extensions: ['.css'],
use: ['css'],
}), …
]
// In the package.json you have to add the proper side effects
{
"sideEffects": [
"**/*.css",
"**/*.css.js" //this one is very important too
],
}
// MyComponent.tx
import '../styles/myGlobal.css';

Resources