Changing a div or span tag to inline-block feels so dirty. There must be a cleaner solution!
i don't found any HTML element that default to "display:inline-block"
thanks in advance
From the sample stylesheet for HTML 4: button, textarea, input, and select default to inline-block, but they aren't generic containers so (presumably given you are talking about alternatives to div and span) don't suit your needs.
There are no generic containers that default to inline-block.
Don't worry about how dirty the default rendering feels to you, it is the semantics that matter.
Maybe Canvas and images ,button, textarea also
In the Rendering section of HTML5 CR, several elements are described as having an “expected” binding that causes that the element is “expected” to be rendered as an inline-block. Most of those elements, such as <input type=text> are unsuitable for your purposes, because they cannot have any content. Other elements have idiosyncratic rendering features that make it difficult to turn them to normal element.
But technically, you could use e.g. textarea. Then you would have to deal with its special rules for whitespace (can be overridden with white-space: normal), font size (can be overridden with font-size: 100%), font family, etc. So you would get more trouble than you would save.
Related
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.
<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>
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.
As I understand, width/padding/margin properties only work on block level elements. However, on INPUT and SELECT elements I am able to specify the width, which works. Should it?
I could write something like this:
<input type="text" style="display:block;" />
But is it necessary?
Can anyone explain please why it works?
Actually, they're not really inline elements, but rather inline-block elements. This allows you to specify width, height and other block-specific properties without the need to break the flow of inline elements. In good browsers you can use "display:inline-block" on any element to achieve the same thing.
The spec says:
Applies to: all elements but non-replaced inline elements, table rows, and row groups
Form controls, such as input and select elements are replaced inline elements (the element is replaced with a form control - the text content of it is not displayed like a normal element).
Since they are replaced, they are not non-replaced, so the width property applies.
Form elements are the black sheep of the HTML/CSS world - there's lots of properties which don't work like normal HTML elements.
While it doesn't answer yor question, you might find the following discussion interesting: http://meyerweb.com/eric/thoughts/2007/05/15/formal-weirdness/
Technically, that's a rendering property which is browser-specific. At this point most browsers do allow you to set the width, but it's not guaranteed (especially on older browsers) and you definitely can run into bugs with it.
The W3 spec for the input element technically makes it an inline element. Inline-block isn't even a part of the W3 spec, it's part of CSS2 (hence older browsers being inconsistent).
IE has some funny bugs if you specify width as a percentage and put a whole lot of text into it, for example.
Long story short, it's almost always safe, just not part of any official spec that I've seen.
Did you thing what happened if that would be not possible? When INPUT element was introduced there was no CSS. And width of INPUT element is absolutely required in HTML for creating proper forms.
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.