Could work for short text. Combining attr()
and pseudo
.
.outer {
width: 200px;
background-color: #ccc;
border: 1px solid black;
display: inline-block;
}
.inner {
display: inline;
position:relative;
}
.inner:before {
content: attr(data-text) " ";
color: transparent;
position: absolute;
left:0;top:0;
border: 1px solid red;
pointer-events: none;
}
<div class="outer">
<div class="inner" data-text="Supercalifragilistic expialidocious">Supercalifragilistic expialidocious</div>
</div>
Edit: Absolute positioning inside inline elements & limitations of the above example.
From CSS2.1 specs 10.1.4: if an element is absolute positioned inside a inline element spanning multiple lines, its containing block is undefined.
By defining the top and left positions,we get the browsers to align the pseudo
to the corresponding top and left edges of the first box created by its 'ancestor'. By definition, pseudo is a virtual child of any selected element and an absolute
looks for a nearest positioned ancestor. Though the inline rule points to no containing block, the position rule works in favour for the top/left sides.
We then allow the pseudo to take the height as computed from its content/intrinsic dimension. Since attr()
pulls the same content, it more or less overlaps well on the text in its ancestor. (when without any font inconsistencies).
But do note, while it may work for single line text its dependent on the white-space/wrap/font and its not consistent across browsers when dealing with multi-line inline elements.
Here is what I mean.
.outer {
width: 200px;
background-color: #ccc;
border: 1px solid black;
margin-bottom: 30px;
font-family: monospace;
}
.inner {
color: black;
position: relative;
}
.inner:after {
content: attr(data-text) " ";
position: absolute;
left:-1px;top:-1px;right:-1px; /* compensating for the border */
pointer-events: none;
color: transparent;
border: 1px solid red;
}
<div class="outer"><span class="inner" data-text="single line inline">single line inline</span></div><div class="outer"><span class="inner" data-text="This is a multi-line inline element which may not hold an absolute positioned pseudo element. Fails in Chrome.">This is a multi-line inline element which may not hold an absolute positioned pseudo element. Fails in Chrome.</span></div>