<legend> tag accepts width if inline - html

When I apply the following styling to a legend tag
display: inline;
width: 300px;
I see that the legend tag has a width of 300px It still accepts the width. Here is a demo. Is there something special with this element, because I expect inline elements to ignore the width setting!

This may be a case similar to button elements, as described in Bindings:
10.5.2 - The button element
#namespace url(http://www.w3.org/1999/xhtml);
button { binding: button; }
When the button binding applies to a button element, the
element is expected to render as an 'inline-block' box rendered as a
button whose contents are the contents of the element.
Chrome seems to do the same for legend elements.
But probably it shouldn't be doing that, because
The spec doesn't define such binding for legend elements.
legend elements shouldn't be replaced elements (they are listed in the Non-replaced elements section), so they should conform to CSS rules.

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

Is tabindex hack for CSS :focus specified somewhere?

There is a hack to make work :focus pseudoclass for div elements: adding to div tabindex. Like this:
.testFocus:focus{
background: red;
}
<div class="testFocus" tabindex="0">awesomeDiv</div>
Is this behavior specified somewhere in W3C documents (where?) or is it just a non-documented hack?
"This behavior" consists of:
div element is not focusable by default.
div element with tabindex is focusable.
tabindex is one of the global attributes. This means it can be specified on all HTML elements.
0 is a valid value (see "If the value is a zero" under the definition of tabindex).
So your HTML is fine.
tabindex will work on the following elements in HTML5. https://www.w3.org/TR/html5/editing.html#sequential-focus-navigation-and-the-tabindex-attribute
a elements that have an href attribute
link elements that have an href attribute
button elements
input elements whose type attribute are not in the Hidden state
select elements
textarea elements

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

Span elements with contenteditable don't lose focus naturally, unlike div elements

JsFiddle: http://jsfiddle.net/sharat87/qWCQT/
As you can (or can't) see in the jsfiddle above, when you click below a div element with contenteditable, it loses focus, and rightfully so. But when you do the same thing with a span element with contenteditable, it doesn't lose focus. Also, div element with the style display: inline-block behaves exactly like the span element in this scenario.
In my app's layout, I need the contenteditable element to display as an inline-block. But it should lose focus when clicked on the empty space given below, which is explicitly provided for losing focus and a context specific purpose. I don't want the contenteditable element to retain focus.
Any way around this, short of handling the click and blur-ing the contenteditable element through javascript?
I've just added style/display property with JavaScript depending on Browser and it worked
window.onload=function(){
var ua=navigator.userAgent;
var spans=document.getElementsByTagName('span');
for(i=0;i<spans.length;i++)
{
if(spans[i].className=='content')
{
if(ua.indexOf('MSIE')!=-1) spans[i].style.display='inline-block';
else spans[i].style.display='inline-table';
}
}
};
Tested in Chrome, FF, IE8 and Opera. An example here.

Why does image use display: inline but behaves like an inline-block element

Why is the default display style for image inline instead of inline-block?
Is there any difference between inline and inline-block for img elements, from what I can see it behaves exactly in the same way.
IMG is an Inline & Replaced element.
A replaced element is any element whose appearance and dimensions are
defined by an external resource.
As per W3C
The IMG element has no content; it is usually replaced inline by the
image designated by the src attribute, the exception being for left or
right-aligned images that are "floated" out of line.
Check this link for more http://reference.sitepoint.com/css/replacedelements
The default browser stylesheets were initially created using CSS1 for HTML3.2, so inline-block was not available or necessary. There's no difference between them for image elements.
References
CSS 1 Specification
HTML 3.2 Specification
The first part of your question is already answered, so I shall not repeat.
For the second part, some browsers like Firefox renders a no-image img tag as a span even when width and height attributes are specified in CSS.
You can try it out yourself with this HTML code:
<img alt='no image' src='about:blank'><br>
<img alt='no image' src='about:blank'id=iblock>
And corresponding CSS:
img {
height: 100px;
width: 100px;
background: cyan;
}
#iblock {
display: inline-block;
}
Or see the difference in rendering effect with this Demo on JsFiddle.
Inline-block allows you to manipulate the object's appearance with box-model styling (such as giving it dimensions), but allows you to keep the object aligned inline, like text.
Inline block is the same as inline, except for it allows you to adjust block properties such as padding and margin. By default, images are supposed to semantically flow with text like a diagram in a news article, that is why all the original attributes are to do with aligning the image with the text flow.
Inline-block is a newer CSS2 declaration, and not fully implemented in IE 6/7.
It's simply an inline element that supports dimension attributes: Embedded content - the img element.