What CSS properties can be applied to which HTML elements - html

I'm looking for a source/spec that can tell me what CSS properties can applied to which HTML elements. For instance, the css property; "overflow". I know I can apply this to div, p, textarea but what other elements can I apply this too? Is there a spec somewhere I can reference?

See http://www.w3.org/TR/CSS2/ and http://www.w3.org/TR/CSS/.
For example, regarding your question about the overflow property, see:
http://www.w3.org/TR/CSS2/visufx.html#overflow-clipping, stating:
'overflow'
Value: visible | hidden | scroll | auto | inherit
Initial: visible
Applies to: block-level and replaced elements
Inherited: no
Percentages: N/A
Media: visual

In the CSS processing model, every element has every property that is applicable to the target media type. For example, even the empty <br> element has the color property. But whether a property has an effect on the rendering of the element itself depends on the specific property and the context, in a manner that is described in applicable CSS specifications and drafts. It is usually described under an “Applies to” heading. There is no combined compilation of this, and the set of properties recognized by browsers varies considerably.
Even though a property “applies to” an element by the specifications, it need not have an actual effect. For example, border-color is irrelevant for the rendering of an element if its border-style is none or its border-width is 0. (The value may still matter if it is inherited by child elements.)

Any CSS property can be applied to any HTML element; they don't restrict each other.
However, as Aron Rotteveel mentioned, the element will have to be either a replaced element (like img), or specified to be block-level. That mean that the following is perfectly fine CSS:
strong { display: block; height: 5em; width: 5em; overflow: scroll; }

You could always use the official spec. The answer to your particular question is here.

Related

Why do the MDN docs state that the initial display value for all elements is inline?

This is clearly not the case as each element can have it's own default.
See here:
https://developer.mozilla.org/en-US/docs/Web/CSS/display
Initial value: inline
Applies to: all elements
And of course contradicting documentation which seems more correct in this case.
https://www.w3schools.com/css/css_display_visibility.asp
Is there something I'm missing here?
It seems to clearly state that "all elements" have "initial value" set to inline.
First of all w3schools isn't the official Documentation, W3C is!
TL:DR: You are confusing things -- The initial value of the property which is inline and to which elements the property applies (no matter the value it has)
They are not related.
Here is the official Documentation about it
Which match MDN Docs.
And yes the initial value of display is inline the line below (in your question) says it can apply display property to all elements, which is true and not starting "all elements" with inline, because if you read the MDN Docs you see this:
The display CSS property specifies the type of rendering box used for
an element. In HTML, default display property values are taken from
behaviors described in the HTML specifications or from the
browser/user default stylesheet. The default value in XML is inline,
including SVG elements.
(Emphasizes is mine)
And what that line means is any browser/user-agent are free to set the initial value of the element as they think it is better.
N.B. Remember that by initial value means using initial value itself, so whenever you set display:initial it will became display:inline as per the Documentation above states.
Initial value: inline
...states that official recommendation for user agents is to interpret display:initial as display:inline, not as the default value for the type of element (i.e. block for <div>, inline-block for <span>, etc...).
So, in practice, setting display:initial; on a <div> will apply display:inline; to it in user agents respecting the standard recommendation, instead of display:block; as most developers would be tempted to assume. Setting display:initial; on any element should be interpreted as display:inline. That is what it means.
Ultimately, this is useful as it reduces ambiguity around a complex attribute, such as display.
As for why does MDN provide this information, generally speaking, there are very few (if any) contradictions between MDN and W3C/official sources, which makes it a valuable and reliable resource. Its main quality is it presents the information in a more accessible format (than the official docs) for people without a solid background on web technologies/concepts.
Personally, besides reading the articles/examples themselves, I find myself using it a lot as the fastest way to get the full list of official resources about any web concept, as you'll always find the links at the end of the MDN article on the subject (where applicable).
Those two things aren't related.
The initial value of a property refers to the CSS-defined default value for that property. Every single CSS property has an initial value, regardless of element type, because CSS properties aren't tied to elements of any document language in any way. This initial value is intended as a default value for unrecognized elements, to guarantee that every element has a value for every property for the purposes of the cascade and therefore ensure that a browser knows how to render that unrecognized element as it encounters it.
The so-called "default value" of a property is just an arbitrary value set by a browser in its UA default stylesheet. The HTML5 spec contains a reference document on what default values should apply to what HTML elements, which browsers follow mostly, but this is completely unrelated to CSS's concept of an initial value (nor does it contradict its definition of initial value, because it defines default styles separately as "user-agent-level styles").
"Applies to", on the other hand, is unrelated to the initial value. Even if a property only applies to certain types of elements, those elements will always have every single CSS property, including properties that don't apply to them. What "Applies to" actually means is "Has effect on". If a property doesn't apply to an element, it simply means that it has no effect.
For example, you may find that the flex property only applies to flex items. However, every single element has a flex property, regardless of whether it's actually a flex item, and they pretty much all have its initial value simply because I'm not aware of any UA styles altering its value from the initial value for any element. You could still set an arbitrary value on an element that isn't a flex item, and it simply would have no effect — but you could, for example, force flex items that are children of this element to inherit this value with flex: inherit (you wouldn't actually do this, I'm just stating an example).
In fact, a real-world example of this exists in the ul and ol elements — many authors (including myself) set list styles on those elements, when really the list markers you see belong to their li children that are inheriting their list styles, since list styles only apply to list-items and ul and ol are not themselves list items.
And as mentioned, W3Schools isn't official documentation. To save you any more confusion, assume W3Schools does not exist. Continue using MDN if it is easier to understand, but always cross-reference with the official specs located at w3.org and whatwg.org (which MDN usually does a good job linking to, it pretty much never links to W3Schools).
Each user agent(browser) applies a default style sheet for an HTML page. You can see in the default HTML4 style sheet:
dir, hr, menu, pre { display: block; unicode-bidi: embed }
li { display: list-item }
head { display: none }
...
The default display property is changed depending on the element.
That would be true for a native xhtml browser. HTML browser is something else completely, it doesn't have to wait for separate instructions. In HTML all known elements have their display rendering predefined by default.
(Which of course can be overridden).
There were browsers which didn't support styles at all. HTML tags are semantic. All xhtml is generic and of course to it all tags are equally [unknown] and indiscriminately inline by default.

How should the content property inherit into a :before or :after pseudo-element from its container?

Consider this HTML/CSS scenario:
p { content:'x'; }
p:before, p:after { content:inherit; }
<p></p>
In Firefox, 'xx' will be displayed. In Chrome and in IE nothing is displayed.
In assessing what I think should happen, I've taken into account the following snippets from the CSS 2.1 spec:
12.1 The :before and :after pseudo-elements
The :before and :after pseudo-elements inherit any inheritable
properties from the element in the document tree to which they are
attached.
So, in general, inheriting a property into a :before and :after pseudo-elements from their containing element should work (and it does work for other properties).
12.2 The 'content' property
'content'
Value: normal | none | [ | | | attr() | open-quote | close-quote | no-open-quote |
no-close-quote ]+ | inherit
So "inherit" is a valid value for the content property
Computed value: On elements, always computes to 'normal'. On :before and :after, if 'normal' is specified, computes to 'none'. Otherwise, for URI values, the absolute URI; for attr() values, the resulting string; for other keywords, as specified.
The important thing here is that this discusses the computed value of the property. Also note that the computed value for elements like the <p> element in the example should be normal
Applies to: :before and :after pseudo-elements
1.4.2.3 Applies to
This part lists the elements to which the property applies. All
elements are considered to have all properties, but some properties
have no rendering effect on some types of elements. ...
So "applies to" is a rendering rule, and does not determine whether the property is meaningful for the element, because all CSS properties are always meaningful.
6.2.1 The 'inherit' value
Each property may also have a cascaded value of 'inherit', which means
that, for a given element, the property takes the same specified value
as the property for the element's parent. The 'inherit' value can be
used to enforce inheritance of values, and it can also be used on
properties that are not normally inherited.
Note that it is the specified value that is inherited, not the computed value. For the <p> element of the example, the specified value of the content property is "x".
Now, in IE's DOM inspector, the computed value of the content for the p element is normal, taken from a specified value of "x". This seems correct to the spec, but the specified value is not being inherited by the pseudo-elements.
In Chrome's DOM inspector, the computed value of the content for the p element is not shown at all! Why Chrome should omit any property is unknown to me. Calling window.getComputedStyle(el).content on the element returns "x". As with Firefox, the seems to be incorrect to the spec.
In Firefox's DOM inspector, the computed value of content for the p element is "x". This seems incorrect according to the spec, which says that the computed value should be normal. However, the specified value is being inherited by the pseudo-elements.
So I conclude that all three of Firefox, IE, and Chrome's behaviour are in some way bugged, but that Firefox is correct in displaying "xx" for the example scenario.
Have I missed anything relevant?
According to this gentleman's answer as to what styles can be inherited, content is not a property that inherits.
Which CSS properties are inherited?
Also on the w3.org website you referenced, there is no description for how the inherit property ought to be handled, while there is a note on all the other possible values, it seems `
> [ <string> | <uri> | <counter> | attr(<identifier>) | open-quote |
> close-quote | no-open-quote | no-close-quote ]+`
To me this implies inherit may be a valid value, but it has no real use. Or it may be a typo...?
It seems some browsers do operate on the inherit value, but it appears inconsistent and unreliable, and therefore I'd suggest avoiding it. You can probably achieve much the same thing with a data attribute.
One caveat I'll add to that, is that considering how the layering works with pseudo elements, I'd perhaps expect the :after pseudo element to inherit the content of :before, if :before sets it's content in some other way.
https://css-tricks.com/pseudo-element-roundup/
However no browser behaves this way right now. If you try this fiddle, firefox is the only one you see something in after, and it's inheriting from the base element.
http://jsfiddle.net/8Lsp7c7j/1/

How to prevent inheritance of any css style of parent node to child node?

Assume a body node having a child node (e.g. div).
There may be css styles attached to the body, which are not known in advance (they are specific to an arbitrary page accessible on the WWW).
The child node (e.g. div) has a bunch of css styles which are static.
How to prevent css styles of the parent to "influence" styling of the child?
There is no generic way. You need to set a value (other than inherit) for every property that has inherit as the default value.
Even that won't prevent all influence.
e.g.
body { width: 300px; }
div { width: auto; }
The width of the div is influenced by the width of the body.
You could use values initial (compatibility: not supported by IE at all) and unset (Fx27+ only)
The initial CSS keyword applies the initial value of a property to an element. It is allowed on every CSS property and causes the element for which it is specified to use the initial value of the property.
where initial value means:
The initial value given in the summary of the definition of each CSS property has different meaning for inherited and non-inherited properties.
For inherited properties, the initial value is used, for the root element only, when no value is specified for the element.
For non-inherited properties the initial value is used, for any element, when no value is specified for the element.
Source for links and quotes: MDN
Relevant polyfill: https://stackoverflow.com/a/15903168/137626 (brace yourself)
You could reset all properties to desired defaults in the child div like this.
div *{
property1:default;
....
propertyx:deafult;
}

HTML element which defaults to display:inline-block?

<div> defaults to block
<span> defaults to inline
Is there one that defaults to inline-block?
If not, what special tag name would be appropriate for me to apply 'inline-block' using CSS?
Or should I stick to using a class?
From what I can tell the <img> tag is the only inline-block by default. To be on the safe side I would recommend a class, you never know when changing all elements of a certain type will come back to bite you. Or, you could always make up your own tag and assign display:inline-block; to it. This way you aren't changing the default functionality of standard elements...
EDIT
It also appears that button, textarea, input, and select elements are also inline-block
Sources:
According to this img is inline-block http://dev.w3.org/html5/markup/img.html#img-display
And here claims that button, textarea, etc. are as well: http://www.w3.org/TR/CSS2/sample.html
EDIT #2
While the source above claims that img tags are inline-block it seems (thanks to Alohci) that they are just inline http://jsfiddle.net/AQ2yp/
The following were tested in Firefox:
button is inline-block: http://jsfiddle.net/GLS4P/
textarea is inline: http://jsfiddle.net/235vc/
input is inline: http://jsfiddle.net/RFKe8/
select is inline-block: http://jsfiddle.net/5B4Gs/
Is there one that defaults to inline-block?
Strictly speaking, no there isn't. The W3 HTML specifications do not ever specify default CSS property values for any elements. They do provide a "default style sheet" for HTML 4, but developers are only encouraged to use it - it is not a requirement or any sort of mandate. The HTML 5 specifications indicate "typical default display properties" but, again, those are not required (also keep in mind that HTML 5 is still a working draft anyways).
So that leaves all default values up to the browser and how the developers actually feel elements should be displayed to a user. No one can guarantee that a specific element will display as inline-block or any other way in someone's browser. You should always explicitly set that if you want it to happen. Don't rely on "defaults."
If not, what special tag name would be appropriate for me to apply 'inline-block' using CSS? Or should I stick to using a class?
This is up to you and how you are designing your pages. You should always use elements that are semantically appropriate to the content contained within them. If the element will always be used in a context which will require inline-block display, by all means set it to that in your style sheet. Otherwise, you will have to resort to classes or more specific selectors in order to make your elements display properly.
Here is a Fiddle that gets the default display value for a majority of HTML tags.
Fiddle
In chrome, the default inline-block elements are: "INPUT", "BUTTON", "TEXTAREA", "SELECT"
My solution to this is declaring what I call a slice.
CSS
sl {
display: inline-block;
}
Usage
<sl>inline block stuff</sl>
You can check my codepen with all HTML elements and their display property by default. Some tags are syntax-broken, but it does not matter for our purpose.
Currently, there are 5 elements with display: inline-block in FF :
<button>
<select>
<meter>
<progress>
<marquee>
And additional 2 (including 5 above) in Chrome:
textarea
input
In principle, it depends on the browser what the default value for the display property is for each element. Even HTML5 drafts do not prescribe what values must be used, though it presents “expected rendering” of elements in terms of CSS.
According the default style sheet for HTML in the CSS 2.1 specification, the elements that have display: inline-block by default are button, input, select, and textarea. Browsers use such settings, except that in Firefox, this only applies to button and select.
In the Rendering section of HTML5 CR, the meter and progress elements are additionally describes as having inline block as “expected rendering”, and browsers that have implemented these elements appear to behave that way. The keygen element is also described as being an inline block, but Firefox does not do that (it implemented keygen internally as select in the DOM); IE does not support keygen at all; Chrome implements it as suggested.
Since all of these elements have rather specialized meanings, functionality, and rendering idiosyncracies, none of them is adequate for general use as an element that is an inline block by default and may have various meanings. What you can use for such an element is normally span or div, depending on whether you prefer inline or block as the default rendering.
Now you can create a Custom Element (for example: <inline-block> or whatever) that will have its CSS property display set to inline-block by default.
customElements.define( 'inline-block', class extends HTMLElement {
constructor() {
super()
this.attachShadow( { mode: 'open' } )
.innerHTML = `<style> :host { display: inline-block } </style>
<slot></slot>`
}
} )
#hw { background-color: lightblue }
<inline-block id="hw">Hello World</inline-block>
button, textarea, input, and select default to inline-block.
In the event you would want to inline-block a div you'd give it a class name.
.inline-block {
display: inline-block
}
Then...
<div class="inline-block"></div>
CORRECTION
I was mistaken about img. It seems it defaults to inline and not inline-block
This isn't really a true answer to the question right now, but with enough support, it may someday be.
<seg> short for "segment". As in, segments of a line.
with the polyfill:
<style> seg { display: inline-block; } </style>
It really would be nice if there was an official one, but there is not, so here is the best (IMO) suggested name for such an element that I know of.
YES there is an element that defaults to inline.
The answer is the span element.
<span>

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>.