Other display values have one or more corresponding HTML elements, such as:
block - div, p
inline - span, strong, etc.
list-item - li
table - table, table-row - tr, etc.
none - template
but display: grid and display: flex must be assigned through styling. I could see it being easier to read through the DOM if <flex> and <grid> elements were available.
Are new element types not being added to the spec now that custom elements can be made?
The answer to your question has to do with the separation of style from the data being presented.
The HTML tags that you use to display data should be chosen based on the type of data that you are displaying. For example, you'd use <li> when you're producing a list or <strong> when you want text to stand out. CSS gives you a lot of flexibility for modifying how the data is presented allowing you can change how data, such as text in <strong> or <em> tags, is displayed. The styles for many tags can be changed so that they behave like other tags. For example, you can make a <span> tag behave like a <div> tag and vice versa. However, you should not do this. In other words, the tags that you select should be based on the type of data being displayed, such as <li> for list items or <p> for paragraphs. Technically, you can never completely separate your data from how it is displayed, but you should attempt to do so as much as is possible.
<flex> and <grid> don't have any meaning with respect to the type of data that you want to display. Thus, they are styles that are editable using CSS (instead of tags).
I could see it being easier to read through the DOM if <flex> and <grid> elements were available.
You're suggesting combining content and presentation, which counters the separation of concerns principle that CSS was created to address.
HTML is used for organization of content. CSS is used for presentation of content. Your <flex> and <grid> elements would combine these two concerns, which is the way things were in the 1990s, before the advent of CSS, when HTML did both.
Also, what if I want my <article> to be a grid container, or my <aside> to be a flex container?
Why not also have <block> and <inline>?
Things start getting messy.
Also, the premise of your question is incorrect.
Other display values have one or more corresponding HTML elements ... but display: grid and display: flex must be assigned through styling.
Actually, the display value of all HTML elements is assigned. The only difference is where the styling comes from.
In raw form, HTML elements have no styles. They only have semantic meaning.
It isn't until the browser assigns default styles that elements take on presentational meaning.
Therefore, the only reason you can say this...
Other display values have one or more corresponding HTML elements,
such as:
block - div, p
inline - span, strong, etc.
list-item - li
table - table, table-row - tr, etc.
... is because the browser defined those elements as such with something like this:
Appendix D. Default style sheet for HTML 4
As you can see, display values are assigned.
So the browser sets a basic level of formatting for HTML elements. Changes and additions to these styles are left up to authors.
Here's some more detail:
Proper way to apply CSS to HTML5 custom elements
<main> element not working in Internet Explorer 11
Related
Sometimes I want to put a wrapper element around several other HTML elements with the sole purpose of setting up a convenient CSS selector to refer to all the contained elements:
<TAG id="just-a-handy-wrapper">
<abc ...>
...
</abc>
...
<pqr ...>
...
</pqr>
</TAG>
...and in the CSS:
#just-a-handy wrapper * {
...
}
I find this easier to manage and maintain than the alternative of assigning a common class to all the items captured by the #just-a-handy wrapper * selector above.
In this example, I've used fictitious tags <abc>, ..., <pqr>, etc., for the contained elements to stress the fact that I'm looking for a solution that works irrespective of the nature of the specific tags among the contents.
I've also used the fictitious tag TAG as a placeholder for the desired "wrapper tag", because my question is precisely about the best HTML tag to use for this purpose. By "best" I mean most "universal" in the types of elements it can contain in valid HTML5, and "most layout-neutral".
IOW, the ideal HTML tag would the one where the page including the code above would always be rendered exactly the same as one where the <tag ...> and </tag> lines were removed, or commented out:
<!-- <tag id="just-a-handy-wrapper"> -->
<div ...>
...
</div>
...
<div ...>
...
</div>
<!-- </tag> -->
A div, for example, is not "layout-neutral" (the browser will generally have strong ideas about how to layout a div), therefore it would not do to set tag equal to div. Here's a simple example of this:
original
with <div> wrapper around two of the three blue
rectangles
Yes, there is a CSS for that supported by major browsers
display: contents
E.g.
<section class="container"><div>Parent is virtually not rendered</div></section>
.container {
display: contents;
}
Sorry, I fear there is no such tag.
Imaginge a scenario where your <abc> or <pqr> tags are block-level tags, say <p> tags. In order to fullfill your requirement (the layout should be the same, if the tag is there or not), the container tag would need to be a blocklevel tag to be w3c conform, and it should not have any default stylings. As far as I know, a <div> is exaclty that.
Now imaginge a scenario where your<abc> or <pqr> are inline tags like <i> or <b>. In order to fullfill your requirement the container tag would need to be a inline tag itself, otherwise it would break the line.
Now the thing is it is not possible for a tag to be inline- and block-level at the same time.
And to answer your question about the most universal tags:
Use div as a container for block-level contents and use span as a container for inline contents. These tags are made for this purpose.
From the w3c Visual Formatting Model document:
Boxes in the normal flow belong to a formatting context, which may be block or inline, but not both simultaneously
In your fiddles, the lack of layout neutrality is demonstrated by the text-align: center; rule on the .outer element no longer applying to the .inner elements, once there was a wrapper element layered between them.
I know that you'd prefer to speak in generalities to stress your point about a layout neutral tag, but since all HTML elements must have a formatting context, there will always be a side-effect to adding more tags to the markup. (In this case, your <div> tag is a block.)
Most often there's no visual issue, but insofar as your layout depends on formatting contexts, adding more elements will always run counter to you having a layout-neutral tag.
I would echo #Mario A's answer that where you need to wrap a tag with something layout neutral, wrap block tags with <div>s, and inline tags, with spans, so as not to introduce new formatting contexts that could disrupt your layout.
<span> is layout neutral but it depends on which types of elements go within in, for example it cannot contain block elements like <div>. Whether an element renders as a block depends on the element, but can be specifying, for example <div style="display:inline-block"> or <div style="display:table-cell"> display differently.
Since it's a CSS question, you can use IDs on your elements to add extra CSS rules, or apply several different classes to one ID. EG
<div id="mydiv" class="blacktext">helloo</div>
<div class="blacktext class2">hello</div> <!-- apply class blacktext and class2-->
CSS
.class2 { background-color: #FF0000;}
References
[1] the <span> tag
The tag is used to group inline-elements in a document.
The tag provides no visual change by itself.
The tag provides a way to add a hook to a part of a text or a part of a document.
[2] span vs div
Answer on stackoverflow about inline-block, block and inline with <span> and ` compared
There isn't such a tag, and there very well should be one.
Some tags like fieldset have behavior that affect child elements, but also do not require having any rendering. fieldset, when disabled, will disable all children input elements and is incredibly useful. However, you cannot wrap it around a <tr> specifically because it needs to be rendered.
I think the slot tag can be a good candidate for your requirements.
What is the purpose of the CSS display property's values such as:
table-cell
table
table-caption
table-column
table-column-group
table-footer-group
table-header-group
table-row
table-row-group
I understand these styles will style the element like a table, but what is the purpose of this when there is already an acceptable, working, table element?
Modern browsers use CSS to style all their markup.
How would they render a <table> element if CSS had nothing that could express the appearance of one?
(That, and you might have non-tabular data that you want to render like a table, there are enough people using tables for layout to see a demand for it).
They can be used to format content in a tabular manner when the markup does not use the table element, e.g. because the markup was written by someone who was told not use tables or because the markup is generic XML and not HTML.
You can also design a page using e.g. div elements so that some stylesheet formats them as a table, some other stylesheet lets them be block elements or turns them to inline elements. This may depend e.g. on the device width.
The <table> HTML markup is for tabular data, i.e. data that consists of logical rows and columns, i.e. a spreadsheet. It should only be used for data that logically requires to be presented in a table.
The CSS table-* display styles allow any data to be presented in a tabular style (which has its own unique logic, mostly in regard to vertical centering and width distribution which is hard to emulate using other elements), while still being marked up using whatever makes the most sense for it semantically, for example a list.
Since it is recommended not to use table elements for layout purposes (non-tabular data), because the special formatting applied to those elements may change in the future, is it also not recommended to use CSS properties such as text-align, which was designed to be used on text, for img elements for the same semantic reason?
I have been looking through the w3c specifications and for instance, line-height seems to be designed for text purposes and has plenty of references in the documentation to font size, so would it be appropriate or abusive to use this property on img elements, simply because they are displayed as inline?
I can understand how the W3C idea of a Semantic Web would use CSS to remove styling information from a page, leaving data exclusively in the HTML for content accessibility. But where is the original rationale documentation for CSS, and why wouldn't they use extremely abstract properties like horizontal-align from the get go, instead of unique alignments for each display type (e.g. text-align: center can be used on all display: inline elements such as img elements) ?
No. CSS is purely presentational. Some of the properties are just poorly named (text-align being a prime example, it is designed to align all inline children).
It is perfectly fine, to use text-align in table cells, that just styling the table as you should be doing. If you want to. Just do it in CSS. Do not use align="right".
https://developer.mozilla.org/en/CSS/text-align
Says it applies to: block level elements, table cells and inline-blocks. So it is a use that is documented and intended. If you have inline content use this property to style its alignment.
http://www.w3.org/TR/CSS21/text.html#propdef-text-align Also states
This property describes how inline-level content of a block container is aligned.
So it is not just text, but all inline content.
I've read many explanations of what the actual purpose of the < span > tag is, and I've tried to incorperate those explanations into real applications but have failed every time.
One person told me that it was to apply classes to sub-tags below it, which does kind of work, except it doesn't apply dimensions to elements, unless you mess around with the display and/or inline settings, which can totally screw up a layout.
Then someone else told me that it's use as a substitute for the < div > tag, which doesn't work because floats or "margin: auto"-type attributes don't work unless contained inside certain types of elements.
Then someone else told me that it's used as a text container, which doesn't work because the "text-align" attribute doesn't work, again, unless contained inside certain types of elements. A default-attribute-cleared < p > tag is much more suited, in my experience.
So what exactly is the point of them? Why are so many people using them when < div > seems to do everything that they're apparently capable of and more?
From Official Docs:
The DIV and SPAN elements, in conjunction with the id and class
attributes, offer a generic mechanism for adding structure to
documents. These elements define content to be inline (SPAN) or
block-level (DIV) but impose no other presentational idioms on the
content. Thus, authors may use these elements in conjunction with
style sheets, the lang attribute, etc., to tailor HTML to their own
needs and tastes.
As it says, you can use <span> tag to structure (inline) the sections of page along with styling which you may optionally pass via id, class or stylesheets.
Characteristics of <span> tag:
It's display is inline by default which means:
you can not apply width to it
you can not apply height to it
you can make it block-level too by using display:block (div serves the same purpose)
The <div> tag is opposite to that and you can apply above rules to it.
It is an inline element with no attached semantics that can be used to wrap some inline content for
the application of JavaScript (e.g. event handlers or moving about the DOM)
the application of CSS
use with the lang attribute
processing by custom tools
… when no element with more appropriate semantics exists.
floats or "margin: auto"-type attributes don't work unless contained inside certain types of elements.
They work (or otherwise) based mostly on the display value, not the element type.
Why are so many people using them when <div> seems to do everything that they're apparently capable of and more?
A div is identical to a span except it:
Can contain block elements
Cannot (error recovery not withstanding) be contained by an inline element (or any other element that can contain only inline content, such as a <p>)
Is display: block by default (instead of inline)
When the text is in a <span> element you can add styles to the content, or manipulate the content.
I know it's wrong to put a block element inside an inline element, but what about the following?
Imagine this valid markup:
<div><p>This is a paragraph</p></div>
Now add this CSS:
div {
display:inline;
}
This creates a situation where an inline element contains a block element (The div becomes inline and the p is block by default)
Are the page elements still valid?
How and when do we judge if the HTML is valid - before or after the CSS rules are applied?
UPDATE: I've since learned that in HTML5 it is perfectly valid to put block level elements inside link tags eg:
<a href="#">
<h1>Heading</h1>
<p>Paragraph.</p>
</a>
This is actually really useful if you want a large block of HTML to be a link.
From the CSS 2.1 Spec:
When an inline box contains an in-flow block-level box, the inline box (and its inline ancestors within the same line box) are broken around the block-level box (and any block-level siblings that are consecutive or separated only by collapsible whitespace and/or out-of-flow elements), splitting the inline box into two boxes (even if either side is empty), one on each side of the block-level box(es). The line boxes before the break and after the break are enclosed in anonymous block boxes, and the block-level box becomes a sibling of those anonymous boxes. When such an inline box is affected by relative positioning, any resulting translation also affects the block-level box contained in the inline box.
This model would apply in the following example if the following rules:
p { display: inline }
span { display: block }
were used with this HTML document:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HEAD>
<TITLE>Anonymous text interrupted by a block</TITLE>
</HEAD>
<BODY>
<P>
This is anonymous text before the SPAN.
<SPAN>This is the content of SPAN.</SPAN>
This is anonymous text after the SPAN.
</P>
</BODY>
The P element contains a chunk (C1) of anonymous text followed by a block-level element followed by another chunk (C2) of anonymous text. The resulting boxes would be a block box representing the BODY, containing an anonymous block box around C1, the SPAN block box, and another anonymous block box around C2.
The properties of anonymous boxes are inherited from the enclosing non-anonymous box (e.g., in the example just below the subsection heading "Anonymous block boxes", the one for DIV). Non-inherited properties have their initial value. For example, the font of the anonymous box is inherited from the DIV, but the margins will be 0.
Properties set on elements that cause anonymous block boxes to be generated still apply to the boxes and content of that element. For example, if a border had been set on the P element in the above example, the border would be drawn around C1 (open at the end of the line) and C2 (open at the start of the line).
Some user agents have implemented borders on inlines containing blocks in other ways, e.g., by wrapping such nested blocks inside "anonymous line boxes" and thus drawing inline borders around such boxes. As CSS1 and CSS2 did not define this behavior, CSS1-only and CSS2-only user agents may implement this alternative model and still claim conformance to this part of CSS 2.1. This does not apply to UAs developed after this specification was released.
Make of that what you will. Clearly the behaviour is specified in CSS, although whether it covers all cases, or is implemented consistently across today's browsers is unclear.
Regardless if it's valid or not, the element structure is wrong. The reason that you don't put block elements inside inline elements is so that the browser can render the elements in an easily predictable way.
Even if it doesn't break any rules for either HTML or CSS, still it creates elements that can't be rendered as intended. The browser has to handle the elements just as if the HTML code was invalid.
The HTML and the CSS will both still be valid. Ideally, you wouldn't have to do something like this, but that particular bit of CSS is actually a handy (and syntactically valid but not semantically valid) way for getting Internet Explorer's double margin bug without resorting to conditional stylesheets or hacks that will invalidate your CSS. The (X)HTML has more semantic value than the CSS, so it's less important that the CSS is semantically valid. In my mind, it's acceptable because it solves an annoying browser issue without invalidating your code.
The HTML is validated independently of the CSS, so the page would still be valid. I'm fairly sure that the CSS spec says nothing about it either, but don't quote me on that one. However, I'd be very careful using a technique like this, as while it might render as intended in some browsers, you'd need to test 'em all—I don't see many guarantees being made.
Are the page elements still valid?
“Valid” in an HTML sense, yes; HTML knows nothing about CSS.
The rendering you get in the browser, however, is ‘undefined’ by the CSS specification, so it could look like anything at all. Whilst you could include such a rule in CSS hacks aimed at one particular browser (where you know how that browser renders this case), it shouldn't be served to browsers in general.
I don't know off the top of my head if this validates any rules but I would recommend using the W3C HTML Validator and the W3C CSS Validator to determine that. Hope this is helpful!
If there is a logic you follow and you end up implementing it like this, it's NOT WRONG. Working things are not "wrong" just because they're weird. Yes, it's quite unusual but it HELPS and it's not a mistake. It's intentional. HTML and CSS should serve you, not the other way around so don't ever listen to comments telling you not to do it just because it's ugly.
It's typical to call a solution "invalid" and suggest a long way around the block. Sometimes you can rethink what you did. But there can be many reasons for what you did and they don't consider them.
I do use blocks inside inlines regularly. It's valid and it's working - it's just not necessary in most cases. So what. Remember when XHTML told us to always put quotes around properties (and everyone yelled at you if you didn't!), now HTML5 allows to omit them if there's no space inside. What happened to that last slash after singular tags? "<br />" ? Come on. Standards change. But browsers keep supporting non-standard things as well. CENTER is deprecated; we're in 2013 and it still works. TABLE for vertical centering? Sometimes it's the only way. DIV inside A to make it hover as you planned? Just go ahead.
Focus on important things.
I think, (x)html is valid, css is valid. Is the result valid? Yes, if it is looking in the browser as You want.
No, It is not a wrong choice. We can use as per requirements.