Some HTML elements have always caused headaches for front-end developers everywhere, like iframes, applets, embedded objects or form controls. One could never have complete control over their display, because they look different from one browser to another, from one OS to another.
Countless libraries and frameworks created replacements, from jQueryUI to Bootstrap, and many more. But have you ever wondered why those elements behave the way they do? Some voices (including a few well-known websites) will point their finger to a fairly obscure definition from W3C, namely the one concerning replaced elements. But are they 100% right? This is the quest we will chase together today.
What are Replaced Elements?
Any good quest must start with research. Therefore let’s have a look at what the official specs say a replaced element is:
An element whose content is outside the scope of the CSS formatting model, such as an image, embedded document, or applet. For example, the content of the HTML IMG element is often replaced by the image that its “src” attribute designates. Replaced elements often have intrinsic dimensions: an intrinsic width, an intrinsic height, and an intrinsic ratio. For example, a bitmap image has an intrinsic width and an intrinsic height specified in absolute units (from which the intrinsic ratio can obviously be determined). On the other hand, other documents may not have any intrinsic dimensions (for example, a blank HTML document).
So far, so good – we got a general description of what a replaced element is. Before we go deeper into this spec section, let’s make a small detour and clarify the “intrinsic dimensions” part.
What are Intrinsic Dimensions?
The best definition available now for intrinsic dimensions comes from the CSS Image Values and Replaced Content Module Level 3 document:
The term intrinsic dimensions refers to the set of the intrinsic height, intrinsic width, and intrinsic aspect ratio (the ratio between the width and height), each of which may or may not exist for a given object. These intrinsic dimensions represent a preferred or natural size of the object itself; that is, they are not a function of the context in which the object is used. CSS does not define how the intrinsic dimensions are found in general.
Here are some examples:
- A normal image has all three dimensions: width, height and aspect ratio.
- An SVG image can have only the aspect ratio. Its scaling nature means that the width and height are not restricted to a single value.
- An empty HTML page, inserted via an
iframeelement has no dimensions at all.
The way these properties are tied to one another means that there can be no object with only two dimensions. Knowing two of them automatically determines the third one.
Overall this means that such an object, when placed into the page, will provide these intrinsic dimensions to the document so that they can be rendered properly. This information will be useful later, but for now, let’s return to the main path.
Replaced Elements in the Real World
For a full description of the replaced elements we need to go to a different resource, namely the Rendering section of the HTML Living Standard document. As one goes deeper into the specs, it’s easy to see how this topic can be confusing. This is because some HTML elements act as replaced elements all the time, while other do it only in specific circumstances.
Fortunately the Subsection 14.4 gives us all the information we need to properly understand each case.
The first category of replaced elements is embedded content. This includes any element that imports another resource into the document, or content from another vocabulary that is inserted into the document. These external resources, by their own nature, have the intrinsic dimensions that match the requirements of the definition.
The main elements in this category are
video. These elements are always treated as replaced elements because they always import external content into your document.
Things are a bit more complicated with elements that fall into this category only in special circumstances:
applet– Treated as a replaced element when it represents a plugin, otherwise it’s treated as an ordinary element.
audio– Treated as a replaced element only when it is “exposing a user interface element”. Will render about one line high, as wide as is necessary to expose the user agent’s user interface features.
object– Treated as a replaced element when it represents an image, plugin, or nested browsing context (similar to an
canvas– Treated as a replaced element when it represents embedded content. That is, it contains the element’s bitmap, if any, or else a transparent black bitmap with the same intrinsic dimensions as the element.
These are the only cases where the elements above are treated as replaced elements (which covers almost all cases where these elements are used). For full details on this, please see WHATWG’s rendering rules for embedded content.
Next on our list are images. In the vast majority of cases (when the image is displayed properly), the
img element is treated as a replaced element with the intrinsic dimensions of the image. This category also includes the
input elements with a
Things get a bit more complicated when, for various reasons, the image is not rendered on the page. A missing image that the browser expects it will render eventually has to be treated as a replaced element whose content is the text that the element represents (optionally an icon can also be added). The
<input type="image"> will be displayed as a normal button instead. The complete set of rules and conditions can be reviewed in the spec.
Default Size of Replaced Elements
This is where the information we gathered about intrinsic dimensions becomes useful. We have established already that the
height properties of a replaced element come from the intrinsic dimensions of the content they bring into the page. If these dimensions can’t be calculated (like in the case of an
iframe loading a blank HTML page), the browser must fall back to the default rules, as specified in Visual formatting model details. The set of rules itself is fairly large and complicated, but we are only going to focus on the “nothing else works” ones:
Otherwise, if ‘width’ has a computed value of ‘auto’, but none of the conditions above are met, then the used value of ‘width’ becomes 300px. If 300px is too wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead.
Otherwise, if ‘height’ has a computed value of ‘auto’, but none of the conditions above are met, then the used value of ‘height’ must be set to the height of the largest rectangle that has a 2:1 ratio, has a height not greater than 150px, and has a width not greater than the device width.
We can summarise all this in three basic rules:
- if the object has explicit
ratiovalues, use them;
- if the object only has
autofor both width and height while maintaining the said ratio;
- if none of these dimensions are available:
width: 300px; height: 150pxwhen the viewport is larger than 300px
- use “auto” for both width and height and a ratio of 2:1 when the viewport is smaller than 300px;
Here is an example illustrating the situations described above. We have a bitmap image, an SVG image, and an iframe. As you can see, the image is displayed at its normal size, the SVG keeps the aspect ratio but takes all available space while the iframe defaults to a maximum of 300×150. If we narrow down the viewport, the iframe keeps at all times an aspect ratio of 2:1.
Rounding things up
We now have enough information to put together the complete list of the replaced elements:
- embedded content:
videoare always treated as replaced elements
- embedded content:
canvasare treated as replaced elements in specific cases
input type="image"are treated as replaced elements when loaded properly or when the browser expects it will render eventually
What About the Other Types of Form Controls?
As I mentioned at the outset, there is a certain level of misconception that other types of form controls are replaced elements too. After all, if you add no styles and no attributes, these elements are also rendered with a default width and height. That would satisfy the requirements of the definition, wouldn’t it?
Actually that is not true. Let’s consult again the Rendering section of the HTML living standard. Here we discover that 14.3.11 Form controls is a subsection of 14.3 Non-replaced elements. What most people consider intrinsic dimensions actually comes from the following line:
Each kind of form control is also described in the Widgets section, which describes the look and feel of the control.
Source: 14.3.11 Form controls
And here is the reason why form controls look so different from one browser to the next and from one OS to another:
The elements defined in this section can be rendered in a variety of manners, within the guidelines provided below. User agents are encouraged to set the ‘appearance’ CSS property appropriately to achieve platform-native appearances for widgets, and are expected to implement any relevant animations, etc, that are appropriate for the platform.
The term “platform-native appearances” explains why form elements are rendered in such a different way from one browser to another and across different operating systems. It comes down to each browser to define their own interpretation of the way these widgets must look.
Looking back, it’s understandable how replaced elements and form controls got mixed up. Diving deep into both the HTML and CSS specs was necessary in order to unearth the truth. They are different categories of HTML elements, with
<input type="image"> being the only form control that is a replaced element.
And here we are at the end of our quest. The results might not be exactly what we expected, but I think they show a clearer picture of a not-so-well-known area of HTML.