Is it possible to override the display property with its default value? For example if I have set it to none in one style, and I want to override it in a different with its default.
Or is the only way to find out what the default of that element is and then set it to that? Would like to not have to know if the element is usually block, inline or whichever...
A browser's default styles are defined in its user agent stylesheet, the sources of which you can find here. Unfortunately, the Cascading and Inheritance level 3 spec does not appear to propose a way to reset a style property to its browser default. However there are plans to reintroduce a keyword for this in Cascading and Inheritance level 4 — the working group simply hasn't settled on a name for this keyword yet (the link currently says revert, but it is not final). Information about browser support for revert can be found on caniuse.com.
While the level 3 spec does introduce an initial keyword, setting a property to its initial value resets it to its default value as defined by CSS, not as defined by the browser. The initial value of display is inline; this is specified here. The initial keyword refers to that value, not the browser default. The spec itself makes this note under the all property:
For example, if an author specifies all: initial on an element it will block all inheritance and reset all properties, as if no rules appeared in the author, user, or user-agent levels of the cascade.
This can be useful for the root element of a "widget" included in a page, which does not wish to inherit the styles of the outer page. Note, however, that any "default" style applied to that element (such as, e.g. display: block from the UA style sheet on block elements such as <div>) will also be blown away.
So I guess the only way right now using pure CSS is to look up the browser default value and set it manually to that:
div.foo { display: inline-block; }
div.foo.bar { display: block; }
(An alternative to the above would be div.foo:not(.bar) { display: inline-block; }, but that involves modifying the original selector rather than an override.)
If using javascript is allowed, you can set the display property to an empty string. This will cause it to use the default for that particular element.
var element = document.querySelector('span.selector');
// Set display to empty string to use default for that element
element.style.display = '';
Here is a link to a jsbin.
This is nice because you don't have to worry about the different types of display to revert to (block, inline, inline-block, table-cell, etc).
But, it requires javascript, so if you are looking for a css-only solution, then this is not the solution for you.
Note: This overrides inline styles, but not styles set in css
Unset display:
You can use the value unset which works in both Firefox and Chrome.
display: unset;
.foo { display: none; }
.foo.bar { display: unset; }
No, it is generally not possible. Once some CSS (or HTML) code sets a value for a property on an element, there is no way to undo it and tell the browser to use its default value.
It is of course possible to set a property a value that you expect to be the default value. This may work rather widely if you check the Rendering section of HTML5 CR, mostly reflecting what browsers actually do.
Still, the answer is “No”, because browsers may have whatever default values they like. You should analyze what was the reason for wanting to reset to defaults; the original problem may still be solvable.
What worked for me was revert!
revert resets the property to its inherited value if it inherits from its parent or to the default value established by the user agent's stylesheet.
If you have access to JavaScript, you can create an element and read its computed style.
function defaultValueOfCssPropertyForElement(cssPropertyName, elementTagName, opt_pseudoElement) {
var pseudoElement = opt_pseudoElement || null;
var element = document.createElement(elementTagName);
document.body.appendChild(element);
var computedStyle = getComputedStyle(element, pseudoElement)[cssPropertyName];
element.remove();
return computedStyle;
}
// Usage:
defaultValueOfCssPropertyForElement('display', 'div'); // Output: 'block'
defaultValueOfCssPropertyForElement('content', 'div', ':after'); // Output: 'none'
Concerning the answer by BoltClock and John, I personally had issues with the initial keyword when using IE11. It works fine in Chrome, but in IE it seems to have no effect.
According to this answer IE does not support the initial keyword:
Div display:initial not working as intended in ie10 and chrome 29
I tried setting it blank instead as suggested here:
how to revert back to normal after display:none for table row
This worked and was good enough for my scenario. Of course to set the real initial value the above answer is the only good one I could find.
According to my understanding to your question, as an example: you had a style at the beginning in style sheet (ex. background-color: red), then using java script you changed it to another style (ex. background-color: green), now you want to reset the style to its original value in style sheet (background-color: red) without mentioning or even knowing its value (ex. element.style.backgroundColor = 'red')...!
If I'm correct, I have a good solution for you which is using another class name for the element:
steps:
set the default styles in style sheet as usual according to your desire.
define a new class name in style sheet and add the new style you want.
when you want to trigger between styles, add the new class name to the element or remove it.
if you want to edit or set a new style, get the element by the new class name and edit the style as desired.
I hope this helps. Regards!
Related
I know there are many so-called "css resets", e.g.
https://ageek.dev/normalize-css,
https://meyerweb.com/eric/tools/css/reset/, or
https://elad2412.github.io/the-new-css-reset/
But what I don't understand is why it seems it is not possible to use something way more simpler.
As far as I know, the initial keyword resets a property to the value that is defined as the default value of that property in the CSS specification.
And since nowadays we have the all property-like keyword, I expected that I can use something like
* {
all: initial;
}
or
:root {
all: initial;
}
instead of all these reset.csss and normalize.csss. That is, I expected that one of these short snipets will help me to remove styles added to a web page from user agent stylesheet.
But it doesn't really work as I expected it. It seems that
:root, html, body {
all: initial
}
doesn't really remove styles "inherited" from user agent stylesheet at all, and
* {
all: initial
}
removes styles too aggressively. For example, it makes my style and script elements visible! I don't think that CSS specification says that these two elements should be visible. I'm sure that CSS specification says that they should be not visible. That is, it seems that
* {
all: initial
}
instead of resetting my styles to the CSS specification-level, resets them to the absolute-zero-level. This is not what I want.
Can anybody explain what is wrong in my understanding?
You are correct that initial resets to initial values for a given CSS property, but note that CSS properties have no initial value for each element-- they only have an initial value for that property, which will be the same for any and all elements it is applied to. For instance, the color property spec has a single initial value defined-- not a list of initial values to which it should be set for every element. So when you use it in conjunction with all, using:
* {
all: initial
}
...you are telling the browser to take every property of every single element and reset it to the property's default value. So, for instance, the display property spec defines its initial value as inline-- so every single element on your page will be displayed as inline.
I have the following HTML page:
<table>
<tr id="tr"></tr>
</table>
In Chrome DevTools' Console, I wrote the following code:
var tr = document.getElementById('tr');
var cs = getComputedStyle(tr);
cs.display;
"table-row"
As expected, the display defaults to 'table-row'.
I then set the display to none:
tr.style.display = 'none';
"none"
cs.display;
"none"
Again, that works as expected.
I then used 'unset' to unset the display style:
tr.style.display = 'unset';
"unset"
cs.display;
"inline"
I expected display to be 'table-row' again, but it becomes 'inline'.
I tried using 'revert' but got the same results:
tr.style.display = 'revert';
"revert"
cs.display;
"inline"
'inherit' doesn't work either:
tr.style.display = 'inherit';
"inherit"
cs.display;
"inline"
My question is: is this a bug? Shouldn't 'revert', 'initial', and 'unset' all set the display property back to its initial value?
Edit based on Danield's response
#Danield is right that revert is supposed to do what I had expected, but is not yet well supported. Safari does support revert:
In CSS, the 'initial' value is per property, i.e. it doesn't refer to the value which the user agent applied to it based on the type of element.
The initial value of the display property is inline.
See display - MDN :
Initial value inline
So no matter which element you are styling display: initial means display: inline.
Here's a simple example:
div {
display: initial;
width: 200px;
height: 200px;
background-color: red;
}
<div>hello</div>
In the above example we apply display: initial; to the div.
Even though the user agent applies display: block to a div, the result is display: inline (notice how the width and height is not applied) because the initial value of the display element is inline.
This also explains the why display: unset results in display: inline because
The unset CSS keyword resets a property to its inherited value if it
inherits from its parent, and to its initial value if not.(MDN)
Now since display isn't an inherited property -
Inherited no
display: unset is actually equivalent to display: initial
Now, regarding the revert value - this is the functionality which I believe the OP was looking for... see the spec regarding revert - one of the CSS-wide property values:
Rolls back the cascaded value to the user level, so that the specified
value is calculated as if no author-level rules were specified for
this property on this element. ...
However the problem is that revert value is currently not (well) supported.
Caniuse on revert actually nicely summarizes:
A CSS keyword value that resets a property's value to the default
specified by the browser in its UA stylesheet, as if the webpage had
not included any CSS. For example, display:revert on a <div> would
result in display:block. This is in contrast to the initial value,
which is simply defined on a per-property basis, and for display would
be inline.
"inline" is always the default property value for display in CSS regardless of the selector.
But read on...
I will now show you what happens when you apply the following property "reset" values on the display property, regardless of element selector in CSS. Keep in mind, except for "inherit", most versions of Internet Explorer (v.1-11) do not support these:
display:revert
display:unset
display:inherit
display:initial
Below are the results you should see applying various CSS "reset" property values to a "tr" element using the "display" property.
First or all, understand that every web browser and web agent comes with its own CSS style sheet, called a UA style sheet. HTML elements by default have NO styling whatsoever until you or your website assigns default values. However, all CSS properties still must default to a default value. That is where these new "reset" CSS property values come in...
This display: table-row style below is usually what browsers provide by default in their UA style sheets that come with the browser on install. You shouldn't have to assign this and why "tr" works as it does correctly in most browsers with no additional styles:
tr {
display: table-row;
}
Use "revert" if you want to remove whatever values your own styles might have applied to "tr" elements and default back to the CSS applied by the browser's UA style sheet shown above. In most cases this is what you want. Note: This only works in non-IE browsers, though, and what is worse, does not work in many versions of browsers prior to roughly 2018. But for those it does work in, it is helpful as it returns you to the browser's default styles for your table rows:
tr {
display: revert;
}
This style below would set "display" back to its "initial" setting or the default property value (regardless of the element and web browser). In most cases the default value for "display" in user-agents is "inline". BAD IDEA! Once you do that, you lose the browser's default values forever in the HTML render tree. This trips up most developers as it doesn't fall back to the browsers UA default style sheet as "revert" does above. Only works in non-IE browsers:
tr {
display: unset;
}
This style below is an atypical use of "display", as the property is not an inheritable property (like font, color, etc). This might have very weird consequences in the display as it would inherit any parent's cascade value for "display", which likely would be "table" in the case of "tr". "inherit" should work in IE and non-IE browsers, though. That is the only good quality of this property. Keep in mind many selectors default to inherit anyway, so its use is often redundant:
tr {
display: inherit;
}
Do NOT ever use "inherit" on non-inheritable CSS properties like "display" which affect HTML structure, design, layout, etc.
As above for "unset", this style below defaults to "inline" for the "display" property. Notice this overrides or rather erases the browser's typical set style for table rows which is "display:table-row". Once you use "initial", you have erased the browser's defaults and your own! Note: Unlike "revert", you cannot recover the browser's original UA style sheet when you use "initial". It is erased from the DOM tree that is painted and rendered in memory. Again, BAD IDEA! Not a wise choice to use unless you want to completely erase the browser's defaults for some reason. Again, this property value below only works in non-IE browsers:
tr {
display: initial;
}
Is it possible to override the display property with its default value? For example if I have set it to none in one style, and I want to override it in a different with its default.
Or is the only way to find out what the default of that element is and then set it to that? Would like to not have to know if the element is usually block, inline or whichever...
A browser's default styles are defined in its user agent stylesheet, the sources of which you can find here. Unfortunately, the Cascading and Inheritance level 3 spec does not appear to propose a way to reset a style property to its browser default. However there are plans to reintroduce a keyword for this in Cascading and Inheritance level 4 — the working group simply hasn't settled on a name for this keyword yet (the link currently says revert, but it is not final). Information about browser support for revert can be found on caniuse.com.
While the level 3 spec does introduce an initial keyword, setting a property to its initial value resets it to its default value as defined by CSS, not as defined by the browser. The initial value of display is inline; this is specified here. The initial keyword refers to that value, not the browser default. The spec itself makes this note under the all property:
For example, if an author specifies all: initial on an element it will block all inheritance and reset all properties, as if no rules appeared in the author, user, or user-agent levels of the cascade.
This can be useful for the root element of a "widget" included in a page, which does not wish to inherit the styles of the outer page. Note, however, that any "default" style applied to that element (such as, e.g. display: block from the UA style sheet on block elements such as <div>) will also be blown away.
So I guess the only way right now using pure CSS is to look up the browser default value and set it manually to that:
div.foo { display: inline-block; }
div.foo.bar { display: block; }
(An alternative to the above would be div.foo:not(.bar) { display: inline-block; }, but that involves modifying the original selector rather than an override.)
If using javascript is allowed, you can set the display property to an empty string. This will cause it to use the default for that particular element.
var element = document.querySelector('span.selector');
// Set display to empty string to use default for that element
element.style.display = '';
Here is a link to a jsbin.
This is nice because you don't have to worry about the different types of display to revert to (block, inline, inline-block, table-cell, etc).
But, it requires javascript, so if you are looking for a css-only solution, then this is not the solution for you.
Note: This overrides inline styles, but not styles set in css
Unset display:
You can use the value unset which works in both Firefox and Chrome.
display: unset;
.foo { display: none; }
.foo.bar { display: unset; }
No, it is generally not possible. Once some CSS (or HTML) code sets a value for a property on an element, there is no way to undo it and tell the browser to use its default value.
It is of course possible to set a property a value that you expect to be the default value. This may work rather widely if you check the Rendering section of HTML5 CR, mostly reflecting what browsers actually do.
Still, the answer is “No”, because browsers may have whatever default values they like. You should analyze what was the reason for wanting to reset to defaults; the original problem may still be solvable.
What worked for me was revert!
revert resets the property to its inherited value if it inherits from its parent or to the default value established by the user agent's stylesheet.
If you have access to JavaScript, you can create an element and read its computed style.
function defaultValueOfCssPropertyForElement(cssPropertyName, elementTagName, opt_pseudoElement) {
var pseudoElement = opt_pseudoElement || null;
var element = document.createElement(elementTagName);
document.body.appendChild(element);
var computedStyle = getComputedStyle(element, pseudoElement)[cssPropertyName];
element.remove();
return computedStyle;
}
// Usage:
defaultValueOfCssPropertyForElement('display', 'div'); // Output: 'block'
defaultValueOfCssPropertyForElement('content', 'div', ':after'); // Output: 'none'
Concerning the answer by BoltClock and John, I personally had issues with the initial keyword when using IE11. It works fine in Chrome, but in IE it seems to have no effect.
According to this answer IE does not support the initial keyword:
Div display:initial not working as intended in ie10 and chrome 29
I tried setting it blank instead as suggested here:
how to revert back to normal after display:none for table row
This worked and was good enough for my scenario. Of course to set the real initial value the above answer is the only good one I could find.
According to my understanding to your question, as an example: you had a style at the beginning in style sheet (ex. background-color: red), then using java script you changed it to another style (ex. background-color: green), now you want to reset the style to its original value in style sheet (background-color: red) without mentioning or even knowing its value (ex. element.style.backgroundColor = 'red')...!
If I'm correct, I have a good solution for you which is using another class name for the element:
steps:
set the default styles in style sheet as usual according to your desire.
define a new class name in style sheet and add the new style you want.
when you want to trigger between styles, add the new class name to the element or remove it.
if you want to edit or set a new style, get the element by the new class name and edit the style as desired.
I hope this helps. Regards!
I need to know what value/ css would be set when I use display: initial on non CSS3 compliant browsers ?
I'm hiding the class using display:none & need to show back, for which I intend to use display: initial (I dont want to use display:block if previously it was display:inline) but the hidden element must be shown on all browsers.
What happens by CSS 2.1 rules on error handling as well as in practice is that the declaration display: initial is ignored, without affecting the rest of the style sheet. The display property thus gets its value from other rules. In the absence of any setting on it in any style sheet (including browser default style sheet), the initial value inline is used.
The “fallback” code in the edit of your question means that the value of display would be inline in browsers that support the value inline, and block in other browsers. This does not sound safe.
The value initial does not mean “the previous value set in a style sheet” or anything like that, as the question seems to postulate. Instead, it means the value that is designated as the property’s initial value in CSS specifications. For display, this is inline.
Ok, I found that providing a fallback would be a safer option. So I use like below:
{
display: block;// just as fallback
display: initial;
}
there is "run-in" value for display property explained in W3C Schools page
EDIT:
run-in value is supported by Internet Explorer, and interpret the element whether it is block-level or inline-level.
I made an example jsFiddle Example .
Is it possible to override the display property with its default value? For example if I have set it to none in one style, and I want to override it in a different with its default.
Or is the only way to find out what the default of that element is and then set it to that? Would like to not have to know if the element is usually block, inline or whichever...
A browser's default styles are defined in its user agent stylesheet, the sources of which you can find here. Unfortunately, the Cascading and Inheritance level 3 spec does not appear to propose a way to reset a style property to its browser default. However there are plans to reintroduce a keyword for this in Cascading and Inheritance level 4 — the working group simply hasn't settled on a name for this keyword yet (the link currently says revert, but it is not final). Information about browser support for revert can be found on caniuse.com.
While the level 3 spec does introduce an initial keyword, setting a property to its initial value resets it to its default value as defined by CSS, not as defined by the browser. The initial value of display is inline; this is specified here. The initial keyword refers to that value, not the browser default. The spec itself makes this note under the all property:
For example, if an author specifies all: initial on an element it will block all inheritance and reset all properties, as if no rules appeared in the author, user, or user-agent levels of the cascade.
This can be useful for the root element of a "widget" included in a page, which does not wish to inherit the styles of the outer page. Note, however, that any "default" style applied to that element (such as, e.g. display: block from the UA style sheet on block elements such as <div>) will also be blown away.
So I guess the only way right now using pure CSS is to look up the browser default value and set it manually to that:
div.foo { display: inline-block; }
div.foo.bar { display: block; }
(An alternative to the above would be div.foo:not(.bar) { display: inline-block; }, but that involves modifying the original selector rather than an override.)
If using javascript is allowed, you can set the display property to an empty string. This will cause it to use the default for that particular element.
var element = document.querySelector('span.selector');
// Set display to empty string to use default for that element
element.style.display = '';
Here is a link to a jsbin.
This is nice because you don't have to worry about the different types of display to revert to (block, inline, inline-block, table-cell, etc).
But, it requires javascript, so if you are looking for a css-only solution, then this is not the solution for you.
Note: This overrides inline styles, but not styles set in css
Unset display:
You can use the value unset which works in both Firefox and Chrome.
display: unset;
.foo { display: none; }
.foo.bar { display: unset; }
No, it is generally not possible. Once some CSS (or HTML) code sets a value for a property on an element, there is no way to undo it and tell the browser to use its default value.
It is of course possible to set a property a value that you expect to be the default value. This may work rather widely if you check the Rendering section of HTML5 CR, mostly reflecting what browsers actually do.
Still, the answer is “No”, because browsers may have whatever default values they like. You should analyze what was the reason for wanting to reset to defaults; the original problem may still be solvable.
What worked for me was revert!
revert resets the property to its inherited value if it inherits from its parent or to the default value established by the user agent's stylesheet.
If you have access to JavaScript, you can create an element and read its computed style.
function defaultValueOfCssPropertyForElement(cssPropertyName, elementTagName, opt_pseudoElement) {
var pseudoElement = opt_pseudoElement || null;
var element = document.createElement(elementTagName);
document.body.appendChild(element);
var computedStyle = getComputedStyle(element, pseudoElement)[cssPropertyName];
element.remove();
return computedStyle;
}
// Usage:
defaultValueOfCssPropertyForElement('display', 'div'); // Output: 'block'
defaultValueOfCssPropertyForElement('content', 'div', ':after'); // Output: 'none'
Concerning the answer by BoltClock and John, I personally had issues with the initial keyword when using IE11. It works fine in Chrome, but in IE it seems to have no effect.
According to this answer IE does not support the initial keyword:
Div display:initial not working as intended in ie10 and chrome 29
I tried setting it blank instead as suggested here:
how to revert back to normal after display:none for table row
This worked and was good enough for my scenario. Of course to set the real initial value the above answer is the only good one I could find.
According to my understanding to your question, as an example: you had a style at the beginning in style sheet (ex. background-color: red), then using java script you changed it to another style (ex. background-color: green), now you want to reset the style to its original value in style sheet (background-color: red) without mentioning or even knowing its value (ex. element.style.backgroundColor = 'red')...!
If I'm correct, I have a good solution for you which is using another class name for the element:
steps:
set the default styles in style sheet as usual according to your desire.
define a new class name in style sheet and add the new style you want.
when you want to trigger between styles, add the new class name to the element or remove it.
if you want to edit or set a new style, get the element by the new class name and edit the style as desired.
I hope this helps. Regards!