Block-level HTML elements and CSS Specification default value of display property - html

This shows that "display" is initially "inline" for all elements:
https://www.w3.org/TR/css-display-3/#the-display-properties
However, this says "(and assuming the DIV and the P both have 'display: block')":
https://www.w3.org/TR/CSS2/visuren.html#block-level
I did see this question that shows that the browser sets the default display value.
Difference between HTML block elements and CSS display block property.
Q. How does this reconcile with the CSS Spec. statement that "display" is initially "inline" for all elements? Does the CSS specification statement about "initially inline" refer to the state before the browser sets display:block for block-level elements?

Does the CSS specification statement about "initially inline" refer to the state before the browser sets display:block for block-level elements?
It refers to the default value of a property if nothing is defined including any browser default style.
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. ref
The fact that you can read "(and assuming the DIV and the P both have 'display: block')" confirms the logic because the Specification is not telling you that p and div should be or are block elements but let's assume they are block element for the sake of the explanation that comes next.
div and p are flow content (WhatWG) and thus presumably have "display: block" by default.
"Flow content" and "display: block" are not linked together. Some elements are flow content but they don't have "display: block" like a, span and many others.
The content models has nothing to do with the display value.

Related

Is a legend element a grid item if a fieldset's display is grid?

What section of the css-grid specification addresses how a legend element should be handled if a fieldset element is set to display:grid?
As you know, a legend element is typically the first child of a fieldset element, yet rarely would anyone want it to be treated as a grid item.
I'm wondering if I need to take explicit styling-precautions to ensure that a legend element will NOT be treated as a grid item, or if the specification already has some rule (I'm overlooking) that means a legend element (by spec) is not a grid item.
This has changed; fieldset rendering has been siginificantly redefined and rewritten such that they may now be laid out as CSS grids. See Mats Palmgren's answer.
You won't find these details in the CSS spec, but in the HTML spec. And HTML is pretty specific about how the fieldset and legend elements should be rendered, and, for historical reasons, layout implementations for these elements is extremely rigid with very little accommodation for changes to layout modes via the display property.
It is for this reason that display: grid is simply not supported on fieldsets by any browser. In fact, just a few days ago there was a discussion around a proposed addition to the HTML spec to specify how the display property should be treated on fieldset and legend elements, and this is what's slated to be added:
The fieldset element, when it generates a box (i.e., is not 'display: none' or 'display: contents'), is expected to act as follows:
...
The 'display' property is expected to act as follows:
If the computed value of 'display' is one of 'inline', 'inline-block', 'inline-table', 'ruby', 'ruby-base', 'ruby-text', 'ruby-base-container', 'ruby-text-container', 'inline-flex', or 'inline-grid', then behave as 'inline-block'.
If the computed value of 'display' is one of 'block', 'table', 'table-row-group', 'table-header-group', 'table-footer-group', 'table-row', 'table-cell', 'table-column-group', 'table-column', 'table-caption', 'list-item', 'flow', 'flow-root', 'run-in', 'flex', or 'grid', then behave as 'block'.
This basically cements the current text which says that the fieldset element is expected to establish a block formatting context, without specifying how it should behave should a UA choose not to follow this definition.
This, coupled with the current interoperable browser behavior, means that the layout of a legend element will not be affected by its parent fieldset having display: grid, since its parent fieldset will be prevented from becoming a grid container in the first place.
All major browsers support grid (and flexbox) layout on <fieldset> these days. Firefox added it back in 2015.
By default, a rendered <legend> is not a child box of the anonymous fieldset content box (which implements the actual grid/flex layout) so it is not treated as a grid item - it behaves the same regardless of the fieldset's display value.
The HTML spec for fieldset/legend rendering now has a fairly detailed description of how the layout works, described in CSS terms.
To override the default behavior and make the <legend> behave as a grid item, style it with display: contents, documented in the CSS Display spec as such:
Per HTML, a <legend> with display: contents is not a rendered legend, so it does not have magical display behavior. (Thus, it reacts to display: contents normally.)
Demo here: https://codepen.io/karlhorky/pen/LYdxQWe

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.

why css width property is working with input element

According to CSS docs:
The width CSS property ... applies to all elements but non-replaced inline elements, table rows, and row groups
Input is inline element. So why width property is work with input element?
The exception is for non-replaced inline elements. Input is a replaced element.
Replaced element
In CSS, a replaced element is an element whose representation is
outside the scope of CSS. These are kind of external objects whose
representation is independent of the CSS. Typical replaced elements
are <img>, <object>, <video> or form elements like <textarea> and
<input>. Some elements, like <audio> or <canvas> are replaced elements
only in specific cases. Objects inserted using the CSS content
properties are anonymous replaced elements.
CSS handles replaced elements specifically in some cases, like when
calculating margins and some auto values.
Note that some replaced elements, but not all, have intrinsic
dimensions or a defined baseline, which is used by some CSS properties
like vertical-align.
Reference: MDN - Replaced element

Difference between HTML block elements and CSS display block property

May I know if there is any difference between HTML block elements (Eg. <p>, <div>,...) and CSS property display: block?
Since from what I have read they are the same, but why we still need to use display: block for some block level element.
What you call "HTML block elements" are elements who have their display property set to block so there is no difference between a <div> and a <span> with display:block;.
This display property is set by the user agent stylesheet (i.e your browser). You can view these properties in chrome dev tool under "user agent stylesheet".
The only reason I see of using display:block; for a div element is :
your target adience is using some obscur user agent that don't follow web stadards (very unlikely)
you need to override a previous CSS declaration like display:none;
There is no difference between... because block elements already have default css property display: block.
But we use display: block to show them again, when we hide/remove them from page using display: none.

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>