How to overcome the overlapping of similar name CSS classes from two CSS frameworks? - javascript

I was using Modal of semanctic-ui-react inside a create-react-app project. Inside index.js I had declared the import for the CSS files of the frameworks
import "semantic-ui-css/semantic.min.css"
import "bootstrap/dist/css/bootstrap.css"
I noticed the weird positioning of Modal. After debugging I found a .modal CSS class was getting applied which was coming from the Bootstrap's CSS. Since semantic-ui also has the similar name classes, this caused the overlapping.
On removing the import "bootstrap/dist/css/bootstrap.css", Modal get positioned correctly.
Solution(partial) in my mind:
import CSS file only in the class where it has been used, and not to the index.js
-this has two problems:
1. Suppose EditForm.js uses semantic-ui, I import the semantic.min.css
directly in this file. But what if it's parent class in which
EditForm.js is used, if parent.js is using bootstrap.css then again
the same problem will occur.
2. I am not sure on this, but importing the complete CSS seperately for each files could make those files heavy, please correct me here.
I want to use both the frameworks in my project, what would be the ideal way?

Do you have to use both of them? if so, another solution to consider is implementing SASS/SCSS in your project.
SASS is usually bundled in alot of webpack-using installations out-of-the-box. I have only used it in vanilla, Vue and Angular projects but i'm 100% sure React would have no problems with it and CRA would be able to generate the necessary configuration for it.
If you installed SASS, you have alot of ways to handle this. Two I would think of though are:
You can decide on one library that is your "main" and import it as normal, while the other one you can "scope" within a css rule. This is possible because SASS automatically unwraps the import and inserts it under that css rule, effectively "Scoping" it. CSS does not do that by default.
.smui {
#import "semantic.css";
}
Read more here: https://sass-lang.com/documentation/at-rules/import#nesting
I didn't check semantic UI's sass support, but Bootstrap is built modularly in SASS which allows you to selectively import the parts you need. So let's say you want to use a semantic button within Bootstrap's Grid layout. Instead of bringing over all of bootstrap, you can simply import the grid module.
#import "semantic-ui";
/* Required */
#import "node_modules/bootstrap/scss/functions";
#import "node_modules/bootstrap/scss/variables";
#import "node_modules/bootstrap/scss/mixins";
.bs {
/* Part you actually need */
#import "node_modules/bootstrap/scss/grid";
}
This would reduce the footprint to only what you need, reduce your CSS size, and reduce overlap of styling for elements/classes you do not want to be overwritten.

I would not recommend assigning an id to your component and writing your overrides there. That will force you to use that id everywhere throughout your application, which you do not want to do.
You have two options:
1) The easiest option would be to build your own version of Bootstrap that ONLY contains the styles for components you are actually using in your app. This is also going reduce the number of styles your user has to download to render your app. Just exclude "Modal" from the build (and any other bootstrap components you do not use).
2) Do a class comparison between the two libraries you are using. This should actually be easy to do with developer tools in any browser. You will see each time the component you are targeting matches a class in one of your style sheets. Some rules will be crossed out in one, some will be crossed out in the other. If you want the styles for Semantic UI to take precedence, you will want to make a separate stylesheet that increases specificity for the style properties that are being lost from Semantic UI. My guess is there are probably only a few style properties that are getting overridden or that you do not want.
You can also put the above styles in the style prop on your modal if you do not want to create a separate file and they will be added inline to the component, effectively being more specific than the styles in either CSS file.

This worked for me.
In a custom css file, insert the following rule
.modal {
top: auto !important;
left: auto !important;
height: auto !important;
}

Related

How to build a UI Component Library with code-splitting for CSS styles

I want to create a UI Component Library where consumers can bundle only the styles for the components they are actually using.
Let's say this question is framework-agnostic since I am more interested to evaluate existing approaches.
The idea would be for a user to be able to
import { Button } from '#mylib/ui`
and not being required to go to their main.ts and add
import '#mylib/ui/styles/main.min.css`
Now, obviously, the first solution is to avoid bundling the CSS together, so a user would be able to import separate stylesheet for each component
import '#mylib/ui/styles/button.min.css';
import '#mylib/ui/styles/accordion.min.css';
Now, this approach works well if you use a handful of components and want to keep the bundle size in check, but it doesn't scale if a consumer starts using dozen of components.
How can I overcome that challenge?
The only approach I can think of is inline styling, which won't work because of missing selectors, media queries, etc.
What I would love to achieve, is a way for consumer to declare what they need, and get the styles for that component without any additional configuration/import, while preserving the ability of only bundle the CSS that belongs to the components that are imported
import { Button } from '#mylib/ui`
I am scratching my head to come up with an idea of how this would work...

Is there a way to find out what CSS has changed after removing an imported stylesheet in react?

Currently trying to remove bootstrap CSS as a dependency from a large monorepo.
Specifically, we are using react-bootstrap which requires a default stylesheet imported into a page.
I have successfully removed all custom components and those with logic but there are multiple global styles that break when removing the imported css.
Is there a way to find out all the things that have changed before/after it's removed? Doing it manually is going to be a grueling task. Any suggestions are appreciated.
ALSO: we are utilizing CSS Modules to ensure global styles aren't getting out of hand. It adds another difficulty to this issue. Where would I even put the changed styles if I do find them?

React - How to make CSS class more selective and override default class?

I am starting with React but have some background in web prior to it.
I have a default component let's say .title, I would like to override few things from it, maybe the background-color or the font-size for the situation where it is in this specific page.
In "normal" web, I would simply write a class .special-page .title or .title.special-version and override what I want.
From what I have read, because of the module CSS system of react, this is not possible. I am using scss and I can't even use nested classes which is a pain but I got used to it.
What is the correct way to do this ?
I tried with classNames and do cn(defaultStyle.title, styles.special_title) but the priority seems random over which of the css class is expressed based on the order of import and the order of the class in cn.
Is there a reliable way to have one class modifying a base one without having to put !important everywhere ?
Thank you !
I guess you interpreted the css module incorrectly. All the classes you have defined in module.css will only affect the respective component. This is because when rendering a component react takes the class name you defined and manipulates them by adding a hash on it (to make it component specific). to use generic class names import the css as regular import (not as module.css but filename.css). the generic css classes will be available throughout the entire app if you placc then in index.js or App.js
Now, you can define your .title in generic css and .special-version in module. Then use them both in class name as regular html title special-version. It will take both .title styles and .special-version style. place those rules, you want to override, in .special-version

Should every react component have it's own stylesheet?

I just started with React and have a simple question I couldn't find anywhere.
So, should every React component have it's own stylesheet?
For example if I have my main App component which I render to the browser should I just include a css file there and have all my styles in that or is it bettet to have an own css file for every component?
Thanks.
CSS best practices in React are still heavily debated. There are pros and cons to each variation.
What you are probably looking for is modularity in your CSS. While having unique style sheets for your components does accomplish this to some degree I suggest taking a look at CSS modules. Packages like this can keep your CSS contained to a specific component so you don't over-write styles on other components.
Personally, I've done a little bit of both. I use a base style sheet (bootstrap for example). Then I use CSS-modules to help me make components that are unique that I might want to easily port over to other projects.

Style that should apply to only one class is being applied to everything

I have a border layout in my viewport. Within the border layout, I have a "header" section and a "navigation" section.
The folder structure looks like this:
I'm trying to add style to the header portion only.
I created a "Header.scss" file in my "sass/src/view/main/header" folder:
As I understand the documentation on styling the view in the app, when you create a matching folder and file structure in the sass/var/view folder, the styles in that scss file should apply ONLY to the given class in the app folder.
I added the following rule to the Header.scss file:
//in Header.scss
$panel-body-background-color: red;
The body background color does change for the header, but it also changes for all panels in the viewport.
Am I misunderstanding how the sass var folders are supposed to work? How would I apply the style rules to only the header class?
when you create a matching folder and file structure in the
sass/var/view folder, the styles in that scss file should apply ONLY
to the given class in the app folder
Not true.
Matching folder and *.scss file names will simply make sure that the file is included in the build — if and only if the corresponding app class is included / in use. Beyond that, Sencha CMD does not intervene in how SCSS is processed and CSS styles are applied — it is all left up to Compass and web browsers.
Am I misunderstanding how the sass var folders are supposed to work?
So yes, you are.
Merely by assigning a new value to a previously defined SCSS variable in a certain *.scss file corresponding to its JS mate, you are not limiting the variable's impact to the relevant app class. You are simply making sure that the assignment will only take place if the app class is included in the build. Once it is included, the variable's impact will be in accordance with how SCSS works — as if you had all those variables and rules in one file (which eventually is the case).
How would I apply the style rules to only the header class?
Use cls to make the header's panel different (or bodyCls), and put corresponding rules in sass/src/view/..../Header.scss:
.<my header panel css class> {
<panel body selector> {
// custom styling
}
}
First, I think the answer of Drake enterprise Systems is great. It covers 99% of the questions of the author. My answer is not meant to be considered as a better answer, it's more a complement for the solution Drake Enterprise Systems came up with.
The best way to style your apps is using a custom theme. It's not that hard, it's reusable and in line with how Sencha would like you to do it. There are several tutorials out there and of course Sencha has a great guide themselves.
For those who don't want to go all in I think using UI's is best practice. It's a great way to style your components. A UI is like a mixin, but with optional parameters (in the past you had to set every parameter, which was a pain in the ass). Most components already have a ui named 'default' and out-of-the-box can be changed to 'light'. You can also create your own ui's as we may expect from a flexible framework as ExtJs is.
If we look at the ui of a panel you can see that a lot of styling can be done through parameters. Here's an example of a custom ui for a panel:
#include extjs-panel-ui(
$ui: 'highlight',
$ui-header-background-color: red,
$ui-border-color: red,
$ui-header-border-color: red,
$ui-body-border-color: red,
$ui-border-width: 5px,
$ui-border-radius: 5px
);
Off course the ui can be set declarative:
// custom "highlight" UI
xtype: 'panel',
ui: 'highlight',
bind: {
title: '{name}'
},
region: 'west',
html: '<ul><li>This area is...</li></ul>',
width: 250,
split: true,
tbar: [{
text: 'Button',
handler: 'onClickButton'
}]
Even if a xtype doesn't have an UI-mixin from default, the ui can be set and is added to the default class name, so for a container this would be x-container-mycustomui

Categories

Resources