Why isn't my last instruction taking precedence? CSS - html

Here is my CSS source code
*{
margin: 0;
padding: 0;
font-family: sans-serif;
}
.container {
width: 100%;
height: 100%;
background: #42455a;
}
.menu ul {
display: inline-flex;
margin: 50px;
}
.menu ul li {
list-style: none;
margin: 0 20px;
color: #b2b1b1;
cursor: pointer;
}
.logo img {
width: 30px;
margin-top: -7px;
margin-right: 48px;
}
.active {
color: #19dafa !important;
}
.search {
margin-left: 398px; /* problem in this line */
}
I have a ul full of li's, and I set their properties in the ".menu ul li {}" category. The thing is I don't want ALL of them to have the same properties, I want the last one which is a search bar to be all the way on the right, like so:
" - - - - ___________ -"
where each "-" represents an li and the "_" is the space in between. The problem is in the very last category I made the margin-left 398 pixels. But despite that being the last instruction it is still following the instructions set before.
When I use !important it works, but I don't see why I would need to use it when supposedly the final instruction takes precedence?
The problem also applies in the .active class as well. Why do I have to use the !important to get it to work? Seems like a hassle if I have to use !important everytime I want a unique property in one of my elements.
EDIT:
I ended up finding a work-around by typing:
.search {
right: 20px;
position: absolute;
}
but my question still stands.

The final rule in your CSS does not take precedence. The various selectors of a CSS rule combine to form a specificity number which is what determines which CSS rules are applied. Classes, tag names, IDs, and other element attributes each increase the specificity score of a rule -- the more selectors, the more specific the rule.
You add together all of the specificity weightings and can essentially read it like a 4-digit number. For example, using a tag gives +1 while a class gives +10 (this isn't totally accurate, see reading materials at end). So your rule for .search has a specificity of 10 since it's just a class, while your rule .menu ul is 11 since it's a class with a tag. When applied to the same matching elements, the properties defined in .menu ul will take precedence over .search despite .search being written last.
!important essentially acts like a boolean flag to work regardless of the specificity scores. However, two rules with !important flags will still fall back to specificity. Similarly, if two rules have the same specificity, only then does the last one written take precedence.
For further reading:
https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
https://css-tricks.com/specifics-on-css-specificity/

Related

li table-cell display not working

I have a horizontal menu built using a <ul> element. I'm trying to get it to evenly spread out each <li> across the width of the menu. Based on several answers here on SO, I used the following CSS:
ul {
display: table;
width: 100%;
}
ul li {
display: table-cell;
}
However, no matter what I try, the <li> elements still end up with a calculated display of block, with this contradictory information from the debugger (tested in FF and Chrome):
I didn't know what is going on here, and (more importantly) how do I get my list items to display as table-cell?
In photo is showed that your style.css is really big (min.1835 lines) and because of that styles to ul could be overvritten somewhere.
To make your rule more important than existing rule, use !important keyword after rule like so:
ul {
display: table!important;
width: 100%!important;
}
ul li {
display: table-cell!important;
}
CSS has a trait called importance, it chooses which rules are the most specific and thus should override more loose rules. As you seem to use a CSS framework, your own rules don't override the framework's generic rules. Turns out that you have two options to increase the importance of your rules at main.css:
Add !important after your rules:
ul li {
display: table cell !important;
}
Make your selectors more specific:
#menu ul li.menu-list-item { ... }
Your question also looks very strange and you may be subject to a browser rendering bug, have you tried it out with other browsers?

spacing for nav bar margins aren't working react

I followed along with this tutorial on building a react app: React JS Tutorial for Beginners #1 – Build a website using React, Sass, Gulp and Node.js
Everything works great except the spacing of the nav bar. The way he adjusts the spacing is in the:
Code: https://gist.github.com/kentonraiford/42cad2361cb6e47c7fd6b995013d50f4
I rewatched the video a few times and was unable to figure out where I messed up. This might be a simple fix but I can't seem to find the solution.
Link to file: https://github.com/kentonraiford/reactTutorial
In the repository that you posted, the problem is the css selector you're trying to use to apply the margin-right has less precedence so is margin-right property is being overwrite
header {
nav ul li {
margin: 0;
padding: 0;
}
}
Precendence is calculate in this way
Element, Pseudo Element: d = 1 – (0,0,0,1)
Class, Pseudo class, Attribute: c = 1 – (0,0,1,0)
Id: b = 1 – (0,1,0,0)
Inline Style: a = 1 – (1,0,0,0)
So this selector will have this precedence: (0, 0, 0, 4)
header {
ul li {
list-style-type: none;
display: inline-block;
margin-right: 20px;
}
}
And the selector you use to add margin-right has (0, 0, 0, 3)
So the other selector has more Precedence that the selector that you want to use to apply margin-right to the li element
You can fix this problem by creating a more specific selector (adding a class or id to the selector) that is going to give it more precedence to overwrite other selectors or use !important (Not recommended way)
For example:
header {
ul.header-list li {
list-style-type: none;
display: inline-block;
margin-right: 20px;
}
}
Precedence: (0, 0, 1, 3)
More info about precedence:
http://vanseodesign.com/css/css-specificity-inheritance-cascaade/

How to successfully target the second part of a string in a span tag with specificity

I understand the easiest way is to "class" something and then give the class the properties needed, however,
1. I'm not a big fan of creating classes everywhere. That's what specificity and CSS mapping is for.
2. It would take me forever to go through hundreds of pages to add these classes and some of the pages I'm not even supposed to even touch AT ALL!
So, at least I have a parent class to start with :) But my problem is, I have never had to target the second part of a text inside span tags divided by a <br> .
Here is the HTML
<div class="locations">
<ul>
<li><strong>Address: </strong><span>47 Feed Mill Lane
<br>
Middlebury, VT 05753</span></li>
<li><strong>Contact: </strong><span>John Doe</span></li>
<li><strong>Phone: </strong><span>800-639-3191</span>/li>
<li><strong>E-mail: </strong><span> email#email.com</span></li>
</ul>
and the CSS for the line in question. I added this specificity logic, but it is taking the entire content inside the <span> I want to select the portion after the <br> so I can indent it.
.locations > ul > li:first-child > span:nth-child(2) {
background-color: #34678a; /*for testing purposes only */
text-indent:25px;
}
Here is the FIDDLE
And a little visual doesn't hurt ;)
CSS can't read the content of your elements and therefore has no idea where the <br> tag is. Target it instead with display:inline-block; and vertical-align:text-top;
jsFiddle example
You can use the following:
.locations > ul > li:first-child > span:nth-child(2) {
background-color: #34678a;
display:inline-block;
vertical-align:text-top;
}
You can't target the second part of the text using css (as it's not a separate element). However you can still indent the text by using a combination of padding and negative margins.
Example 1:
.locations li {
display: block;
padding-left: 65px;
}
.locations li strong {
margin-left: -65px;
}
Example 2 (all strong tags same width):
.locations li {
display: block;
padding-left: 70px;
}
.locations li strong {
margin-left: -70px;
width: 70px;
display:inline-block;
}

applying !important to all properties' values once

I am giving !important to all of the css propertis' values like this
.someclass{
color: #f00 !important;
background-color: #ff0 !important;
margin: 0 !important;
padding: 0 !important;
width: 100% !important;
display: block !important;
}
Is there any method to apply only once !important that all values get !important of .someclass?
Edit
suppose main div is controlled with some scripts and then how could I give !important to all at once.
No, but there is a better way. Make the selector more specific than the selector that you want to override. You can for example specify the element name in the selector to make it more specific:
div.someclass {
color: #f00;
background-color: #ff0;
margin: 0;
padding: 0;
width: 100%;
display: block;
}
Not only is it simpler, it's also possible to further override this with an even more specific selector. Adding !important only works in one level.
The specificity of a selector is basically calculated by the number of identifiers, the number of class names and the number of element names that it contains, in that order. For example a selector like div.item .cost with two class names and one element name is more specific than a selector like div span.count with one class name and two element names.
There is no way to do it. Write better selectors instead.
SHORT ANSWER: NO there is not (as far as i know);
LONG ANSWER:
the css has a very nice but sometimes annoying hierarchy system
first of all adding !important is not an adviced move it can do some harms to your page speed and may be some hard times in your next editting to find what cause something not work as it intended.
you can make something stronger priority by determining it with its ID or by making it a decendant like this:
.somediv > li > a {
color: #000;
background: #fff;
}
and it will over ride this:
a.something {
color: #fff;
background: #ff0;
}
and this will over ride both:
a#something {
color: #f00;
background: #0f0;
}
and these will override all but the second is stronger by the way:
a.something {
color: #0f0!important;
background: #00f!important;
}
a#something {
color: #0f0!important;
background: #00f!important;
}

CSS Inheritance - Why is a 'later' declaration being overwritten by an 'earlier' one?

I'm new to html and CSS but through the recent work I've been doing I thought I was getting a hold of how CSS works.. And it seemed to work kind of like scope in a language like Java.
My understanding was that, like Java, the declaration with the narrowest scope wins.. aka the most specific declaration would override its inherited versions, allowing you to, like I am trying to do, declare a set pattern for a group of objects and then if one of those needs a slightly different setting you can simply override the general rule for that one item.
However, I'm getting the feeling this is not the case, here I have a tabbed content box I'm working on;
The html:
<div id="feature-tabs">
<ul id="tabs">
<li>What We Do</li>
<li><a id="large" href="#What Makes Us Different">What Makes Us Different</a></li>
<li>Our Background</li>
<li>Why We Do It</li>
</ul>
</div>
And of course I labelled the one list-item as "large" so that I could force its width to be a little wider so it can fit on one line.
The CSS:
ul#tabs li a {
width: 144px; //TRYING TO OVERRIDE THIS DECLARATION
height: 33px;
color: #42454a;
background-color: #fff;
border-left: 1px solid #000;
border-right: 1px solid #000;
text-decoration: none;
display: block;
text-align: center;
border-radius: 3px;
}
a#large {
width: 155px; //WITH THIS ONE
display: block;
}
What is happening is that the width of a"large" is being overwritten by a. (144px not 155px)
So, two questions:
Is it possible to do what I am trying to do here-override an inherited trait?
Is it possible to simply vertically align each of the 4 tab's text to be centered? (This would make up for the ugly look I'm getting from the one button being two lines, where the rest are just one)
See Cascading. The order in which the CSS is encountered is only used as a final resort.
Both selectors have the same media type.
Both selectors have the same importance and origin.
The specificity of your selectors are different
ul#tabs li a a=0 b=1 c=0 d=3
a#large a=0 b=1 c=0 d=1
The top one is more specific, so it's the one that will get used.
But if you used ul#tabs li a#large, it would get selected because it has the highest specificity.
ul#tabs li a#large a=0 b=2 c=0 d=3
The CSS specifications define some 'rules of specificity' that determine which properties override others. This article covers the basics of it.
The selector ul#tabs li a is more specific than a#large and therefore the properties from a#large that are also in the other ruleset are ignored.
One workaround is to use !important:
a#large {
width: 155px !important; // !important gives this property precedence
display: block;
}