The issue:
Using the out-of-the-box react-scripts package included with create-react-app to build a production build of React, dynamically imported CSS files get ignored and instead all CSS seems to get compiled into the production build.
Example of what is happening:
/* styles/desktop.css */
.some-class {
background-color: white;
margin: 0;
}
/* styles/mobile.css */
.some-class {
border: 1px solid black;
margin: 1em;
}
.another-class {
background-color: black;
padding: 3px;
}
Note we are using require() with template strings as the import statement only accepts string literals and cssEnv could be any number of things which would make a conditional statement untenable.
/* config.js */
const cssEnv = 'desktop';
require(`./styles/${cssEnv}.css`);
We build our production build.
$ npm run build
In the build folder, we find our compiled CSS. Note how all our CSS files have been compiled into one (including even CSS we never imported).
/* compiledCSS.chunk.css */
.some-class {
background-color: white;
border: 1px solid black;
margin: 0;
}
.another-class {
background-color: black;
padding: 3px;
}
A similar SO question I found in Googling for a solution:
react-scripts build ignores conditional css imports
I'm immediately answering my own question because I've already solved it, but also because I had a bit of a Homer Simpson "d'oh!" moment when I finally found the solution after scouring Google and documentation far and wide. This is why I posted the question, in hopes of saving other people that time searching for a solution that wasn't super obvious (and doesn't seem to be addressed anywhere that I have found).
So I didn't realize that the import statement had a dynamic importing functionality via import(). So the solution was simply to replace require() with import().
/* config.js */
const cssEnv = 'desktop';
import(`./styles/${cssEnv}.css`);
Now when we build our production build, we get the correct compiled CSS
/* compiledCSS.chunk.css */
.some-class {
background-color: white;
margin: 0;
}
So my best guess as to what is happening is that react-scripts treats require() differently than import(), where providing a template string with variables to require() causes the variables to act like wildcards (*). So when we were building the production build earlier,
require(`./styles/${cssEnv}.css`);
got treated like
require(`./styles/*.css`);
Hence all css files in the styles folder were compiled together.
I'm not entirely sure of the intimate inner workings of what is happening here, so I wouldn't mind getting input from folks like Dan Abramov and others who might better understand what exactly is happening to clarify this.
Related
I'm a backend developer tasked withed moving a front end from a custom framework to React. (Spare a thought for me please).
I've come across CSS classes within other CSS classes such as:
content.document{
display: flex;
.important{
background-color: #FAD08A;
padding: 20px 0;
border-radius: 5px;
position: relative;
img.important{
width: 70px;
float: right;
}
h2 {
font-size: 16px;
color: #ccc;
text-align: center;
line-height: normal;
}
}
}
I have never seen this way of doing CSS and of course if I paste it into a normal CSS file, it doesn't work.
Is there a library that would all me to have CSS classes defined within other CSS classes (such as how h2 is defined in .important above)? I'd rather not have to modify tons of CSS to get this to work.
This is sass. There is sass and scss syntax. The one you have above is scss. They have .scss or .sass file-types. Sass-Variant drops the brackets and works with indents alike CoffeeScript or YAML.
Since you are using React now, you can just install a "sass" package with yarn add or npm install command. There are different versions of sass because of legacy and different environments. You can decide if you want to install it locally (per project) or globally (-g flag for npm).
Usually, I go with the package named sass. You could probably also use dart-sass. If you want to get fancy: more-details-about-sass-variants.
You can read more here: https://create-react-app.dev/docs/adding-a-sass-stylesheet/.
This tool supports sass and scss with different setups: sass playground
As Jon mentioned, it is written in SCSS. You can try to use an online tool that converts SCSS to CSS.
I'm using css modules in a create-react-app project (React V17.0.2 / React-Scripts V4.0.3). All seems well in local but the styles break in production (hosted on netlify).
I believe the problem is that the css modules are not recognizing variables I've defined globally in plain css files. Here's an example of the set up I came up with:
index.css file imported at the top level index.js in my react project:
#import '../Global/ColorScheme.css';
body {
// body styles
}
a {
// global a tag styles
}
ColorScheme.css:
:root {
--green: #00b890;
--pink: #ef767a;
--brown: #554348;
--orange: #fb8f67;
}
Then some CSS module consuming global styles from ColorScheme.css..
SomeFile.module.css
.greenBox {
background-color: var(--green);
height: 500px;
width: 500px;
border: 1px solid #333;
}
Example Component
import React from 'react';
import styles from '../somePath/SomeFile.module.css';
export default function MyComponent() {
return <div className={styles.greenBox} />;
}
When I run it locally I will get a green box with height & width at 500px with a 1px solid black border around it. So all is working as expected. However the production build will show a 500px by 500px box with 1px solid black border but no background color. I'm guessing it's the disconnect is when a css module is using a variable defined in a plain css file. Maybe something with the way webpack compiles down a create-react-app for production build?
Does anyone have any ideas as to why this might be happening and any way I can get around it? I've seen instances of global variables in css modules but I'm trying to avoid importing the global styles in every single module.
I found the solution to my own problem and originally had that solution in the OP as an edit. Moving this to 'Answer my own question' so it's more clear if someone finds this issue in the future:
I found a work around by chance, but I don't understand the 'why' or 'how'. It seems like my custom CSS properties defined in :root were working, just not the ones I titled with color names (i.e. --navy, --green, --orange, or even --gray-scale-0). After running create-react-app's standard npm run build the produced main.css file would replace my css like this:
Some CSS Module Before Build
.someClass {
color: var(--green);
background-color: var(--gray-scale-0);
}
Same Class in Main.####.chunk.css After Build
.someClass {
color: var(green);
background-color: var(gray);
}
Changing my custom properties to something like --theme-orange or --theme-green works just fine. I'm still new to webpack and preprocessors so if anyone knows why this happens I'd love to know.
You should define the variable with $ and use it also with $ without any problem =>
$green : #00b890;
.greenBox {
background-color: $green;
}
This is probably already answered somewhere so I apologize, but I couldn't find a solution for more recent versions of React and it's something I'm just very confused by.
I am running the most recent version of React and am currently creating a registration page for my app. I have a CSS file I imported with import "./RegistrationPage.css" and have also tried using import registrationCSS from "./RegistrationPage.css". Each input also has a unique id.
I am deploying my application using AWS Amplify, and my issue is the CSS is different between my dev build and production build. On my localhost the id css are affecting my page properly but className css are partially working, but when I look at my deployed page all the className css appear different than in dev. This is a big issue since I never know what my app will truly look like till I deploy it.
I included 2 images as an example.
Production Build
Dev Build
What's the fix for this?
Thanks.
Edit: I've noticed the class css property are affecting it some if I were to remove it or change it, but that shouldn't affect it from dev to prod build I wouldn't imagine, and then it's affected even different when it's deployed (font/padding/etc shown in the images). I've also gone through all my css files several times and haven't noticed any other property that I believe could be affecting it like this. The wrapper css property seems to function differently as well.
RegistrationPage.js
<Col className="registrationWrapperInfo">
<div>
<InputGroup>
<Input id="regGlow" className="registrationInputBoxes"
type="password" value={passwordCheck}
placeholder="Password..." onChange={(e) =>
setPasswordCheck(e.target.value)}/>
</InputGroup>
</div>
</Col>
RegistrationPage.css
.registrationInputBoxes {
width: 100%;
height: 100%;
margin: 5px;
font-weight: bolder;
}
#regGlow:focus {
outline: none;
box-shadow: 0 0 10px #f069ca;
border: 2px solid #f069ca;
}
.registrationWrapperInfo {
min-width: 300px;
max-height: 500px;
border-radius: 20px;
background: rgba(0,0,0,0.65);
box-sizing: border-box;
padding: 30px;
color: #fff;
margin-top: 50px;
margin-right: 30px;
margin-left: 30px;
}
I'm using Reactstrap in this project, and it just now occurred to me it could be overriding my class changes, which it turns out it was. The simple fix for my question was simply to move my bootstrap import above my index.css import in my index.js file.
I had a similar problem. First, I had corrupt CSS files that would not allow me to build the application. Second, apparently it is difficult to compile multiple imported css files from jsx files, to fix this problem I removed all imports from all jsx files and imported them once in index.js (less and css files). Third, in the folder where you save the styles, i delete all subfolders of styles, leaving all the style files in a single folder of styles. This fixed my problem, hope that helps.
I'm not sure whats happening. I'm new to Sass, so I was following this begginers guide: https://scotch.io/tutorials/getting-started-with-sass
For practicing (and hoping to use it as my developing tool) I set LiveReload to compile .scss files. But when testing the variable scope I got unexpected results.
In style.scss I have the following code:
$primaryColor: #eeccff;
body {
$primaryColor: #ccc;
background: $primaryColor;
}
p {
color: $primaryColor;
}
// When compiled, our paragraph selector's color is #eeccff
So p is supposed to get color: #eeccff. But this is what I'm getting:
body {
background: #cccccc; }
p {
color: #cccccc; }
I tested the same code in sassmeister.com and it worked as expected, just like the tutorial says:
body {
background: #ccc;
}
p {
color: #eeccff;
}
Again, I'm using LiveReload for Mac. And these are the compiling options:
Does anyone has an idea of why is this happening?
Thanks!
EDIT:
I found this question where someone was experiencing a very similar problem in a different situation: Web Essential for Visual Studio Sass compile wrong
Apparently it has to do with the Sass version you use. But how do I change that for LiveReload? How you change that?
Well, I just changed from Sass compiler. I had to stop using LiveReload and compile with Koala to have the expected results. Couldn't manage to change LiveReload Sass gem.
I'm running into problems with WordPress style.css files when trying to use then as .styl -files. The style.css from twentytwelve is the only one so far that works when I just change it from .css to .styl.
So for example when I copy-paste the style.css from theme twentyeleven or Nimble by ElegantThemes to a .styl -file, it won't compile and I get an error from CodeKit:
ParseError: /Applications/MAMP/htdocs/test/wp-content/themes/twentytwelve-child/style.styl:1454
1450| }
1451| article.feature-image.small .entry-summary p a {
1452| background: #222;
1453| color: #eee;
> 1454| display: block;
1455| left: -23.8%;
1456| padding: 9px 26px 9px 85px;
1457| position: relative;
expected "indent", got ";"
If I delete all the CSS from around it, the error just jumps to a different line of code.
I also get similar errors if I use css2stylus.com to make Stylus from CSS.
So for you people wiser than me:
How would one go about debugging Stylus? Is there a smart method for that? What if it's just copy-pasted CSS, and what if it's been compiled to .styl?
Any way to just make the style.css -files work by not compiling, other than loading separate files using one made with Stylus and the original CSS?
Do you think that this kind of problems are less likely to happen with i.e. SASS?
So for anyone using Stylus with WordPress, it would be very nice to share some thoughs!
Thank you very much.