At the moment I'm working on a boilerplate based on React.js. In the assets folder I have a _mixins.scss
and _breakpoints.scss
file.
// ../assets/_breakpoints.scss
/* Small (sm) */
$screen-sm-min: 640px;
/* Medium (md) */
$screen-md-min: 768px;
/* Large (lg) */
$screen-lg-min: 1024px;
/* Extra Large (xl) */
$screen-xl-min: 1280px;
/* Two Extra Large (xxl) */
$screen-xxl-min: 1536px;
...
// ../assets/_mixins.scss
// Medium devices
@mixin md {
@media (min-width: #{$screen-md-min}) {
@content;
}
}
// Large devices
@mixin lg {
@media (min-width: #{$screen-lg-min}) {
@content;
}
}
...
I import the two .scss
files in the App.js so I can access the classes/mixins/variables global. But only the classes are accessible.
So for example using a mixin in App.scss
:
.container {
background: red;
@include md {
background: green;
}
}
You should think this would work (defining a class in the _mixins.scss
and using in the App.js
file works) but he gives the error:
SassError: no mixin named lg
Anyone who is similar with this problem and maybe can help me?
Top comments (13)
I'm sorry that I don't have a solution, but this post taught me about the
@content
feature of Sass. Thank you!Hey no problem. If have a nuxt boilerplate with the same structure as this react project: github.com/dennisfrijlink/nuxt-spa..., with the difference that it works.
The weird part of the story is, is that I can use the .css classes I define in the global .scss files in all the React Components but I can't use the global mixins/variables.
If that's the case, I'm gonna take a stab at saying that it has to do with the way that the webpack pipeline is behaving. My guess is that in the nuxt version the sass isn't being compiled until after the component styles are stripped out of the
.vue
files, but in the react version the sass from.scss
files is being compiled separately from the styles being stripped out of component files. I know that importing.scss
into Vue components without a nuxt project used to take a bit of work.Something you could try: import that global sass file right into the react component using
@import "...";
and see what happens. In previous Vue projects, I did this instead of a global include and it worked well. Obviously it's much nicer to have a single, global import statement, but this could potentially help with troubleshooting.At first I wanna thank you for your support. Hopefully we can fix it.
Even when I make a
.scss
file for theroot.js
component the child components can't use the mixins. In the .README I explain the structure of the boilerplate: github.com/dennisfrijlink/react-sp.... Maybe you can take a look? Probably I miss somethingNo problem! I'm admittedly not very familiar with most React development, but I use Sass and Vue regularly.
So what I'm suggesting for troubleshooting is: instead of relying on webpack to make your global mixins available, try explicitly importing the mixin file into the children files. So in the "For Example" snippet at the very bottom of the README, do this:
Aaah okay. So if a component needs one or more mixins, defined in
mixins.scss
, I have to import it in the local.scss
file of the component right? You maybe have an idea why only the breakpoints & mixins are not working? If I define for example a class in themain.scss
file than I can use that class in every component without importing it every time.I'm sure there is a way to avoid this in the long run, but from my experience this is at least a fairly easy way to get things working.
To answer this, it's important to consider exactly what's going on mechanically, and how CSS works without even using Sass or any pre-processors. The goal of Sass is to use a language that supports more features than CSS, run that language through a processor, and generate a plain CSS file that can be handed to a browser. A "mixin" is a feature of Sass, there is no concept of it in CSS. So when you use a mixin, the Sass compiler actually has to know about the mixin definition, which means that the compiler needs the code in your file and the mixin code which, in this case, is in a separate file. Because Webpack is responsible for running your Sass through the Sass compiler, it seems that the compiler doesn't have access to the global
mixins.scss
file while compiling all of the other.scss
files.The other code, such as plain CSS classes, are being compiled in your root scss file and served to the browser. Your components are referencing these classes using
class="my-root-class"
. This is exactly the same as going into the root of your HTML document, creating a<style>
tag, and adding some classes there. Any class loaded into the browser is available anywhere on the page because CSS itself is inherently global.The summary is that mixin problems are an issue with the compilation step (converting Sass to CSS), while using global CSS classes in any component is not related to Sass or the compilation step.
That makes sense! So if I wanna use the mixins globally I have to configure the webpack right?
That would be my guess about where the problem lies. If I'm not mistaken, doesn't the Next configuration actually have the global scss file declared somewhere? I believe this is imported into webpack's chain in a way that makes it available to the Sass compiler. So there should be some way to accomplish the same thing outside of Nuxt.
Here is an answer in Stack Overflow that's discussing this exact problem (except variables instead of mixing) stackoverflow.com/a/35554536
Alright. I will take a look at the configuration of webpack and I how I can fix the global
.scss
mixins. Thanks for your help and the explanation of sass + webpack! I will sign you if it works :)You bet, good luck!
Hey Jordan,
First of all. Thanks for your support. After searching and testing I started to use CRACO (Create React App Configuration). CRACO is an easy and comprehensible configuration layer for create-react-app based on the structure of Webpack. It kinds of overwrites the rules of webpack you specify in the
craco.config.js
file. With the plugincraco-sass-resources-loader
I managed to load a global SCSS file calledutils.scss
:In the
utils.scss
I simply import all the main SCSS files I wanna use (think of mixins, breakpoints etc.):