I have two Components and two css file for each component. css file is imported in req component. The problem is each component has same classnames and if i changes css in component it's effecting the other component with same class too.. Pls help.. comment if you don't understand my question
html {
font-family: sans-serif;
}
/*
This rule is not needed ↷
p {
font-family: sans-serif;
}
*/
html {
font-family: sans-serif;
}
p {
line-height: 1.5;
}
/*
This rule is not needed ↷
p a {
line-height: 1.5;
}
*/
About the css priority level,
Basically, the css that follows has a higher priority.
!important> inline style attribute> id> class, other attributes, capital class (like :first-child)> tag element, capital element (like ::before) in order of priority.
If the priorities are the same, the css with a larger number have higher priority.
https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
If it is not inside and is imported, the priority is the same.
And because of the inheritance, cascade of css, it will affect if you define p even if it's a different file.
There are also css methodologies such as BEM, SMACSS, and OOCSS. However, this also does not solve the fundamental problem.
From CSS methodologies such as BEM and Atomic CSS through to programmatically encapsulated CSS modules, many are doing their best to sidestep or otherwise suppress these features. This gives developers more control over their CSS, but only an autocratic sort of control based on frequent intervention.
https://www.smashingmagazine.com/2016/11/css-inheritance-cascade-global-scope-new-old-worst-best-friends/
There are options such as shadow dom, but polyfill is also directly linked to performance issues.
If you're using react, I think the approach taken by the next's attitude that is looking at about css is probably the closest to the current best we can see.
I hope you have a look at the way css is divided in next.
https://nextjs.org/
Related
I created a page with a resizable panel on the bottom using react-resize-panel lib.
I had to change the alignment of the elements inside the divs generated by the <ResizePanel> component provided by the lib.
<ResizePanel> creates three levels of elements:
I needed to override the margin-bottom property of the child with the class name ResizePanel-module_ResizeBarVertical__2LUZV. Likely, the suffix is generated dynamically, so I had to use the CSS selector to override it:
[class^='ResizePanel-module_ResizeBarVertical'] {
margin-bottom: 0;
}
Tested it locally and it worked as expected. But when I deployed to remote the sequence of the CSS rules applied changed and my custom style was overridden:
I would like to get a better understanding of how CSS is loaded locally and remotely. In particular, is there any rule of thumb for local testing when it comes to React styles and conflicting CSS rules
UPDATE with solution
There are two solutions suitable:
narrow down the selector to div only (selected this one based on best practices)
div[class^='ResizePanel-module_ResizeBarVertical'] {
margin-bottom: 0;
}
use !important in the style
[class^='ResizePanel-module_ResizeBarVertical'] {
margin-bottom: 0 !important;
}
CSS Precedence could be tricky sometimes, there should be 3 "levels", sorted by highest priority:
!important (you can force override; should solve your problem, but probably doesn't fully answer your question)
specification of selector (how much specified the selector is; seems like what you are struggling with – your custom selector is less specified, so it has lower weight)
order; what was declarated first (there could also be problem with cache; but that's probably not your case)
More info about the selector specificity weight in the Mozilla docs:
https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
I am building a UI library in Angular and often designate elements to be styled with generic classes such as .slider, or .form-control. The problem I run into is that sometimes the consumer (who uses the library) uses the same classes for its own elements and when he applies styling it inadvertently breaks the library's UI.
Angular does provide scoped classes so that if for instance I have the style:
.form-control { line-height: 2em; }
then at runtime, Angular has modified it to dynamically add a component specific attribute:
.form-control[ng_content0] { line-height: 2em; }
And because that attribute is added to the element itself dynamically, my styles don't bleed out and impact the elements of the client who consumes the library.
That's great. But how do I prevent the reverse? Basically, how do I use CSS in a way that limits the consumer from breaking things when there is a conflict of class names? Only thing I've thought about is to prefix all class names with a prefix. Some kind of janky namespacing:
.mylib_form-control { line-height: 2em; }
What's the right approach?
Basically, how do I use CSS in a way that limits the consumer from
breaking things when there is a conflict of class names?
I think it's more important to try to prevent a conflict in class names, instead of dealing with what happens if there is one. If there is a conflict, assuming the selectors have the same specificity the style defined last will win. So, depending on if the consumer adds your library before or after their own styles, that would affect what conflicting rules would apply. If you think your library is super important, you can add !important to all your library styles. Which is a bad idea. You should just try to avoid the conflict.
You could perhaps add a prefix to all your classes, say beetle-ui and I would assume the consumer doesn't have any classes that start with that.
You could do something like Semantic UI and for an HTML element to take on the style of the library, it must have the class ui in it's class list. Then all your selectors kind of look like:
.ui.input {
}
.ui.header {
}
The corresponding HTML would like something like:
<input class="ui input" />
I would do something like my first example, and use BEM and define my CSS using SASS so my syntax can be a bit cleaner and benefit from the prefixing.
.beetle-ui-form {
background-color: grey;
&__input {
outline: red;
}
}
Which would generate CSS like:
.beetle-ui-form {
background-color: grey;
}
.beetle-ui-form__input {
outline: red;
}
I'm curious what the CSS directive #apply does. I have googled #apply but I couldn't find anything that could explain its meaning properly for me.
What is the usage of such a directive?
The simple way of explaining it would be; introducing variables into CSS (which is a feature of preprocessors, such as Sass), and mixins which are function like behaviors (also in preprocessors).
Imagine that --header-theme is a function (mixin):
:root {
--header-theme: {
color: red;
font-family: cursive;
font-weight: 600;
};
}
h1 {
#apply --header-theme;
}
h2 {
#apply --header-theme;
}
This way, you can use it in many different places without having to rewrite it again (DRY).
Now the variable part could be explained with this example:
:root {
--brand-color: red; /* Default value */
--header-theme: {
color: var(--brand-color);
font-family: cursive;
font-weight: 600;
};
}
h1 {
#apply --header-theme;
}
h2 {
--brand-color: green;
#apply --header-theme;
}
The mixin will have a variable sent to it and change the color.
This is not the limits of the feature, and you can use it for far more. You can read more about mixin and variables in Sass for other ways of using it, and after I suggest you read this blog post.
Now after I got you excited, it is time for the bad news. It is not implemented in browsers yet (Chrome), but it is still worth knowing that it is coming and maybe if you want to prepare yourself start with Sass.
#apply is from a proposal that has since been abandoned, and replaced with CSS Shadow Parts.
the #apply rule, which allows an author to store a set of properties
in a named variable, then reference them in other style rules.
Tailwind uses this as a special directive.
Tailwind's #apply is kind of like a super-class. You can list other classes that should apply to this rule. I think of it as a way to group classes together that are often found together.
#apply is pretty cool. It basically allows you to reuse CSS blocks without having to copy them around and without having to modify their selectors.
It will make it easier to use CSS frameworks and keep semantic class names at the same time.
I found this article to be a nice instruction to this feature.
Unfortunately, at the moment, browser support is basically non-existent. It can be used with a CSS pre-processor such as PostCSS.
It's future is also uncertain, if I understand well. The main advocate behind this feature stopped supporting it.
One feature I really love with LESS is nested rules. It makes the stylesheet much cleaner that way and you can find an element very quickly.
I was wondering if there's an option when compiling to optimize selectors. For example...
#global {
/* Styles here maybe */
.container {
/* Styles here maybe */
#sidebar {
/* Styles here maybe */
.title {
font-weight: bold;
}
}
}
}
will be compiled to #global .container #sidebar .title { font-weight: bold; }.
But the first two selectors are useless, since #sidebar should be unique in my page.
Is there a way to ask LESS to compile this to #sidebar .title { font-weight: bold; } instead?
Your assumption is wrong that multiple IDs in CSS are redundant. Imagine, as an example, a site where the CMS generates the page type into the output, like that it's the contact page:
<body id="contact">
<section id="content">Blah</section>
</body>
According to your logic, the following piece of CSS would be a candidate for 'optimization':
#contact #content {
background:red;
}
Now however, your home page has <body id="home"> of course in this imaginary CMS. And suddenly the content of your homepage has a red background because you decided to erroneously optimize that #contact selector out of the CSS, while it most certainly shouldn't have a red background according to this rule.
So no, LESS cannot do this because it would break code. If you don't want the selectors, don't use them and don't put them in your code.
Other answers, including the accepted one, have explained convincingly why LESS cannot simplify your nested selectors in the way you want.
Actually, SASS has the ability to do this:
#global {
.container {
#at-root #sidebar {
.title {
font-weight: bold;
The #at-root directive essentially ignores all the higher nesting selectors. I don't know if LESS has something similar. The above compiles into simply
#sidebar {
.title {
font-weight: bold;
But there is a deeper issue here, starting with the fact that you "love" nested rules in LESS. Stop loving them quite so much. I don't know about you, but most people love nested rules because they think it's cool to exactly mimic the hierarchical structure of their HTML. The SASS docs even claim this as a benefit:
Sass will let you nest your CSS selectors in a way that follows the same visual hierarchy of your HTML.
So people with HTML such as
<div class="foo">
<ul>
<li class="item">
write LESS like
.foo {
ul {
li.item {
This is a horrible, horrible idea, It makes the structure of CSS completely dependent on the structure of the HTML. If you change one nesting level in the HTML, your CSS breaks. Often this approach is combined with a lot of rules defined against tag names such as ul instead of class names, which aggravates the dependency, so changing the ul to ol in the HTML breaks the rules again. Or it's combined with rules based on Bootstrap classes such as col-md-6, so if you ever change that to col-md-4 things break again.
CSS rules should be orthogonal to the HTML. They represent a different dimension. They represent styling concepts which are applied selectively throughout and across the HTML.
I am guessing that you wrote
#global {
.container {
#sidebar {
.title {
font-weight: bold;
because you are adopting this mistaken idea of mirroring the HTML structure in your LESS. Then, you notice that this compiles down to having selectors which contain multiple IDs, which you imagine must be inefficient (although, actually, the degree of inefficiency is minimal). You yourself are writing extraneous nesting levels in your LESS, then complaining that they may be slowing down performance!
Worse, you've hard-wired assumptions about the HTML structure into your CSS. It's of no consequence that the sidebar happens to fall inside a .container which is inside a global element. So don't write them. Perhaps at some point you decide to change the container class to container-fluid. Boom, instantly your CSS breaks. What is the point of conditionalizing the fact that the title should be bold on it being contained with a container class, which in any case is a layout-related class that has (or should have) nothing to do with styling? If you're going to duplicate your HTML structure in your CSS using preprocessor nesting, just go back to writing inline styles. At least that way you'll only have one file to change when you change your HTML around.
When designing CSS, you should think just as hard about the design of the rules as you do about the design of classes and methods when writing JS. In this case, you need to ask yourself, "What characterizes the situation where I want some title to be bold? What drives that? What is the nature of boldness? What am I indicating by boldness? What is the semantic notion indicated by boldness?"
Let's say that you want all titles to be bold. Then you simply say that:
.title { font-weight: bold }
Let's say that you want a title to be bold only when it's in the sidebar. Then you simply say that:
#sidebar .title { font-weight: bold; }
My suggestion here is to go cold turkey. Stop using nesting during a withdrawal period. Write rules with the minimum number of selector components. Refactor your classes to have semantic names (such as title-emphasis). Once you're "sober", you can go back to cautiously using LESS's nesting capability when it is useful, such as perhaps for hover:
#boo {
color: red;
&:hover {
color: blue;
}
}
This is actually useful and saves you from writing #boo twice, and groups the rules in an easy-to-understand way.
I have created a web widget. That my client put in their websites. Basically on load it calls webservice and loads data specific to client.
As a result it looks like:
<div class="widget">
<div class="container">
</div>
</div>
Dynamically I apply CSS styles to my widget class. To look consistent with our corporate styling.
The problem is when client application styles overwrite the style I applied run time.
For example if client has, it overwrites my styles:
body {
margin: 0 auto;
padding: 0;
width: 90%;
font: 70%/1.4 Verdana, Georgia, Times, "Times New Roman";
}
Is there any way to break inheritance? Just to say whatever div with class widget styles has do not inherit parent styles.
I don't think you can break CSS inheritance per se, but you can try to circumvent it by following the rules of CSS specificity. Here's a good article about Specificity.
As a last resort, try adding !important to styles in the widget to give it a higher specificity than the default styles.
#myWidget{
font: 100%/1 "Times New Roman", Serif !important;
}
If the client is also using !important it could cause problems. If you could setup a jsFiddle with an example, we could help find the issue.
Note, going the route of adding !important should be a last resort as it's the 'nuclear option' of style specificity.
You can not force elements to NOT inherit parent styles.
You can however override all possible styles that you do not want changed. If your CSS specificity is higher than the customers specificity then your styles will be dominate/expressed on the page.
See:
CSS Specificity via css-tricks.com
Per your example using the code below would be more specific than the body declaration and thus override :
.widget .container {
font-family: Arial;
}
You can't break style inheritance as such, but you can ensure that your styles are either more important or loaded in the right order so yours comes out on top.
Have a look at the !important tag.
Alternatively if you load your stylesheets after theirs yours will take precedent (unless theirs is inline). You can use Javascript to load your styles after the body has loaded (But then you'd get a "flicker" effect).
You could also try inline styling. Inline styling has the highest priority. This will work if client overrides use an imported stylesheet.
Like others have mentioned, another option is !important.
You can also read up the relevant specs at http://www.w3.org/TR/CSS2/cascade.html where they describe exactly how they cascade. If above mentioned tricks don't work, perhaps specs will give you a clue or you will know for certain that this is not possible.
Use of the !important css attribute is considered a bad practice. Because it introduces the potential for precedence conflicts, and makes it extremely difficult to troubleshoot css in the long run.
A less intrusive approach to this problem is to delimit your widget with an id, and in your stylesheet, to reset some of the most important style declarations using the "universal" selector, such as:
#myWidget *{
margin: 0;
padding: 0;
background: none;
border: none;
}
For example. Then, define your overrides specifically.