What's the difference between :root and *? - html

When we declare variable in CSS, why we do write:
:root
{
--bgcolor:orange;
}
/* instead of */
*
{
--bgcolor:orange;
}
What is the difference between both of those things?

:root is a pseudo selector that is equivalent to html 99% of the time, but with higher specificity (specificity equal to html + class).
:root selects the root element of the document based on it's format. It exists as CSS can be used in other document formats (SVG, XML).
* would apply the css to every element on the page. This is usually reserved for normalisation, fonts etc.

This is because :root is simply a pseudo selector for the <html> element. When setting CSS custom properties/vars, they are being set on the root element - think of it like a global variable.
If you use * (universal selector) - it's setting the custom property/var on EVERY element (e.g., div, p, span, ect.) in the DOM.
Using :root is simply allowing all children elements access to that property/var without the unnecessary overhead of computing that for all elements of a DOM.

Related

How is css specificity determined for elements with the same selector? [duplicate]

I'm trying to figure out why one of my css classes seems to override the other (and not the other way around)
Here I have two css classes
.smallbox {
background-color: white;
height: 75px;
width: 150px;
font-size:20px;
box-shadow: 0 0 10px #ccc;
font-family: inherit;
}
.smallbox-paysummary {
#extend .smallbox;
font-size:10px;
}
and in my view I call
<pre class = "span12 pre-scrollable smallbox-paysummary smallbox ">
The font (The overlapping element) shows up as 10px instead of 20 - could someone explain why this is the case?
There are several rules ( applied in this order ) :
inline css ( html style attribute ) overrides css rules in style tag and css file
a more specific selector takes precedence over a less specific one
rules that appear later in the code override earlier rules if both have the same specificity.
A css rule with !important always takes precedence.
In your case its rule 3 that applies.
Specificity for single selectors from highest to lowest:
ids (example: #main selects <div id="main">)
classes (ex.: .myclass), attribute selectors (ex.: [href=^https:]) and pseudo-classes (ex.: :hover)
elements (ex.: div) and pseudo-elements (ex.: ::before)
To compare the specificity of two combined selectors, compare the number of occurences of single selectors of each of the specificity groups above.
Example: compare #nav ul li a:hover to #nav ul li.active a::after
count the number of id selectors: there is one for each (#nav)
count the number of class selectors: there is one for each (:hover and .active)
count the number of element selectors: there are 3 (ul li a) for the first and 4 for the second (ul li a ::after), thus the second combined selector is more specific.
A good article about css selector specificity.
Here's a compilation of CSS styling order in a diagram, on which CSS rules has higher priority and take precedence over the rest:
Disclaimer: My team and I worked this piece out together with a blog post (https://vecta.io/blog/definitive-guide-to-css-styling-order) which I think will come in handy to all front-end developers.
What we are looking at here is called specificity as stated by Mozilla:
Specificity is the means by which browsers decide which CSS property
values are the most relevant to an element and, therefore, will be
applied. Specificity is based on the matching rules which are composed
of different sorts of CSS selectors.
Specificity is a weight that is applied to a given CSS declaration,
determined by the number of each selector type in the matching
selector. When multiple declarations have equal specificity, the last
declaration found in the CSS is applied to the element. Specificity
only applies when the same element is targeted by multiple
declarations. As per CSS rules, directly targeted elements will always
take precedence over rules which an element inherits from its
ancestor.
I like the 0-0-0 explanation at https://specifishity.com:
Quite descriptive the picture of the !important directive! But sometimes it's the only way to override the inline style attribute. So it's a best practice trying to avoid both.
The order in which the classes appear in the html element does not matter, what counts is the order in which the blocks appear in the style sheet.
In your case .smallbox-paysummary is defined after .smallbox hence the 10px precedence.
First of all, based on your #extend directive, it seems you're not using pure CSS, but a preprocessor such as SASS os Stylus.
Now, when we talk about "order of precedence" in CSS, there is a general rule involved: whatever rules set after other rules (in a top-down fashion) are applied. In your case, just by specifying .smallbox after .smallbox-paysummary you would be able to change the precedence of your rules.
However, if you wanna go a bit further, I suggest this reading: CSS cascade W3C specification. You will find that the precedence of a rule is based on:
The current media type;
Importance;
Origin;
Specificity of the selector, and finally our well-known rule:
Which one is latter specified.
Also important to note is that when you have two styles on an HTML element with equal precedence, the browser will give precedence to the styles that were written to the DOM last ... so if in the DOM:
<html>
<head>
<style>.container-ext { width: 100%; }</style>
<style>.container { width: 50px; }</style>
</head>
<body>
<div class="container container-ext">Hello World</div>
</body>
...the width of the div will be 50px
AS is state in W3:
W3 Cascade CSS
the orden that different style sheet are applied is the following (quote from W3 cascading section):
user agent declarations
user normal declarations
author normal declarations
author important declarations
user important declarations
More information about this in the referred W3 document
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)
Inline css ( html style attribute ) overrides css rules in style tag and css file
A more specific selector takes precedence over a less specific one.
Rules that appear later in the code override earlier rules if both have the same specificity.
In a simple and short way, one should keep in mind the two things below:
Inline CSS has a higher priority than embedded and external CSS.
So final Order is: Value defined as Important > Inline > id nesting > id > class nesting > class > tag nesting > tag

Add CSS variables (custom properties) in the root not in the document

I am working with angular 12 and I am creating dynamic theme change.
When my application is loaded according to the selected theme I set all my color variables like this:
document.documentElement.style.setProperty(colorKey, colorValue);
After it, all colors are set to the document element not to the root element.
As you see I also have some variables to the root element. But those variables are defined in the css file as:
:root {
--primary: #005d7a;
--primary-50: #edf1f2;
--primary-400: #0094bd;
--primary-700: #027498;
--secondary-50: #ffebb7;
--silver: #3a3a3a;
--silver-light: #e4e7ea;
--silver-light-border: #dad7d6;
--main-background: white;
--main-page-background: #e4e7ea;
--main-text-color: #3a3a3a;
--disabled-color: #ccc;
}
And that works fine.
My question is:
How to set other variables which are defined from the ts file to the root not to the document element ?
According to the post root selector is stronger than document. How then (as you can see on the image above) my root primary-50 color is overridden with document primary-50 ?
Nothing is set on the document. The documentElement is the root element.
You have a stylesheet that sets some things on :root, which is the html element in an HTML document.
i.e. :root in CSS targets the same element as document.documentElement in DOM.
You have some inline style (a style attribute) on the html element (which is the same element).
Cascading rules give rules in the style attribute priority over all other rules of equal importance and from the same source.
The document you reference says that the selector :root has higher specificity that the selector html. Neither of them have higher specificity than a style attribute.

Using custom CSS when there is no div ID

I'm running a website on Wordpress. Whenever I have to do CSS, I go onto Appearance > Custom CSS. To find the element I want to target I use the Inspect tool.
However on this instance there is no element ID. As this a small browser window for allowing card payment, I cannot find the div ID using Inspector.
IMAGES
Not OK to CSS
OK to CSS
You may want to give the CSS Selector documentation a read. There are many ways to select an element without a distinct Class or ID, including by attribute, type, and even Combinators (which are probably the best way to solve this problem you're having).
You can start be selecting an ancestor of the element you want, such as the.woocommerce wrapper.
You could then use the Direct Child Combinator: > and select the .order_details element.
Now you can use the Adjacent Sibling Combinator: + to select the div that is its adjacent sibling.
(Note that the adjacent sibling combinator is used here, not the General Sibling Combinator: ~, otherwise it would select all divs that are a later sibling of .order_details.
The following selector would probably be more than sufficient, and perhaps even a bit more specific than it needs to be (you may not need the >, but I put it in there for good measure - when using combinators on elements with no id or class, adding another layer of specificity usually doesn't hurt)
.woocommerce > .order_details + div { /* Styles here*/ }
If you're trying to override any of the inline styles on that div, you'll need to be more careful about the Specificity of the selector. Generally speaking there are 4 levels of specificity:
inline - ID - class - element
The Selector I gave you above has a specificity of 0021 (no inline, no ID, 2 classes, 1 element). However after your comment, it looks like you're trying to overwrite an inline style which has a gargantuan specificity of 1000. So if you apply any CSS that's not already defined inline, it should handily take effect. If you're changing any of the inline styles themselves, you'll need to make use of the _generally, but not always, bad-practice: !important Exception. Using !important will actually add a fifth order of magnitude to your specificity:
!important - inline - ID - class - element
So, if you're trying to change your inline background color, using the following:
.woocommerce > .order_details + div { background-color: #0095ee !important; }
Will give your blue background color an astounding 10021 specificity, which is higher than the inline grey's 01000.
Be very careful not to overuse !important - it's a tool that should be reserved for situations like this, and not just because you have a few CSS rules above that are slightly more specific.
Here's a handy CSS Specificity list, and a handy CSS Specificity calculator.

What is the difference between using the * universal selector and html?

Know this might be a ridiculous question but what is the difference between using the * universal selector, which I know applies to every single element on the page and using just html?
For example:
* {
margin: 0;
padding: 0;
}
and
html {
margin: 0;
padding: 0;
}
* wildcard is for all elements in page, doesn't matter what tag, classname, id or attribute it have.
html is only for <html> element.
Examples:
* {
color:red;
}
div {
color: green;
}
<p>this is red</p>
<p>this is red</p>
<div>this is red but styling specifically to green</div>
<p>this is red</p>
The obvious answer is that simply using the * {} wilcard selects all elements on the page (even including the html element and any other element whether they had a class, id or not).
Using the html tag as a selector simply targets the html tag.
The * wildcard is very useful in that you can also use it to target ALL children of other elements, ie:
.parent > * {
color: red;
}
The above means that any DIRECT descendant of .parent will have a font color of red. Similary, you can do .parent * {} to target all descendants of .parent, whether they're directly below, or a few levels below.
The Universal Selector
In CSS, you generally want to be as specific as possible, so using the universal selector is often not the best approach to take.
The Universal Selector * is going to apply the specific styles to every single element within the entire DOM, regardless of its tag. Additionally, the universal approach can interfere with default inheritance as more specific styles may still be overridden by the * style.
The HTML Selector
The html selector will only apply to the single <html> element that is present. This will still allow inheritance and specificity to function as expected (as it's merely targeting a single parent element and not all of the children individually).
Applying styles to html will work like with any other element and its children: styles trickle down from the top unless the child has its own definition.
With * you set the style for each element individually, so it's applied to each first level element, second level element and so forth.
An example of a practical difference is when using the > operator, which applies styles to direct children of the element:
* > p {
font-size: 12px;
}
Will set the font size to every p that's directly a child of any element in the DOM, regardless of how deep it is.
html > p {
font-size: 12px;
}
Will set the font size of every p that's directly a child of the html element, which would not happen, since body and head are usually the only children of html

CSS style does not apply, style depth limit?

I have the following problem:
I get a generated HTML with dynamic content. The IDs and the html tag-hierarchy is always the same. I can set a stylesheet.
I tried to set the color of the text to red. If I set it on this position where it's done in the screenshot it does not work. If I set it inline in the table below (table cols=2 border=0...) it works.
Is there a depth limit for CSS ? How can I set the color for the whole text containing the div (id=15B_gr or id=oReportCell) ?
++UPDATE++
I tried to set a stylesheet, but it does not work:
You should be able to target all the children of a div by using an asterisk. In this case:
#15B_gr * {
color:red;
}
or you could set it on just the elements:
#15B_gr span {
color:red;
}
** Edit for further information **
As pointed out by #nico o, some complications can arise due to having a number as the first character in the ID. Previous versions of the HTML spec did not allow IDs to begin with a number.
http://w3c.github.io/html-reference/datatypes.html#common.data.id
Maybe you have a rule (in another stylesheet?) which has a selector which has the elements class that you want to style but additionally the class name of an element of a parent or grandparent element. In this case that specific style would outweight your style.
In this case you could add an "!important" to your rule (color: red !important; ) ...
or you could add the selectors of the other stylesheets style to yours too so that that style doesn't outweight your's anymore.
You should "inspect" the element! (Rightclick on it, "inspect element") to find the active and overwritten rules for that specific element! You find those info in the lower right corner of the "inspector"-Window wich then opens. Along with the currently active styles you there find the stylesheet in which the styles are defined.