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

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.

Related

What's the difference between :root and *?

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.

What is the difference between using "html{}" and "root:" pseudo-class while styling a css document? [duplicate]

I can't seem to find much information about this.
Smashing Magazine seems to be saying that html and :root are the same thing but surely there must be a tiny difference?
One technical difference between them is that :root - being a pseudo class has a greater specificity than html (a type selector)
:root {
color: red
}
html {
color: green;
}
<div>hello world</div>
So, in the above example, the :root selector overrides the html selector and the text appears red.
From the W3C wiki:
The :root pseudo-class represents an element that is the root of the document. In HTML, this is always the HTML element.
CSS is a general purpose styling language. It can be used with other document types, not only with HTML, it can be used with SVG for example.
From the specification (emphasis mine):
This specification defines Cascading Style Sheets, level 2 revision 1 (CSS 2.1). CSS 2.1 is a style sheet language that allows authors and users to attach style (e.g., fonts and spacing) to structured documents (e.g., HTML documents and XML applications).
For HTML documents, there is no difference - your root element is the <html> tag, so html{} and :root{} are (besides from a difference in specificity) semantically equivalent.
However, you can apply CSS not only to HTML, but all XML-like documents. That's why :root is there - to target the document's root element regardless of document type. Most people are confused by the difference because the overwhelmingly predominant use case for CSS is styling HTML documents.
Example:
You can style SVG documents with CSS. When styling it, your root element will (obviously;-)) not be html but svg. See the following list of SVG tags.
Another thing to consider is that it's technically possible to replace the root element using javascript:
<html>
<body>
<div id=test>
This will become the root element!
<style>
:root { text-decoration: underline; }
html { color: red; } /* this selector will stop working */
</style>
</div>
<button onclick=document.documentElement.replaceWith(test)>click to replace the root</button>
</body>
</html>

Reset all CSS for one element and its children

My Problem:
We offer full customization for our site to our customers (so they can make out app look like the rest of there site). They provide us a HTML "surround" page, which our main app is rendered into (no iFrame, the HTML of our app is string.replaced() server side essentially). They can include any JS and CSS links to style this "surround" page.
The problem is, they often include their main CSS file for there full website (totally unnecessary, but easiest method to make there part look right), which includes lots of generic rules. Our app then obviously then obeys these rules, and it breaks a lot of our default styles. Specific example, they have a 'h3' rule which sets text-transform and font-family
h3 {
text-transform: uppercase;
font-family: 'Fjalla One',sans-serif;
}
In our own CSS, we set a the font-family of a class that is applied to the h3 tag, but not the text-transform property. As such, our CSS changes the font-family, but we inherit the text-transform.
Is there any way I can tell the browser to "start again" with applying CSS from a given element? I know its very un-Cascading, but I need the users CSS to stop cascading past our apps first element, and then apply our CSS to that element and its children. I hope i've explained myself clearly.
Option 1:
Give them a class like remove-all-styles
.remove-all-styles {
all: revert;
}
Then write your css code below this css code and make sure your css has higher priority than their css file.
What is the order of loading the CSS files in a HTML page?
Option 2:
Give initial or auto values to all elements in css then write your css code below
https://www.w3schools.com/cssref/css_default_values.asp

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.

Should global css styles be set on the html element or the body element?

Sometimes I see people apply global css styles to html, sometimes I see them apply them to body, with both raw css and javascript.
Are there any differences between the two? Which is the standard to make a global css style? Is there anything I should know when picking between them?
I'm assuming that "global page styling" here refers to things such as fonts, colors and backgrounds.
Personally, I apply global page styling, for the most part, to body and the simple element selectors (p, h1, h2, h3..., input, img, etc). These elements are more closely related to the presentation of content of an HTML page to the user.
My rationale for this is simple: the presentational attributes bgcolor, background, text, topmargin, leftmargin and others were given to the body element, not the html element. These attributes are now converted to their respective CSS rules with extremely low precedence in the cascade:
The UA may choose to honor presentational attributes in an HTML source document. If so, these attributes are translated to the corresponding CSS rules with specificity equal to 0, and are treated as if they were inserted at the start of the author style sheet.
Most if not all implementations I'm aware of will convert these to CSS rules on body, based on their HTML equivalents. Others such as link, alink and vlink will become a:link, a:active and a:visited rules respectively.
Of course, it should be noted that CSS itself doesn't really have any semantics to it per se, as it's a styling language in itself which is completely separate from the content structure of an HTML document. Although the introduction to CSS2.1 covers the basics of styling an HTML document, note that the section calls itself non-normative (or informative); this means it doesn't set any hard and fast rules for CSS implementers to follow. Instead, it simply provides information for readers.
That said, certain styles may be applied to html to modify viewport behavior. For example, to hide the page scrollbars use:
html {
overflow: hidden;
}
You can also apply rules to both html and body for interesting effects; see the following questions for details and examples:
What's the difference in applying CSS to html, body, and *?
Applying a background to <html> and/or <body>
Note that html is not the viewport; the viewport establishes an initial containing block in which html is situated. That initial containing block cannot be targeted with CSS, because in HTML, the root element is html.
Note also that, technically, there is no difference between applying properties to html and body that are inherited by default, such as font-family and color.
Last but not least, here is an excellent article that details the differences between html and body in terms of CSS. In summary (quoted from its first section):
The html and body elements are distinct block-level entities, in a
parent/child relationship.
The html element's height and width are controlled by the browser window.
It is the html element which has (by default) overflow:auto, causing
scrollbars to appear when needed.
The body element is (by default) position:static, which means that
positioned children of it are
positioned relative to the html
element's coordinate system.
In almost all modern browsers, the built-in offset from the edge of the
page is applied through a margin on
the body element, not padding on the
html element.
As the root element, html is more closely associated with the browser viewport than body (which is why it says html has overflow: auto for scrollbars). Note however that the scrollbars are not necessarily generated by the html element itself. By default, it's the viewport that generates these scrollbars; the values of overflow are simply transferred (or propagated) between body, html, and the viewport, depending on which values you set. The details of all this are covered in the CSS2.1 spec, which says:
UAs must apply the 'overflow' property set on the root element to the viewport. When the root element is an HTML "HTML" element or an XHTML "html" element, and that element has an HTML "BODY" element or an XHTML "body" element as a child, user agents must instead apply the 'overflow' property from the first such child element to the viewport, if the value on the root element is 'visible'. The 'visible' value when used for the viewport must be interpreted as 'auto'. The element from which the value is propagated must have a used value for 'overflow' of 'visible'.
The last bullet point probably has its roots in the aforementioned topmargin and leftmargin attributes of the body element.
If you want to style only the content that'll be displayed, targeting the <body> element saves the style rules an unnecessary level of cascading.
Is there a reason you'd want to apply styles to the <title>, <meta>, <script> etc... tags? That would happen by targeting <html>.