CSS Modules Breaking in Production with Create React App - 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;
}

Related

CRA - React production build with dynamic CSS imports

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.

How can i apply CSS to components in VAADIN 8

I am trying to apply CSS to Vaadin 8 component. I have followed this example and still unable to apply CSS. I understand that i can call the addStyleName method and i am able to apply the build in ValoTheme styles (for example ValoTheme.PANEL_BORDERLESS does make a button smaller), but my custom styles are ignored. I have tried defining my custom CSS rules in the following files:
/src/Main/webapp/VAADIN/themes/apptheme/styles.css
#import "../reindeer/styles.css";
.mystyle {
color: red;
background: #012345;
background-color: #012345;
}
Then in Java i create a button:
Button btn = new Button(" Test ");
btn.addStyleName("mystyle");
My custom style does not get applied to the button. I suspect that i am not defining CSS correctly. Please share your knowledge of how to do this correctly in Vaadin 8.
This is not related, but are you actually using a reindeer theme?
Otherwise, you should put you styles in your own theme file (the default one generated from an archetype is mytheme.scss)
It's suggested to leave styles.scss as it is. Also, it's mentioned in comments section of the file:
This file prefixes all rules with the theme name to avoid causing conflicts with other themes. The actual styles should be defined in mytheme.scss
If you want, you could add your styles there as well under
.mytheme {
#include addons;
#include mytheme;
.testStyle{
color: red;
background: #012345;
background-color: #012345;
}
}
While it works, I will still suggest to add them to your custom scss file (Based on your folder name it is apptheme.scss)
Mine mytheme.scss looks like this:
#import "../valo/valo.scss";
#mixin mytheme {
#include valo;
.testStyle{
color: red;
background: #012345;
background-color: #012345;
}
}
After styles are applied, button looks like this:
Style files are located under webapp/VAADIN/themes/mytheme

Toggle scss variable file

I am trying to make a toggle between night mode and day mode only by changing colors. I have some base color variables inside my _colors.scss, and they are used all over my site. I use React to toggle a className between 'night-mode' and 'day-mode' at the first div of the project.
I have tried to wrap the variables in the mentioned class names, but the result is that no other files can access the variables. Therefore I was hoping for a solution where I can use a night-mode file and a day-time file and toggle between them.
As I see it now, the issue is that I can't wrap the $variables or the #import in a class name, which makes it difficult to know what mode is selected. I am looking for a solution that does not include jQuery (I have a variable globally stored that can be used for javascript reference if that ends up to be the best solution).
You can't toggle scss files at runtime, since they are already compiled to css.
I would go with CSS custom properties (sometimes called CSS variables) instead of pure Sass variables.
Example:
:root {
--background: lightblue;
}
.night-mode {
--background: darkblue;
}
.component {
background-color: var(--background);
}
Toggle the class .night-mode on with javascript depending on the time of day.
You may of course feed your CSS custom properties from Sass variables in your scss files:
$bg-day: lightblue;
$bg-night: darkblue;
:root {
--background: $bg-day;
}
.night-mode {
-- background: $bg-night;
}
.component {
background-color: var(--background);
}

React Toolbox Components are Huge

I'm playing around with React Toolbox and I've noticed (not that you'll miss it) that the components are rendering really big. Here's an example:
I'm sure that that can't be correct, that toolbar's height is pretty big and those checkboxes.. well.. Is there something that I'm missing? This is the first time using React Toolbox.
I'm not sure if this might have something to do with the Layout component? You can check it out in the documentation here. It goes on to describe how it has all these fancy breakpoints, but I have no idea how to actually implement and work with them?
"Is there something that I'm missing?"
No, nothing to worry :)
You're just seeing the default styles of the react-toolbox components as they are defined in the package.
Take a look inside node_modules/react-toolbox/lib/. Your sass-loader in webpack.config.js compiles and injects those styles (because node_modules is not excluded explicitly).
But of course you can OVERRIDE these default styles by defining your own .scss or .css files in your project.
All component's in react-toolbox accepts a property className.
ie you can do
styles.css (go with .scss if you like that more)
.myCustomInput {
font-size: 10px;
height: 12px;
background-color: #ccc;
padding: 3px 5px;
}
AddToDo.js
import { Input } from 'react-toolbox';
import styles from './styles.css';
...
<Input className={styles.myCustomInput} />

Semantic UI - change component styles (override components css)

I'm trying to change the style of some semantic ui components. I've created a css file and I've been changing the parameters there. Then I noticed that all component css files (in Semantic UI folder) have the following code at the end:
/*******************************
Theme Overrides
*******************************/
/*******************************
Site Overrides
*******************************/
I've copy pasted the code from my css file to the bottom of the component css file but the styles were not updated/overrided. I tried to use !important but it didn't worked either.
I've tried something like this:
/*******************************
Theme Overrides
*******************************/
.ui.header {
border: solid red; !important
border-width: 2px; !important
}
I was expecting this element to get a red border around it
<div class="ui small header">This is a header</div>
Any idea why it didn't worked ?
You need to add your overriding CSS styles in src/site/elements/header.overrides file and run gulp build command.
If "gulp watch" is already running, then it will automatically run build task on detecting changes in the aforementioned file.
The src/site folder is present to override any style introduced by the selected theme.
Try including '!important' within ';' in your code like this,
.ui.header {
border: solid red !important;
border-width: 2px !important;
}
Another possible solution would be to nest all your application's less styling under a unique id, used at the root element of your app.
for example in my own case:
#__next {
.is-pink {
color: pink
}
.mb-70 {
margin-bottom: 70px !important;
}
}

Resources