Webpack bundles CSS in the wrong order - javascript

At the moment, my webpack is bundling my CSS styles like this:
//this css is going first, it's supposed to go last
.rbc-btn {
color: red;
}
//this css must be first
.myStyle {
color: green;
}
What I want is to bundle my CSS styles in a specific order, something like this:
.myStyle {
color: green;
}
.rbc-btn {
color: red;
}
How can I fix this with webpack?
Thanks! :)

There was a similar bug that was fixed with extract-text-webpack-plugin#3.0.0, ensure you're using the same version or newer.
If that doesn't help, a common mistake is to load a component first and then loading the CSS files. It has become a common pattern to make every component to import their own styles which can change the style order in webpack if your component is loaded first.
Considering you have index.js like this:
import MyApp from './myApp'
import './myStyle.css'
It means to Webpack that every style imported in './myApp' will be loaded first, so styles applied 'myStyle.css' will appear below other styles, thus overriding them.
The fix could potentially be just changing orders
import './myStyle.css' // parent component imports style first
import MyApp from './myApp' // imports your component along with any other styles

Adding on to Cezar Augusto's answer:
If you have module.css, the import order of the components whose module.css is being bundled together will impact the order!
So for me I needed #import for fonts in my css to be bundled on top first, so in my index.js file, I needed to import my module.css file with my #import first before importing my components whose module.css needed to be bundled later.

Related

How to Prevent Css applying to other Files?

In this React Component I have Cookbook.js and Cookbook.css. I have a bunch of styles in Cookbook.css and specifically it has
form {
display: inline-block !important;
padding-top: 30px;
margin-left: 100px;
}
Which is fine since I import that into the Cookbook.js. But I created another Component called Survey.js along with Survey.css. In Survey.js I use a form as well but I ONLY import survey.css. Yet for some reason, The CSS from Cookbook.css gets applied to the form in my Survey.js. As a result, my form on Survey.js is in a odd spot. How Can I ensure that the css for each form is independent of each other?
When you create CSS rules, it is often easier to use class names instead of id's. Such as:
.class {
background-color: blue;
}
When you have common elements across multiple components, the CSS color will apply the styling to all elements such as:
p {
background-color: blue;
}
If you want to differentiate the styling where it applies in one component but does not apply to another which I think you are trying to do in your case, you need to use id's instead of element or class names.
Add an id to the component that you want to style and create a rule for that element such as:
#hero {
background-color: bluel;
}
This should be able to ensure that CSS is different from each other.
I think that you are looking for CSS modules. CSS modules are CSS files that only apply to a single component. Here is an example: https://css-tricks.com/css-modules-part-1-need/. More about CSS modules can also be found on Google and other forums.
Thank you,
Caiden Sanders.
In React when a component is mounted, its specific CSS file is also imported. You should know that React makes only a single HTML page application. In one HTML page if you import multiple CSS files and if they have conflicting CSS, then CSS will be applied on the basis of priority.
CSS that comes last overrides existing if common elements conflicting unless you haven't used !important with any property.
So, you should use unique ids or classes to prevent conflicts wherever required, and use common CSS if you have similar behaviour for certain elements.

Apply CSS theme based on react state

I have a REACT application (bootstrapped with create react app and react-bootstrap) for which I am trying to add option to switch to DARK theme if user enabled this in his settings. I am storing the settings on server and fetching them into properties.
I have a separate stylesheet called dark.css where all my component styles are overriden.
dark.css (example):
#root {
background-color: var(--dark);
color: var(--light)
}
.card {
background-color: var(--dark); // overriding bootstrap styles here
}
I am trying to apply it at the root of my application like this:
componentWillReceiveProps() {
if (this.props.profile && this.props.profile.theme === 'dark') {
require('./styles/dark.css');
}
}
It works great when running the application locally with yarn start. But when I actually build the app using webpack, it works really strange. Part of the new styles are applied and part on, regardless of which theme is selected. For example background is applied from the main theme and ignored in the dark theme but text color is the opposite.
Why is this happening?
It seems that the dark stylesheet is not being applied at all when building the app with webpack, although everything looks correctly when running it with yarn start.
I guess that you have a naming clashes, which overrides your css.
React supports CSS Modules alongside regular stylesheets using the [name].module.css file naming convention.
CSS Modules let you use the same CSS class name in different files without worrying about naming clashes
I solved my issues simply by importing all styled css sheets and then prefixing them like this:
.dark .card {
color: black;
}
.light .card {
color: white;
}
I assign class to the wrapper based on my props:
<div id="root" className={theme}>
// content
</div>
Works like a charm.

styled components + reactstrap how to import bootstrap stylesheet after other stylesheets

I need to use bootstrap in a few of my projects and one problem I have is that for some reason the bootstrap stylesheet takes priority over the styled component styles.
import "bootstrap/dist/css/bootstrap.
const StyledButton = styled(Button)`
background: blue;
`;
intended result: use the background specifield in my component
actual result: StyledButton has the default bootstrap background
example here: https://codesandbox.io/s/p2wz01wnz7
I'm currently importing bootstrap in my index.js like this:
import "bootstrap/dist/css/bootstrap.css";
Is there a way I can force it to load last? I'm also using create-react-app just like in the codepen
I do not want to put
&&&{
}
around all of my styles.
You could place this import statement at the bottom of the header in your html file. If you have a css or scss import, just put it below that.

How to compose styling with sass and css-modules?

I just go into create-react-app v2 and I was wondering how the styling is done in projects. There are so many ways to do styling. For instance, if you have .NavBar which also uses a reuseable .container and maybe another class, how do you compose them together? Do you use :root and use compose of css-modules or do you use #extend or #mixins of sass? Or maybe pass an array as className <div className={['navbar', 'container']}>?
How do you do the importing as well? Is importing one index.scss file containing all re-useable classes for each [name].module.scss the way to go?
So every [name].module.scss starts like this:
#import '../../styles/index.scss"
....
.navbar {
display: flex;
}
....
and index.scss has
#import 'layout'
#import 'colors'
#import 'typography'
...

Using LESS, how do I reference a class in the separate font-awesome .less file?

Background
I am using Twitter Bootstrap LESS source with LessJS
I'm using font-awesome.less (referenced from within Bootstrap.less)
I've removed the icons section from bootstrap so they don't conflict.
I have a site.less file which I also reference from within Bootstrap that contains some site-specific styling.
Goal
I would like to be able to do something along the following lines in my site.css file:
.feedbackItemIconPraise
{
.icon-thumbs-up; //class included in font-awesome.less
color:Green;
}
Problem
When I try the approach above, I get the following error:
This error makes sense; I'm just not sure how best to correct it without creating an additional import of font-awesome.less in my site.less (which I imagine would be its own issue).
To clarify: Per comments below: I have a class name that I'm using from a Knockout viewmodel. (for example, if "Praise" is selected, it will apply the class "FeedbackItemPraise"). If FeedbackItemPraise is selected, I'd like it to apply the .icon-thumbs-up class from font-awesome (which displays the icon via a web font) and then also make the color green.
What I have so far
Bootstrap.less customization (only relevant parts shown):
//Sean's customizations
#import "background.less"; // Background images and colors
#import "font-awesome.less"; // Font Awesome font (SK 2012/09/04)
#import "site.less"; // site-specific LESS
Class within site.less:
.feedbackItemIconPraise
{
.icon-thumbs-up; //class included in font-awesome.less
color:Green;
}
UPDATED
Upon looking at Font-Awesome again, looks like they have now included mixins for the icons. See the following two files.
https://github.com/FortAwesome/Font-Awesome/blob/master/less/variables.less
https://github.com/FortAwesome/Font-Awesome/blob/master/less/mixins.less
Use like:
.feedbackItemIconPraise
{
.icon(#thumbs-up-alt)
color:Green;
}
ORIGINAL
If you look at font-awesome.less you will see that class doesn't exist, it's actually .icon-thumbs-up:before. Unfortunately you can't use pseudo classes as mixins, eg .icon-thumbs-up:before;.
You will need to modify your font-awesome.less file (or just add this class, or just put content: "\f087"; directly where it needs to go) so there is a non :before version:
.icon-thumbs-up:before { content: "\f087"; }
.icon-thumbs-up { content: "\f087"; }
Then apply this concept:
.feedbackItemIconPraise {
font-family: "FontAwesome";
font-size: 90px;
padding-top: 7px;
font-weight: normal;
font-style: normal;
display: inline-block;
text-decoration: inherit;
&:before {
.icon-thumbs-up;
}
}
Seems Font-Awesome icons have to use the :before pseudo for them to show up.
Demo: http://pulse-dev.com/files/stackoverflow/fontawesomeclass/
There may be another solution to this, but I combine my scripts into a single file (automatically) before running it through the LESS compiler. This allows me to define variables and mixins up front that can be used in any of my LESS files.
The online documentation does mention that LESS can include the #import files, making the variables and mixins available. You may need to ensure that you are on the latest version of the compiler and if the import files are organised in a folder structure, you may need to tell the compiler where to search.
var parser = new(less.Parser)({
paths: ['.', './lib'], // Specify search paths for #import directives
filename: 'style.less' // Specify a filename, for better error messages
});

Categories