IE vertical centering bug with table-cell parent a

2019-09-07 05:24发布

问题:

I'm building a flexible progress-bar with a number of constraints. It needs to be able to contain any number of items within it, have these items all be the same width, vertically centered, support content of varying lengths, work in IE9 and above and have an icon next to them without any additional markup. display: table-cell seemed to be the most appropriate solution for the potentially unlimited number of items inside as well as vertically aligning the text nicely, and :before would take care of the icon, which would also be vertically aligned with the top: 50%; translateY(-50%) method.

This seemingly works fine on modern browsers, as there's nothing particularly fancy here. However, in any version of Internet Explorer, this isn't going as smoothly as I'd like. If the items are of a variable height, the icons aren't vertically centered on anything but the tallest element. IE9 has support for translateY and it's been ages since we had difficulties with display: table/table-cell. Even IE11 can't make this work.

I have created a reduced test case on CodePen so you can see it in action:

Here's a screenshot of the method working perfectly in Firefox: And failing in IE11:

I initially thought the failure was due to the height of the elements not being calculated correctly in IE, but the borders being uniform indicates that this isn't the case.

If I set the list items to display: inline-block and manually set their widths, the icon vertically centers as expected, but I'd like to retain the more flexible behavior of table-cell display, if at all possible.

Any insights would be greatly appreciated. Thanks in advance!

回答1:

The issue seems to be with how IE is calculating the heights of the cells. Their heights seem to be based on the height of the contents, not the element itself. So I moved the relative positioning to the list itself as its intrinsic height should be consistent:

.progress-bar {
  display: table;
  table-layout: fixed;
  width: 100%;
  position: relative;
  counter-reset: progressBar;
}

Then I positioned the check in a slightly different manner using your top offset of 50%, but leaving the left offset to “auto” and using negative margins to move it into place (since they have better backward-compatible support than transform), but that choice is up to you:

&:before {
  content: "✓";
  color: green;
  display: block;
  position: absolute;
  top: 50%;
  margin-top:-.5em;
  margin-left: -1em;
}

I hope this helps.

Here’s the Codepen fork: http://codepen.io/aarongustafson/pen/PwPxEp