How to avoid css selector applying style rules from another file - css

I came across this problem while handling a large project and felt that i should seek an opinion from the community here.
I have specified a css class 'header' in style1.css, i.e.
.header { color: red;}
In another file, I inadvertently, named a class 'header' again with this rule :
.header { background-color: yellow; }
When i refreshed the browser i noticed the red font and after examining the style inspector found the problem. I tried to avoid the problem by applying specificity, i.e. #some-div .header, but that didnt stop it from applying the red font. Of course i could simply solve the problem by renaming header to something else, but i'm curious how developers who handle large projects handle this. Thanks for your time.

Well, from your code, you specified values for different properties in the two declarations of the header class. The first declaration specifies a color property and the second specifies a background-color property. From all indications you're not really "overriding" anything since you didn't give conflicting values for one property so, CSS is simply giving the values of the first declaration of the header class to the second one because there's no difference. If you wanted to override it for the second you'd have to probably add a different identifier to the second declaration of the header class to point to a unique element and specify a different value for the color property. Hope this satisfied your curiosity.

Just add a different class to one of the cases. For example:
.header {
color: red;
}
.header.yellow-bg {
color: initial;
background-color: yellow;
}
<h3 class="header">Red header</h3>
<h3 class="header yellow-bg">Black/yellow header</h3>
The second declaration for color applies because it is more specific (2 classes > 1 class).

Don't use !important as another user suggested. Avoid it all costs. It's the easy way out for the moment, but once you start going down that road, you're going to end up with a stylesheet that's terrible to manage.
Set your styles for a specific base and use classes and more specific selectors as overrides. Remember that stylesheets cascade.
For example, say you have a typical header font color that should be your .header. If you have other one-off or unique headers that share same structure provide another class to that which makes sense to you.
So as an example:
Both headers have the .header styles but headers with the special class have blue text color which overrides red.
.header {
color: red;
width: 100%;
display: block;
background-color: #eee;
padding: 10px;
margin: 2px;
}
.header.special {
color: blue;
}
<div class="header">Regular Header</div>
<div class="special header">Special Header</div>

Related

how to ignore class prefix in css file

I see some e.g. div/button style in Chrome console like this:
/* Chrome browser styles tab */
.ItemClass1-0-3-171.ItemClass2-0-3-173: {
background-color: "red"
}
How do I define a new style in CSS ignoring that class numbers? because it can be a different number for other div/button on the page..
/* CSS file */
.ItemClass1.ItemClass2 {
background-color: "blue"
}
You can use two attribute contains selectors for this.
[class*="ItemClass1"][class*="ItemClass2"] {
background-color: red;
}
<p class="ItemClass1-0-3-171 ItemClass2-0-3-173">foo</p>
But keep in mind that this will also select elements with the class fooItemClass2.
You can use an attribute selector with a starts-with value to pick up anything that starts with ItemClass.
Note: This solution assumes ItemClass is the first classname and doesn't account for whether the element has both classes. For these reasons Sven's answer might better suit your needs.
[class^='ItemClass'] {
background-color: blue;
padding: 4rem;
}
<div class="ItemClass1-0-3-171.ItemClass2-0-3-173"></div>

CSS variables and custom properties - How do they work?

dynamic-text-colors.css
:root {
--title-color: #555555;
}
.text-title-color {
color: var(--title-color);
}
.bg-blue-100 {
--title-color: #999999;
}
.bg-blue-200 {
--title-color: #888888;
}
.bg-blue-300 {
--title-color: #777777;
}
index.html
<div class="bg-blue-100">
<h1 class="text-title-color">I am colored #999999</h1>
</div>
<div class="bg-blue-200">
<h1 class="text-title-color">I am colored #888888</h1>
</div>
<div class="bg-blue-300">
<h1 class="text-title-color">I am colored #777777</h1>
</div>
Question:
I don't understand the process that allows each h1 to have a different color. In this instance, I don't understand how the value of "text-title-color" can be different based the background color.
"Custom properties are scoped to the element(s) they are declared on, and participate in the cascade: the value of such a custom property is that from the declaration decided by the cascading algorithm." - https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties
According to the explanation above of custom props by Mozilla, each variable is scoped to its element its decalred on. As such, would the browser some how convert the code to something like this and if so where is the code below stored?:
.bg-blue-100 .text-title-color{
color: #999999
}
.bg-blue-200 .text-title-color{
color: #888888
}
.bg-blue-300 .text-title-color{
color: #777777
}
The browser doesn't need to do any conversion in the way you describe
The variables are all part of what it understands.
It's not like a preprocessor which has to convert everything to 'real' CSS before anything runs.
When the browser has to render an h1, say, as in your question it will pick up the value for --title-color from whichever style is relevant. Just as it would pick up, say, the color or width if they were set there.
The value of CSS variables is precisely because they can be set at run time, e.g. by Javascript on some user action and the new value will be used 'on the fly'.

Apply 2 different CSS pseudo-elements to the same class on the same time

It is correct to apply 2 different CSS pseudo-elements to the same class on the same time?
Browser interpret my desired result, at least on Firefox everything works fine, but for me is important if this is a correct approach.
Do you have a correct CSS approach of this scenario?
.critselect {
display: block;
margin-top: 40px;
}
.critselect p:nth-child(2) {
text-transform: lowercase;
}
.critselect p:nth-child(2):first-letter {
text-transform: uppercase!important;
}
<div class="critselect">
<p class="randvis">This is first paragraph and have <strong>CRM / Marketing</strong> or others extrnaly inserted values that must remain Uppercase.</p>
<p class="randvis">This is second paragraph and have <strong>French, English, German</strong> or others eternaly inserted values that must to be converted via CSS to lowercase.</p>
</div>
yes, it's correct to apply two different CSS pseudo-class to the same class,
but in your scenario..., I do not see it very feasible, it is better to use text-transform: capitalize; it is also not necessary to use the important! is bad practice

How to avoid CSS impact by a third party library?

I have a angular project which use a library called smDateTimeRangePicker , it include the code below:
Link Here
.action {
height: 30px;
margin-bottom: 0;
position: absolute;
bottom: 0;
width: 100%; }
However, in my project, there is a code which also include action class
<div flex class="action cell">
And it is impacted by the CSS above, how to avoid it?
This question considered about these points below:
There is a way that can avoid the CSS impact between project and library.
The library uses a bad practice, it must avoid impacting project. It is a bug for the library and must be fixed.
This impact usually happens, so I need to change my project to avoid the conflict
Rename your project action class to something else is the cleanest way. Else you have to resort to fixes that are considered bad practice like !important, however these still get the job done.
this happens to me quite frequently, so to solved it I just add one parent class to my page or that particular section
<div class="my-unique-class">
---
<div class="action">
---
</div>
---
</div>
.my-unique-class .action {
height: 30px;
margin-bottom: 0;
position: absolute;
bottom: 0;
width: 100%;
}
You can avoid such kind of situation by increasing specificity of your css rules.
There are multiple ways to do so:
Include all third party CSS files before your custom file so that css rules with same priority (In Your Case) can override the rule in third party CSS file.
Above solution should work in most of the cases, but there are chances that Third party CSS might come with higher priority orders, so you can increase weight of your css by adding class at your parent tag as:
.parent > .action {
/ * Some CSS Code */
}
<section class="parent">
<div flex class="action cell"></div>
</section>
MDN has great article about CSS Specificity here
If you can't change your class name, you could make your styles unique to your element by doing:
.action.cell {
/*your styles here*/
}
By leaving out the space between action and cell you are saying that both classes are on the same element. Also, make sure you are loading your stylesheet after the 3rd party stylesheet so that your styles are being applied over theirs.
When you have a CSS rule, you can use !important before semicolon:
background: black !important ;
It marks your rule as "important" and it cannot be changed with any CSS file.
Only inline CSS can overwrite it:
style="background: blue !important"

I want to have a css to be applied over another

I have a button that is displayed in a lot of pages of my website (With an automated javascript Widget).
I want this CSS :
.app.programEditor .col-2 .actions .widget.bt-flat.programs > .bt-flat-icon {
}
to be applied, and not this one :
.app.programEditor .actions .widget.bt-flat > .bt-flat-icon {
left: 145px !important;
top: 19px !important;
But instead, what happens, is the two css are applied, and as a result I get the second element that overwrites what I want to do with the first CSS ( A blank css with no rules )
Please I really need your help
The root cause of your problem is the poorly written rule that uses !important. This is an excellent example of why not to use !important. If at all possible, try to understand why !important was thought to be needed there, and see if you can remove it.
But if you are left fighting against an important rule, your only choice is to fight fire with fire, and toss back an !important of your own, in a rule designed to take precedence either because it is more specific (in this case, your override rule has seven classes, to the original rules's six, so it is more specific), putting it later in the file if it has the same specificity, or if you have no other choice use the various tricks available to jack up the specificity.
Having said that, overall this CSS seems to be poorly structured, verbose, and inefficient.
.app.programEditor .actions .widget.bt-flat > .bt-flat-icon {
First, if .app is a class applied to your entire application, it is probably not necessary. If .actions only occurs within .app.programEditor, then the latter is not necessary at all. If .bt-flat can only apply to widgets, then instead of widget.bt-flat you can just write .bt-flat. If .bt-flat-icon can only occur within .bt-flat, as seems likely, then .widget.bt-flat may not be necessary. And so on. In general, instead of writing down every single class in the HTML hierarchy in your CSS rules, try to limit selectors to those necessary to unique select the element you want. In this case, for example, it is possible your rule could be written as simply as (just an example):
.programEditor .actions .widget > .bt-flat-icon {
Second, the magic numbers 145 and 19 are a massive code smell. They are probably connected to other magic widths and heights elsewhere in the CSS, and would have to be changed if those change. What do the 145 and 19 mean? Perhaps they are actually a percentage of some underlying dimension. In other words, maybe some element is 160 pixels wide, and we want to place the icon to the upper right. In that case, instead of hard-wiring the 145, you can either use a percentage, or specify a right property, or use the transform property perhaps, so no matter how the width changes--such as with the introduction of .col2--the icon remains in the right place with the original rule.
You can simply change it to position:static this is just a demo. Otherwise, if you understand concept of Specificity very well, then there was no need for this question.
$('#change').click(function() {
$('.one').css("position", "static");
$('.one').text("Position changed to Static")
});
.container {
width: 90%;
margin: 50px auto;
position: relative;
border: 1px solid #000;
display: block;
height: 200px;
overflow: hidden;
}
.one {
width: 150px;
height: 150px;
background: tomato;
position: absolute;
left: 118px!important;
top: 30px!important;
display: block;
color:white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="container">
<div class="one">
Positioned using absolute or relative</div>
</div>
<button id="change">Change CSS</button>
If many rules exist, the first one takes precedence, but if the last one is more specific, it will override the first one. BUT if the first one is less specific AND has !important that one will take precedence. :) To make matters more complicated, if both rules has !important the most specific rule will take precedence.
So the easy solution here, if you cannot change the already existing rule, just add !important to the code you can edit. If that doesn't work, try to get your code processed earlier in the code than the other one.
.app.programEditor .col-2 .actions .widget.bt-flat.programs > .bt-flat-icon {
left: 40px !important;
top: 40px !important;
}

Resources