How does a CSS rule override another CSS rule? - html

So, this is what I'm doing:
#id-form td {
padding: 0 0 10px 0;
}
#particular-td {
border: 1px solid black;
text-align: center;
background-color: #DFDFDF;
height: 30px;
padding: 10px;
}
I have a table #id-form, on which I set all tds to have padding-bottom: 10px.
But on one special occasion, I want a particular td to have padding: 10px in all directions, which I set in the #particular-td.
Obviously, I put the CSS styling in sequence in an external file.
But the rendered CSS only has padding-bottom, and padding: 10px appears to be overridden!?
Please explain:
How and why is this happening?
How should I arrange these rules to solve my problem (other than inline styling)?
EDIT: I removed 'table' before #id-form in table. I was never using this, I just mentioned it here to be able to explain it better.

Because of CSS Specificity. A selector's weighting is evaluated based on the components that make it up, with id's given a weighting of 100, classes with a weighting of 10, and element selectors with weighting of 1.
So in your example:
table#id-form td
Has a weighting of 102 (table#id is 101 and td is 1), whereas this:
#particular-td
Has a weighting of 100. If you change your second to this:
#id-form #particular-td
You will get a weighting of 200 which will override the previous selector. Only as a last resort should you ever use !important, as this pretty much prevents you from overriding it further down the line.

This has to do with specificity. table#id-form td is more specific than #particular-td. A rule with higher specificity has precedence over a rule with lower specificity.
Here are a few resources to get you started on understanding how it works:
Smashing Magazine article
W3C spec on specificity
Specificity calculator
About using !important, as suggested by others:
One might be tempted to use the !important keyword to sort this out, but that is rarely a good idea:
It becomes a pain to maintain/troubleshoot
It breaks the normal flow of CSS
The rule cannot be overridden by other rules later on
It might take a few minutes to read up on specificity, but it will be well worth the time spent when you've got a grasp of it.

You have two ways, either add !important after your padding for the particular-td:
padding: 10px !important;
OR, your selector altered like so:
table#id-form td#particular-td {
border: 1px solid black;
text-align: center;
background-color: #DFDFDF;
height: 30px;
padding: 10px;
}
Both are fine. Personally I don't like the use of !important if I can avoid it.

Try this code, I have added !important to your css, in this mode can ovveride padding of table#id-form td
#particular-td {
border: 1px solid black;
text-align: center;
background-color: #DFDFDF;
height: 30px;
padding: 10px !important;
}

Related

Angular Material ng-tns class changes margin of items in my table, can use CSS to change the margin but then another variant of ng-tns is applied?

I have an angular project where I'm using Angular Material and material table.
It seems that all the text in my table has the 10px margin top and bottom applied due to a class named something like: .ng-tns-c5-1 or .ng-tns-c6-1 etc.
I can't find a way to change those margins without inspecting element, finding that class and then using CSS to change that margin.
But after some changes to other elements on the app, the .ng-tns-c6-1 (for example) is changed to something like: .ng-tns-c4-0 and then I have to change that. The problem is I've done this 5-6 times now and it's a complete pain.
Because of that the table has a lot of useless white space and just overall makes things look bad.
What is that class and what can I do to make sure the margin remains at the 2-3px I'm setting?
This is the type of thing I have in my CSS:
.ng-tns-c5-1 {
margin-top: 2px !important;
margin-bottom: 2px !important;
}
.ng-tns-c5-0 {
margin-top: 2px !important;
margin-bottom: 2px !important;
}
.ng-tns-c6-1 {
margin-top: 2px !important;
margin-bottom: 2px !important;
}
.ng-tns-c4-0 {
margin-top: 2px !important;
margin-bottom: 2px !important;
}
You can use the following to select all the current and future elements.
[id*='ng-tns-c'] {
}

Wordpress remove CSS content with custom CSS

I'm using the most recent version of Wordpress in combination with a theme.
On that theme there is some css code I don't need/want and which makes my customized page look bad. This would be one example:
#content table {
border: 0;
margin: 0 0px 24px 0;
text-align: left;
width: 100%;
vertical-align: top;
}
#content tr {
vertical-align: top;
}
So far I always commented out such parts directly on the style.css of that theme. But like that I'll always loose my changes whenever I update that theme.
Now I've started to bring all my changes into the custom css directory of that theme. This works good for changes, however I have no idea how to remove the part I'm usually commenting out.
Any idea how to do that?
This question aims also to such changes where I'm commenting out parts of that style:
#content tr td {
border-top: 1px solid transparent;
/*
padding: 6px 24px;
vertical-align:top;
*/
}
Hopefully you understand what I mean :)
You need to create a child theme and then import the functions.php and style.css in it.
Then add your changes here.
You will never lose it whenever you will update your theme.
Please let me know if you want code too...
Since you are using a separate custom css file, commenting will obviously not work as your main css file will still contain some of the same style sets. So, to remove a style set entirely do the following on your custom CSS file.
#content table {
display:none!important;
}
You can do this for each style set or add them all together, separating them with a comma. i.e.
#content table, #content tr {
display:none!important;
}
In regards to the second part of your question, you can't remove just part of a style set but you can overwrite it by continuing to use the !important declaration and using opposite values such as changing padding from 24px to 0px if you don't want any padding. You will need to realign to your preference or set it to baseline which is the default. (Again, this goes in your custom css file)
#content tr td {
padding: 0px 0px!important;
vertical-align:baseline!important;
}
Notice that I didn't include border-top: 1px solid transparent; because your main CSS will still apply this part of the style so you only need to overwrite anything you don't want or wish to change on your custom CSS being that there is no way for you to comment style sets in the same manner as you would using a single CSS file.
If you've found it helpful please mark this as the accepted answer to your question. Thanks.

Padding in tables that are not border="0"

With CSS, I'm trying to add 5px padding to tables which do not have the border attribute set to "0". To do this, I'm able to select these tables like this, and test it by making the background color of them red:
table:not([border="0"]),table:not([border="0"])>tr,table:not([border="0"])>tr>td
{
background-color: red;
}
Also, this works to make all tables have padding:
td,th
{
padding: 5px;
}
However, I only want tables with borders to have padding, and this does not work:
table:not([border="0"]),table:not([border="0"])>tr,table:not([border="0"])>tr>td
{
padding: 5px;
}
Does anyone see an issue here? Thanks in advance.
EDIT: I see the code I posted above actually works, I didn't realize that I left out code that broke it, but this is what I tried to get working:
table:not([border="0"]),table:not([border="0"])>tr,table:not([border="0"])>tr>td
{
border: 1px solid rgba(0,0,0,.25);
border-collapse: collapse;
padding: 15px;
}
The border-collapse:collapse; property seems to be causing this problem. Is there any way to have single borders between cells and padding at the same time?
A <table> always has a <tbody> if you don't specify one explicitly in the HTML.
(It would be different in XHTML, but this is HTML, not XHTML.)
Solution: also specify the tbody in the CSS selectors.
table:not([border="0"]), table:not([border="0"])>tbody>tr, table:not([border="0"])>tbody>tr>td
{
padding:15px;
}
See fiddle
By the way, you could remove the middle selector (ending in tr) from the rule, because it doesn't do anything. You can't give padding to table rows.
You say it does work with the first example in your post, but that isn't entirely true. Only the first selector works, giving the whole table the red background, and the other two are ignored, so the cells remain transparent.
Oh, and it's best to not use the border attribute any more. There was a dispute between the WHATWG and the W3C about whether it was still valid, but they finally agreed that it was obsolete.

Some questions about CSS rules priority

I have the following CSS problem: a website first import a CSS style file named bootstrap.css (The BootStrap framework CSS settings), then it is imported another CSS file named my-custom-style.css that override some of the bootstrap.css settings (so I can create some custom settings leaving unchanged the bootstrap.css file)
Now I have the following situation, in the bootstrap.css file I have this property that I want to override:
.img-thumbnail {
background-color: #FFFFFF;
border: 1px solid #DDDDDD;
border-radius: 4px;
display: inline-block;
height: auto;
line-height: 1.42857;
max-width: 100%;
padding: 4px;
transition: all 0.2s ease-in-out 0s;
}
Now I have to override it in my my-custom-style.css file in such a way that the .img-thumbnail object have no border. So I delcare a
.img-thumbnail {
}
and I want to say to CSS that the following field (setted in the **bootstrap.css) must not exist in the overrided file (so I have not the border)
background-color: #FFFFFF;
border: 1px solid #DDDDDD;
border-radius: 4px;
height: auto;
Can I do something like this or have I to override it with a specific value?
I tryied to override it with a specific value but I can override the background-color with a new color value (and it work) but when I try to change the border value to 0px it still use the bootstrap.css definition
Can you help me to solve this problem? I think that exist an elegant way to simply say: "don't use the overrided file settings without explicitly override it with new values
Tnx
Andrea
Basically, the CSS engine will decide which rule to use based in 3 things (listed here in order of importance):
!important clauses
More specific rule
Rule order
Now, check out this fiddle.
First, let's talk about the order. We have:
div { background:green; }
and
div { background:gray; }
So, which background CSS will use? green or gray? They are both rules with no !important clauses, and have the same specification level (both are applied for div) only remaining the order to decide. In this case gray comes last so it will be applied to all div elements.
Now, the "specificness" of the rule.
#div1 { background: red; }
This one is a much more specific rule than the other rules that apply only to div elements. So #div1 will have a red background even with a div{ background: gray; } coming later.
And last, but not least !important.
These rules are... important. They can only be overridden by another !important rule that comes later and have the same specific level.
Even if a !important rules is declared in a lower level of specification, it won't be overridden. Like in:
div { width:50px !important; }
#div2 { border:3px solid blue; width: 100px; }
Even coming later and being more specific, width: 100px; will not be applied to #div2.
Now that you know all of this, it's a matter of inspecting the element to see what's going on and then guess "how much power" you'll need to override that rule.
yeah, just override that class in your own css file and add !important at the end

Need help CSS class referring to markup-tag

I'm working with Vaadin, a GWT like framework for developing rich web applications.
Now I want to set the padding of a generated HTML-tag element in my markup and I'm having big problems with it...
This is how the markup looks taken from Firebug:
The tags
v-formlayout-captioncell
v-formlayout-errorcell
v-formlayout-contentcell
all have padding-top: 12px and padding-bottom: 12px, I would really like to change this padding to 2px, but I can't seem to get it to work.
I've already tried these combinations among others:
.v-formlayout-captioncell td {
padding-top: 2px;
padding-bottom: 2px;
}
v-formlayout-row td {
padding-top: 2px;
padding-bottom: 2px;
}
.v-formlayout-row th,
.v-formlayout-row td {
padding-top: 2px;
padding-bottom: 2px;
}
But none of them does any impact on the padding... could someone with better knowledge about CSS and HTML than me please take a look at this and give their opinion on how a CSS class should be written to do what I want. If you want me to provide more information then please ask! =)
Thanks in advance!
EDIT: Thank you Taryn East for your nice and graspable answer, it definitely taught me something new about CSS syntax! However, it seemed like the biggest problem I was having was that the padding parameters I was adding was overridden by the browser. But by using the !important CSS flag and writing the class as such it was fixed:
.v-formlayout-row td {
padding-top: 2px !important;
padding-bottom: 2px !important;
}
If the class is in the td, then it should be:
td.v-formlayout-captioncell
the css here is saying is "find a td with the class 'v-formlayout-captioncell'"
By comparison, your css is saying: "find a td that is a descendant of something with the class 'v-formlayout-captioncell'"
Edit:
The reason why the formatrow isn't working is because CSS always picks the innermost style ie for
<tr class="a"><td class="b"></td></tr>
then anything in class b will override anything similar in class a.
In your case - the per-td padding was being set by an outside class, and you weren't overriding it with your 2px padding on the td... and any padding you were putting in the tr was simply being overridden by the outside-defined class on the td.
"important" fixes that because that gives it a priority to the tr styles that overrides the innermost-td style despite them being "more inner" - because they only have normal priority. However - this is kind of a bit of a hack that is unnecessary in your case.
The better-practise fix is just to use the td.v-formlayout-captioncell class