If someone walked up to me the other day and asked me what the difference between inherit
and initial
is, I may have replied:
“What, there’s a difference?”
I’ve been writing CSS for more than ten years, but I’ve somehow escaped understanding what exactly initial
is or does. Call it ignorance, laziness, or luck, but inherit
has gotten me by and I never thought to look up when initial
might be used instead. So, this post is gonna share some of the things I learned.
initial
means
What First off, the spec helps us understand the difference between an initial keyword and an initial value.
- Initial keyword: If the cascaded value of a property is the initial keyword, the property’s initial value becomes its specified value.
- Initial value: Each property has an initial value, defined in the property’s definition table. If the property is not an inherited property, and the cascade does not result in a value, then the specified value of the property is its initial value.
Umm, okay. I ran those definitions through Google Translate (joking!) and came out with this:
The initial keyword is what is declared as the property where the initial value is the resulting output, as defined by the browser default.
So, if the initial
keyword is used here:
.module {
color: initial;
}
…then the initial
value might return as black
, if black
is the browser default for that element’s property.
inherit
How it is different from If you’re thinking this sounds a lot like inherit
, then you’re absolutely right. It does sounds a heck of lot like that.
But initial
and inherit
are distinct in the extra step that inherit
takes to check whether there are other properties it can use in the cascade before it moves to the initial value.
An example of the difference
See the Pen CSS Initial vs. Inherit by CSS-Tricks (@css-tricks) on CodePen.
See that? The properties in the left box are all set to inherit the values of the .module
class since it the parent element. On the flip side, the properties in the right box are set to initial
, which resets the element’s properties to the browser defaults.
initial
When to use I like to think of initial
as a hard reset. It’s easy for styles to get convoluted as CSS grows, and using initial
is a way to clear things out so an element can go back to its natural state of being. If initial
were old-school Nintendo, I would use it as the equivalent to pulling out a buggy game cartridge from the console and blowing into it (even though doing so supposedly had no effect).
But that doesn’t mean initial
is a silver bullet for resets. That’s because initial values are still subject to browser defaults, which we know can vary from browser to browser.
Oh wait, you use CSS resets? You can expect those to be used as initial values instead.
Bottom line: I would use initial
to completely wipe out any inherited styles from an element and use inherit
to make sure the element takes its cues from the nearest parent.
A more practical use case
Here’s an example of how initial
can be used to create alternating colored lines in tables.
See the Pen CSS Initial by CSS-Tricks (@css-tricks) on CodePen.
Browser Support
MDN has a nice breakdown of the current support for initial
. Note the glaring lack of IE support.
Chrome | Safari | Firefox | Opera | IE | Android | iOS |
---|---|---|---|---|---|---|
Yes | Yes | 19 | 15 | No | Yes | Yes |
Wrapping Up
I’ve been racking my brain for some interesting use cases for initial
. While I see a lot of potential usefulness in being able to use default styles on an element, I just haven’t come across them in a practical application—though that could say a lot more about me than the property value itself.
Where this will come in real handy is when all
gains more support as a property. That would make declaring all: initial
a real powerful tool for creating resets on any element.
Please share any situations where initial
was something you had to use in a project. Bonus points if you’ve used it for any tricky feats.
“Going to” not “gonna”.
Woowoo, that’s the sound of the grammar police!
Oh boy, come on!
display: none
works for every element, and it’s useful when you want to hide something using a class.But what if you want to display it back with the correct value for a given element, without creating multiple selectors for each element?
That’s right, you could use
initial
.This, here, is precisely the reason I want
initial
to be supported everywhere.That is nice!
It’s also worth noting that
display: initial;
seems to always returndisplay: inline;
so there could be some funkiness there if not used carefully.Unfortunately, as Geoff point out, this nice use case wouldn’t actually work as you hope.
The
initial
value is defined for each property, (e.g., fordisplay
), not for any particular tag name (e.g.,li
). The association between HTML tag names and display types is applied via a browser style sheet, which is treated just as an ordinary CSS stylesheet that is run before processing any of your website’s styles. Those default styles get reset withinitial
just as much as your own code does.In contrast, there are a very small number of properties, such as
font-family
, where the specs don’t specify an initial value. In that case, the browser’s default is the initial value. However, if the browser applies different font families for headings versus paragraphs, that is again the browser style sheet, and aninitial
value will reset them both to the same overall default (whatever that may be).@Amelia: So the one use case I had for it is the use case it doesn’t work for? Ah well, there’s web dev for ya. Thank you for disabusing me of my hopes and dreams :D :D :D
It’d be great if there were yet another keyword for resetting to the browser default, along the lines of
to reset block-level elements to
block
, inline elements toinline
, etc.Is that true? My understanding was that it would still reset your styles to the browser default, not that which was set up in the reset stylesheet. I mean, I would love it if the latter were the case, and if it is, please, someone tell me so I can have at least one reason to be happy about CSS :)
I thought the exact same thing when I first started digging in, but found that CSS resets do indeed return as the value. You can play around with the example pen by adding a CSS reset and seeing how that impacts the style.
From what I can tell, initial will not use the values specified in reset. It may appear that it does, however, because the initial value for many properties is the same as what reset defines. This means that it just so happens to be the same as reset. Here is an example where initial is clearly not using the value defined in reset.
Paul’s correct. Although this would work in many cases, it is more by coincidence than design.
The point of most standard “CSS reset” techniques is to cancel out the browser’s default HTML stylesheet and instead set values to the CSS initial value. In these cases, you could use
initial
and get the same effect.However, if you use any other type of CSS reset (to a value other than the initial value defined in the specs), you can’t recreate that with
initial
. For example, if you use a reset to changebox-sizing
toborder-box
on every element and before/after pseudo-element, that’s very different frombox-sizing: initial
.Total lack of IE support makes it pointless.
Agreed, this makes IE pointless.
The IE team was/is sleeping all the time. When the great browsers are on to something, IE was/is nowhere to be seen!
IE is terrible. No doubt. But if they don’t support it, you can’t really use it. I hate it, but it is the way it is.
Some of the diagrams and prose in this post are a little misleading.
initial
is not equivalent to inheriting from:root
, and it is not always the “browser default” either.The initial value is independant of any values set in the cascade, including defaults set by the user-agent stylesheet! Case in point, the
initial
value in the above example pen causes the inner div to be inline instead of bock-level.I can certainly see that, though the diagrams are illustrating a scenario rather than all cases. You are certainly correct here, though!
I found this:
Source
Looks like it resets to a value defined by the specifications, don’t matter what’s the default value of the element. So
display
will beinline
toa
,div
,table
and evenoption
. To me it’s basically useless.This article seems to have a fundamental misunderstanding of ‘initial’. It is nothing like ‘inherit’, and it has nothing to with what properties are set on the root, aside from the root not being commonly styled much.
‘Initial’ is just the value of a property before any value is set by a style sheet, whether it is a browser (aka “UA”) style sheet, author (web designer or developer) style sheet, or user style sheet.
The UA style sheet can be thought of as the “browser defaults”, and can vary much more from browser to browser. Those variations are mostly eliminated by reset stylesheets, which also remove a lot of useful values, like margins on paragraphs.
But all conformant browsers start with the initial value as defined in the spec. That’s why the UA style sheet has ‘div { display: block }’, but they don’t need a ‘span { display: inline }’, since inline is already the “default” initial value for the ‘display’ property anyway, regardless of what the element is, until a stylesheet sets it to something else.
‘Inherit’ on the other hand, means that the value is taken from the parent element in the HTML. Some properties, like ‘color’ inherit automatically, without having to set anything in the style sheet. That’s why if you have ‘color: green’ on a P tag, you don’t also have to set it on a SPAN inside the P (unless you are worried that the UA stylesheet has a color explicitly set for SPANs, but that is never the case).
If you use the ‘inherit’ keyword as a value, it forces inheritance of the value from the parent, even if it is a property that doesn’t normally inherit automatically, such as ‘float’. So if you had ‘float: inherit’ on element A, and the parent B of that element A had ‘float: left’, then element A would also float to the left inside the floating element B.
@Brad You are quite correct, except for one, slightly confusing thing: the
initial
andinherit
keywords are similar in the specification, and are in fact defined in the same place. This is because they both override the usual rules for determining the value of a property. I believe this similarity of specification has led to a belief of similarity of function.@tom I don’t think it is really accurate to say they “override the usual rules for determining the value of a property”. The keywords give a value to a property, same as any value does. Whether or not “initial” or “inherit” keywords have an effect still depends on selector specificity and order, whether or not ” !important” is there, and with author style sheets overriding UA style sheets, same as any other value.
What makes keyword values different from most others is that the used value varies from the specified value (not in itself unusual), but with “initial” getting its used value from the property’s initial value (as defined in the specification of the property), and “inherit” getting its used value from whatever its HTML parent’s used value. Those two effects are very different from each other, but they use keywords the same as any property would use a keyword, such as “none” or “solid”. All keyword values assign some meaningful value that generally depends on the property, and so do these. They both begin with the letter “i”, which I suppose can make it easier to confuse them.
The fact that they are defined in the same spec doesn’t make them similar, any more than “border” is similar to “background” because they are in the same spec. Nor are “solid” and “none” are similar (as border styles), just because they apply to the same properties in the same spec and are defined in close proximity to each other. The main thing that makes “initial” and “inherit” similar is that they can apply to any property.
To truly understand what these two keywords do when assigned to a property, you just have to understand what they mean as concepts. The meaning exist regardless of whether or not there was ever a keyword that could be used as a property value. I think some people get confused because the keyword is something you can set. But even when not set, all properties have an initial value and many, many properties inherit anyway. Having an initial value prior to any CSS rules applying is a very different concept than looking at the HTML hierarchy to see if the parent element has a property value (like color or font size) that also should apply to the child. Once you understand those two concepts, then the meaning of the keywords you can use should be very clear and distinct.
@Brad Both
initial
andinherit
are keywords that are valid results of the cascade for any property, but moreover they are handled specially when computing the specified value; from the Cascade Level 3 working draft:That’s what I mean by saying they are similar. What I meant by “override the usual rules” was just that usually the specified value of a property is the same as its cascaded value (if it has one); the exception is if the cascaded value is
inherit
orinitial
. As you say, this is not an override in the sense of!important
, so perhaps that was my bad wording; I just meant the use of these keywords if they are the result of the cascade changes how the value of the property is computed.@Tom, OK, but know that having a used value that is different from the specified value is not at all unusual. For instance: ‘width’ can have values specified as ‘auto’ or a percentage, but the used value will be a concrete length measured in px.
@Brad
Absolutely, yes. The unusual thing about
initial
is that it sets the specified value to be different from the cascaded value. So the HTML<div style="width: initial;"></div>
(assuming no other CSS) would give the width property on thatdiv
a cascaded value of “initial”, a specified value of “auto”, and a computed value of some concrete width in px.Seems like it could be more rope with which to hang ourselves.
That said, I’ll take it. Perfect for those times when only the browser’s default Times New Roman will do!
I didn’t know this, I’ve only ever used ‘inherit’ so it’s nice to know exactly what ‘initial’ does.
I hesitate to say it, because I think you know more about CSS than I ever will, but I think you’ve missed the point of
initial
. The initial value exists because there needs to be some default for all possible values. The CSS specification cannot assume that there are any user-agent style sheets, so it needs to define a default value for all possible properties. These are mostly what you would expect, but there are some quirks. Because these are default values and do not reference any kind of selector, they are the same for all elements at all times. For example, as noted in a comment above, the initial value fordisplay
isinline
, which makes sense forspan
elements, but not so much fordiv
orp
. (You can see a list of initial values in section 4.1 of the Spec).So your Google translation of the spec isn’t quite right. A better description would be:
(Note there are some additional complications: you will see in the table that some of the initial values are listed as user-agent specific; however, this is separate from any user-agent style sheets, and is best thought of as a hard-coded default of the browser. Additionally, I’ve glossed over the difference between the specified value and computed value, which is important because the
initial
keyword actually sets the specified value.)So why would you use
initial
? I honestly can’t think of a real reason, outside of curiosity. It certainly can’t be used as a hard reset; from the point of view of the CSS parser, there’s no difference betweenp { display: initial; }
andp { display: inline; }
, so why would you use the less readable version?One actually practical solution is to use initial to restore font-size after applying zero font-size trick to get rid of white space between inline-block elements.
If HTML root element size is left untouched then the end result should be about always the same: skipped inheritance. In this particular context initial gives at least slightly better explanation on what is happening.
Of course these days this is quite a bit of a niche case: it requires template based JS DOM usage or manually written HTML. Modern tools for DOM management like React or Mithril are white space free by design.
Very nice summary! I think you’re spot on here and, at best, the use case is fuzzy to me as well. The funny thing is that while spec cannot assume user-agent stylesheets, the fact is that they are used predominantly throughout. That would mean a better (more inclusive) definition might be:
I scratched my head for a good use case as well. Perhaps that’s why I’m only just getting acquainted with
initial
and have gotten by without it for so long. :)A good time to use
initial
is when developing a widget or web component that will be used in a variety of environments. Doin#my-widget * { whatever: initial; }
is a lot easier than making a widget-specific reset sheet.Variety of Environments do exclude any IE (Desktop or mobile) then? What use is it then?
I (try ;) to use only properties which are either supported everywhere OR which have no desatrous effect if not used. But using initial potentially can mess up a layout completely so actually is not safe to use IMHO.
Excluding IE is a pretty good use case, though not intended by the spec writers. For instance, ‘display:none; display:initial’ will hide something in IE, while displaying it as ‘inline’ for all other browsers.
This list is really awesome. This is my first time visit to your blog and i was really very impressed with your article. also you can see may official blog … Thank you.
http://www.1bag.co/
Something I miss from These articles is a warning to maybe not use These properties which can be very harmful on Browsers which do not support them. In a lot of cases like here too this may be IE but there are other cases too like Display table in Firefox (positioning issue) or transform quirks in Chrome or Background-size values in (<9?) Safari.
In combination with selective testing on only some Browsers in mostly one platform this can lead to sites simply not working everywhere and that is what the web is about, or is it?
I actually saw an example of of a lesser experience Developer using initial for “Position” which totally messed up layout in IE where it would have been easy to just use something like Position: static or so to make it working in (almost ;) every browser.
Sorry but TBH, I blame sites like CodePen to a certain extend, as they tend to write about new and admittedly exciting new stuff but failing to properly warn about Problems in older or less capable Browsers (which is NOT always IE BTW).
I recently struggled with this issue as I believe
initial
did as you suggested. Reset the value back to the browser default for that element.But it actually resets the property not the element.
See initial value for display is
inline
as defined here. https://developer.mozilla.org/en-US/docs/Web/CSS/displaySee the example xGrzYx by Jack McNicol (@jackmcpickle) on CodePen.
Just to be clear: “inherit” does not set the value back to the element default either. It sets it to the parent element’s value for that property.
@Brad Kemper: Using display: initial to hide something from e.g. IE (but guess also older browsers like Androids, Opera Minis?) sounds like a horrible hack. No fallback whatsoever I guess? :(
Doesn’t sound like a good idea to me. If you do that, what are you really testing? “Show this content only to those browsers that understand the
initial
keyword?” There are a lot better ways to do capability testing or user agent sniffing.