If you never tried to center vertically a text, you know nothing about CSS
CSS tables are the main instrument that browsers, since IE8 included and above, make available to perform basic typographical operations such as center a text vertically inside of a container without knowing the height of the container nor the bulk of the text in terms of font size and number of lines, without them the property
vertical-align:middle is pretty much useless.
A typical example is the caption within an image, with a CSS table it’s possible to allow the text to stay centered no matter if it’s a single line or multiple lines, as long as it’s height is less than its container it will remain centered, otherwise the container will grow in height to accomodate the exceeding content.
In this case the effect you want to achieve is that the container caption covers in width the parent container, reason why we apply the
width:100% property, and as long as the size of the parent container remains fixed everything works as planned.
Problems arise on WebKit and Blink based browsers, meaning on all desktop and mobile versions of Chrome, Safari and Opera.
If the size of the parent container is itself variable, meaning set using a percentage unit, you will notice a strange effect: resizing the parent, the child with
width:100% will not overlap perfectly its father at all stages of the resizing process, you will notice instead a sort of flicker of 1px, on the right or left side of the element depending on the type of
In the case of the previous demo, adding an animation helps to grasp better the issue, if the element is in
position:relative and with
float:right the flickering can be observed on the left side, also it becomes clear how the text “tremble” during the animation due to the size of the box not being calculated correctly:
The bug is also illustrated in the following GIF while occurring on the right side, highlighted in red are the elements that use
display values of the
table type, if the element is in
position:absolute the flickering will occur always on the right side of the element even if you apply a
float:right, behavior observed in Chrome Mac Version 39.0.2171.95 (64-bit):
The previous GIF is based on the following demo, where all types of
display values are tested, using 100% width and animation on the parent container of all elements, here can be observed how all the elements with
display value belonging to the
table category do not respect the
width:100% property, but when the father shrinks enough to force them to fit they all exhibit the same behavior of the values
There are two possible
porkaround workaround for this bug which should be assessed according to the needs of the situation:
- Assign to the container a table-type
displayvalue as well, so that by adopting the same algorithm, the width bug is not identifiable.
- Nesting the element with
display:tableinside another element with
displayof any other type that can properly apply the
The first method avoids introducing additional HTML and “solves” the problem with a single CSS declaration, however, if the element is for example part of a column with other elements which all have the same width this is going to move the bug, rather than solve it, yet this allows to use the
min-height property directly on the
table element so that the height remains dynamic, allowing for better management of borderline cases.
The second method has the undesirable side effect of adding an additional HTML element and moreover it will require to apply an explicit value to the
table‘s height so that the container will expand to fill it vertically thus allowing to center its contents, however, this entails that if the content exceeds the available vertical space the outer container will not expand to accommodate the content and the directives of the
overflow property will kick in.
This bug is visible only when the
table element that is resized exposes a background color or border, so if you do not use these visual attributes you can just ignore it. Both solutions aren’t optimal for each single case, which means that you will have to evaluate each time which one is the lesser evil, it is not beautiful but “You gotta do what you gotta do“.
Hoping that this annoying bug will be eventually solved, I opened an issue on bugzilla respectively for WebKit e Blink, if the issues will be enhanced by further reports the probabilities that someone will take charge and resolve them once and for all will be higher, hopefully simultaneously (yay for forks!).