Why using display:block for block level elements - html

Sometimes I see designers using display: block for block level elements? For instance I saw people using display:block on elements that are already block level elements like ul, li and headers like h1, h2, h3 and so on.
If browsers already treats those elements as block level elements why do I have to use display block on them ?
thanks in advance

Most browsers recognize h1, h2, ul correctely (they were always included in HTML) but for newer HTML5 elements like header, footer and main and canvas it's a good practice. Because older browsers didn't recognize them, but if you did declare them as block element they will display them properly.
For instance IE8 wouldn't recognize footer and would display the footer as inline element (on most sites that would cause a mess). (http://caniuse.com/#search=footer)
This code block is from normalize.css a often used CSS stylesheet to "normalize" the display of elements across browsers:
/* HTML5 display definitions
========================================================================== */
/**
* Correct `block` display not defined for any HTML5 element in IE 8/9.
* Correct `block` display not defined for `details` or `summary` in IE 10/11 and Firefox.
* Correct `block` display not defined for `main` in IE 11.
*/
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
nav,
section,
summary {
display: block;
}
The comments are pointing out why they are applying display: block.
In some cases, display: block may be used to set properties previously changed in CSS. For instance if a plugin wants to make sure its headings are displayed as block, it sets h1, h2... to display: block, because maybe the site it's included in has set h1 to inline.

That's done to help older browsers properly display modern HTML. In the case of ul, li, h1 etc. tags that have been around since HTML 1.0, it's overkill. display: block is usually done so that modern HTML tags, i.e. HTML 5, that are new such as canvas, article etc. can be displayed by older, or non-standards browsers.

Related

Semantic elements work in IE 8 without html5shiv

I'm building a website and need IE 8 support. I'm using HTML5 semantic elements (main, section, article, nav, header and footer).
I know these should NOT work in IE 8 so I included html5shiv.
And styled all elements as display: block;.
My layout was still a mess in IE 8 … so I added classes to all semantic elements and used those classes to style the elements in CSS.
Now the layout is correct AND I no longer seem to need the html5shiv.
Is this even possible? Can you style the semantic elements using classes without the use of html5shiv? If so, why use html5shiv?
nav {color: red}
does not work, but
<nav class="nav">
.nav {color: red}
does seem to work without html5shiv. Can someone confirm this?
EDIT:
After some careful testing I found out the following:
When having a SVG element on the page (which will not render in IE 8) the semantic elements can be styled with classes without the use of html5shiv.
This is very weird and probably some kind of bug in IE 8.

What happens to old browsers if I use the new HTML5 tags?

If I use <main>, <article>, <aside>, <footer>, <header>, or <nav> elements will there be any bad side effects when someone with IE8 tries to load my page?
You will find many articles on this saying that some of these new elements are no different than generic block elements so they don’t pose any compatibility problems and all you need to ensure compatibility is to add a CSS rule to your website that causes the relevant elements to behave like block elements. Like this:
header, section, footer, aside, nav, main, article, figure {
display: block;
}
But IE8 and previous versions of IE pose a challenge. Any element not in the official roster of elements cannot be styled with CSS. That means we cannot make then behave like block elements or give them any formatting because they behave as if they don't exist.
Fortunately, a workaround exists for IE to recognize these new elements allowing them to be styled, and thus giving us full use of these new semantic tags. It’s a tool called HTML5Shiv.
The trick is that calling document.createElement("section") will suddenly cause IE to recognize the section element. No one knows why, but it works.
But you need to make sure to call it early on in your website before any of those elements are used, otherwise it won’t work.
To answer your question, (what do older browsers do?), some browsers will ignore the element. Some treat them as errors. Some will treat them as <div>. It's pretty much all over the place. So you need to do something and setting them to block level is the best thing you can do for them.
Here's a longer review along with suggestions.

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>

What HTML elements might have browser set default padding/margin?

I know that ol and ul elements have default padding set on almost all browsers. Apparently h{#} tags do too on some browsers.
How do I get a list of all elements?
I could simply do * { margin: 0; padding: 0; } (which is my desired result), but that's simply bad.
The W3C has a (informative, not normative) default stylesheet for HTML 4 here:
http://www.w3.org/TR/CSS2/sample.html
where you can see that no elements have padding, but body, h1..h6, p, fieldset, form, ul, ol, dl, dir, menu, blockquote and dd have a margin by default.
This is a somewhat solved problem. You have two options:
A 'reset' stylesheet, one that removes all special styling (like padding and margin) from (almost all) elements, so you can start 'fresh'. You'll need to redefine things like font-weight for <b>old and <strong>. Reset.css is a popular choice.
A stylesheet that sets sensible defaults. This would, for example, remove paddings and margins, but then add them again so that browsers are consistent with each other. The stylesheet included in the HTML5 Boilerplate can be stripped or used as-is for your purposes.
You can also use the above two stylesheets as a guide on what elements might have margins and paddings in different user agents and roll your own. In my opinion, setting sensible defaults (the second option) is better, since you might forget things like :focus styles with a plain 'reset stylesheet'.
You can use a simple CSS reset, a list of all resets: http://perishablepress.com/press/2007/10/23/a-killer-collection-of-global-css-reset-styles/
And you can get a look into a Useragent Stylesheet: http://meiert.com/en/blog/20070922/user-agent-style-sheets/
But there are very much elements with padding/margin:
body
blockquote
dd
p
ect.

How are different HTML elements equivalent?

Some HTML elements (<div>, <span>, <p>, <h1>, <h2>, ..., <h6> <b>, <i>, and so on) seem to behave the same way except for default styling. For example, <span style="font-weight: bold;"> x </span> seems equivalent to <b> x </b>. Some elements such as <a> have special properties but behave mostly the same way.
Can someone make this precise?
In particular, is there a subset of elements that "covers" all of HTML?
Edit: I understand that elements are meant to carry semantics. But suppose that I don't care about semantics, and I only want to deal with the smallest subset of HTML that will give me access to some given browser behavior. I'm wondering how to find that subset.
HTML is meant to mark up text semantically. That means giving meaning to a piece of text, like this is a headline, this is a paragraph, this is a quote, this should be emphasized. Some/most of them are displayed very similar by default, but that's not the point. The point is to be able to programmatically extract meaning and process elements according to their meaning, for example by styling them. Don't confuse semantics with style.
If you want to leave that aside, you pretty much only need block level elements like a div and inline elements like span, plus anything that has a specific function like links, objects etc.
Some reasons why an element cannot fully be replicated by <span class="..."> ignoring mere semantics and just considering browser or other HTML consumer behaviour:
The element is the root element.
The element is a metadata element
The element is a scripting element
The element is an embedded content element
The element is a forms element
The element is an interactive element
The element is a links element
The element is used by the document outline algorithm; including:
Sectioning content elements
Sectioning root elements
Heading content elements
The element goes in a place in the DOM where a span is precluded from going by the parser
The element forms part of a specific rendering binding
The element has a default WAI-ARIA role other than 'no role'
The element's DOM interface extends beyond that of HTMLElement
The element is the span element itself.
By my reckoning that leaves abbr, address, b, bdi, bdo, br, cite, code, dd, dfn, div, dl, dt, em, footer, header, kbd, mark, p, pre, rp, rt, ruby, s, samp, strong, sub, sup, u, var and wbr as the maximum list of elements replaceable by span if one ignores semantics. That's 31 out of 107 different elements in HTML5. Of the other 76, each has a specific job in browsers.
I note that of the above list, there are a number where I don't know what the equivalent styling would be, and that in all cases it's less typing to use the correct semantic element than to replace it with a span+class.
This depends on what you mean by browser behavior. All browsers will treat e.g. a elements with href attributes in a special way, as links, and this cannot be expressed in CSS. Similarly, form input fields are special, and so is img, even though you can simulate much of its behavior by using a background image in CSS. But what about abbr for example? Although most browsers just apply some default styling to it, some special browsers or assistive tools used with them give the user optional access to the value of the title attribute. Similarly, while most browsers treat h1 and other heading elements just by applying some default styling to them, some browsers have e.g. a mode where the browser only reads the headings to the user.
Similarly, you can create tables using CSS (display: table etc.) without using any table markup in HTML—though older browsers won’t get this right—but then your “tables” will not have accessibility features that HTML tables can have.
Search engines are not browsers, but they may be very important, and they are known to pay attention to HTML markup, though the details have not been disclosed. However, if you start e.g. using styled div elements intead of heading elements, you will probably lose something in search engine friendlyness.
Some elements have a very specific purpose, for example html, head, body, script, meta, embed, object, hr, table, tr, td, form, input. They do things that isn't possible to do by just specifying a style.
The rest of the elements, for example span, div, b, i, u, h1, p, only differ in their default style. You can use a span tag and apply display:block to it, and it works as a div tag.
Note though that there are block elements like div, and there are inline elements like span. You can't put a block element inside an inline element (until all browsers support HTML 5).
So, you strictly don't need all different elements. Some elements are even deprecated in HTML 4, for example b and i, as they are not needed and doesn't follow modern markup usage, so they should be replaced by styling.
You should however consider the semantics that the different elements add. The h1 element for example is important for search engines when they try to find out what the page is about. If you don't use the h1 element for your headline, search engines will rate your page lower.
The main difference between them is semantic. To illustrate, in HTML5 for example, you have div, section, header, footer etc., which are all block elements. In HTML4 you're required to use div for all of those. Which is easier to read, to look at, to style - a page full of div's or something divided into headers, and sections, and footers?
As you state, some elements have attributes that are specific to that element type/or certain types (e.g., a). So there's another difference.
Finally, in your list, you also have some block level (e.g., div, p) and some inline level (e.g., span, b) elements - those have very different default behaviors. See: http://www.webdesignfromscratch.com/html-css/css-block-and-inline/