Recently, I started working with our most loving dreadful Internet Explorer again. As I can't help the corporate companies asking them to switch to a newer version of Internet Explorer, the possibility of which is almost near nothing. So here goes my rant from Stack Overflow - Issue with IE11 multi-height TH and positioning of pseudo elements...
I am trying to add few icons on the <th>
by putting them to position: relative
and then position
ing the icons as ::after
pseudo element using position: absolute
inside the <th>
and giving the icons as background (since they are sprites). This works perfectly in Google Chrome and Firefox, but not in Internet Explorer.
Here's the snippet that demonstrates the problem (which is reproducible only in Internet Explorer, my version 11):
* {font-family: 'Segoe UI';}
.arrow {border: 1px solid #ccc; padding: 5px; line-height: 1; background-color: #00f; color: #fff; position: relative; cursor: pointer; padding-right: 20px;}
.arrow-normal::after {width: 9px; height: 12px; margin-top: -6px;}
.arrow-up::after {width: 9px; height: 6px; margin-top: -3px;}
.arrow-down::after {width: 9px; height: 6px; margin-top: -3px; background-position: 0 -6px;}
.arrow::after {
top: 50%;
position: absolute;
right: 5px;
content: ' ';
display: block;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnZJREFUeNpsk99rUmEYx1/l+Hvmj8HwQgQvvHKS0LqJQCOIMnTmqOb8UTfdDjb/iYneDAaCIhgSE/NnTOZNMAapkCFYbMEIuiswaHPq5tHj6XlsR3TsCw/nfR/e9/M+vw4RCAQEDWW325+0Wq0fDofDKhKJyMLCwthYlh1btVolpVKJHB4eklgsdlur1X4LBALPCoUCSSaTJJvNkgnM6XTaz0FwkYVP2+VyPRIKhTPASqVCDg4OSCQSWZqfn/8F11h4uLe5ufk8l8v9B6JWVlacl5eXF+yUOp3OOfjHUA7YbDbJzs7Oklqt/o0wziiKotfX11fL5TIha2trL/v9Ps3eIIB2fT7fMgeMx+P35+bm/kzDpozZ2Njw8xqNxkeDwXC32+22eSByJQTKZLJbJycnn81m80P0QRneQcp2uVz+F7aTsyjIUKbX65s8t9st1Gg0gsFgwE7BCLKhvryzs7MBREajv16vU0qlUsDn81kOeHV2vO/1egxlMpkYm82GL5DrwvpBRAy3h1qNisXigGvktCAgsri4OKJgVEqwuAOOzrUzLFyUSySSL7B+jI6tra14Pp9/ClGeQmQzKUN0MqPR+JVsb2/7R6MRc1NThsNhP5FIvOCasre390ChUJze1BRMOxgMvsGRIdFodBUinOk0TdO9VCrlgBmbjA08QPb39++pVKqZTkNNmVAo9Ap+CsKXSqU4sCmYfA9ALjB8/GYymdWjo6MPYrF4khY0iFit1sru7u4yDDZCsXE0wF57vd637Xab8NGJ0Fqt9h4idcOln+l02nV8fDwDQ2HnEWqxWD7BGZtOp/seDof9Ho8niTDM4p8AAwB6jpihgDknYAAAAABJRU5ErkJggg==");
}
<table>
<thead>
<tr>
<th class="arrow arrow-normal">Two Line<br />Column</th>
<th class="arrow arrow-up">Single</th>
<th class="arrow arrow-down">Three<br />Line<br />Column</th>
</tr>
</thead>
<tbody>
<tr>
<td>Item 1</td>
<td>Item 2</td>
<td>Item 3</td>
</tr>
</tbody>
</table>
The output of the above can be seen live here:
See the Pen IE TH Multiline Issue by Praveen Kumar (@praveenscience) on CodePen.
When I run this in Google Chrome, I get the expected output:
All the icons in Google Chrome are aligned perfectly in middle.
Whereas, in Internet Explorer, the problem is, all the <th>
elements take the right height, when they have different contents, but the positioning is messed up.
What I see is that, in Internet Explorer, the heights are calculated right, but for position
, the initial heights before adjusting the tables are taken into account. Is there anything that can be done to fix this?
Note 1: I have also looked into IE vertical centering bug with table-cell parent and absolutely positioned pseudo-element, which requires me to use another element and give
position: relative
, but this is not possible in my case as my HTML is fixed and can't be changed. It is generated by an enterprise application, which I have no control over.Note 2: Since I already know the heights of each element, I am using the negative margin technique.
Solution
Okay, I was constantly trying out different methods to use ::after
and position it correctly and it looks like none of the methods worked in Internet Explorer 11. So finally I decided using three separate images for the background and positioning it as required.
Here's my updated snippet if someone would use it.
See the Pen IE TH Multiline Solution by Praveen Kumar (@praveenscience) on CodePen.
Bonus: The nice part about this is, I have also used something called CSS background-position edge offsets, which helps me in achieving the following stuff, that I did using right: 5px;
for ::after
pseudo elements in my snippet. Well, I wanted to give a 5px
padding for my arrows to not get stuck to the edge of the table, and I had the following reasons / justifications:
- I am lazy to use Photoshop CS3 to give a padding right to the image and recreate the
data://
URI for the same. - This is not right, as the image shouldn't have padding inbuilt. What if it is supposed to be used on left side?
By adding the extra bit of:
.class {background: url("image.png") right 5px center no-repeat;}
The above CSS offsets the right side of background-position
for a span of 5px
, which is literally like right-5px
calculation. Cool, isn't it?
Challenge: If someone gets to know the fix, obviously using the
position
and CSS Sprites, please do let me know in the comments.