flexbox垂直居中
Flexbox is extremely useful in layout in modern web design. However, one thing it’s not good at vertically aligning wrapped text in some circumstances. Returning to the example I detailed last week, the solution works really well when the text for both links is the same length, but when the text of one link wraps but not the other, the result is out of alignment:
Flexbox在现代Web设计中的布局中非常有用。 但是,在某些情况下,它不能很好地垂直对齐包装的文本。 回到我上周详细说明的示例,当两个链接的文本长度相同时,该解决方案的效果很好,但是当一个链接的文本换行但另一链接不换行时,结果是不一致的:
While it’s a small issue, it’s also an annoying one, and one that I wanted to solve. The solution needed a little JavaScript; first, the markup:
尽管这是一个小问题,但它也是一个烦人的问题,也是我想解决的一个问题。 该解决方案需要一些JavaScript ; 首先,标记:
<div id="prevnext" class="flex apart">
<a class="prev-one flex" href="/1059/Responsive-Image-Hinting-Using-the-w-Descriptor" rel="prev" accesskey=",">
<span class="thumb">
<img src="toubana-diver.jpg" alt srcset="toubana-diver-2x.jpg 2x">
</span>
<span class="articlename">
Responsive Image Hinting: Using w
</span>
</a>
<a class="next-one flex" href="/1063/Techniques-and-Treatments-for-Background-Retina-Images" rel="next" accesskey=".">
<span class="articlename">
Techniques and Treatments for Background Retina Images
</span>
<span class="thumb">
<img src="birds-on-wire.png" alt srcset="birds-on-wire-2x.png 2x">
</span>
</a>
</div>
The CSS is as before: see the last article for that.
JavaScript (The JavaScript)
I’m going to make the assumption that this kind of navigation occurs only once per page, so I can identify each navigational element uniquely via a querySelector
:
我将假设这种导航每页仅发生一次,因此我可以通过querySelector
唯一地标识每个导航元素 :
var leftText = document.querySelector("#prevnext a span.articlename"),
rightText = document.querySelector("#prevnext a:last-child span.articlename");
The adjustment of the text link elements is made in a function named matchHeight()
:
文本链接元素的调整是在名为matchHeight()
的函数中进行的 :
function matchHeight() {
var difference = leftText.offsetHeight - rightText.offsetHeight;
if (difference > 0) {
rightText.style.marginTop = "-" + difference+"px";
}
if (difference < 0) {
leftText.style.marginTop = difference +"px";
}
if (difference == 0 && (leftText.hasAttribute("style") || rightText.hasAttribute("style"))) {
leftText.removeAttribute("style");
rightText.removeAttribute("style");
}
}
A quick explanation:
快速说明:
difference
measures the height difference between the two text links. The result could be 0 (meaning that the links are the same height), positive (meaning the left link is taller than the right) or negative (i.e. the right link is taller than the left).difference
测量两个文本链接之间的高度差异。 结果可能是0(表示链接的高度相同),正(表示左侧的链接比右侧的高度高)或否定的(即右侧的链接比左侧的高度高)。In the first case, the right link is raised (using a negative top margin) by the
difference
amount.在第一种情况下,右链接会增加 (使用负的上边距)
difference
量。- in the second case, the left link is raised by the difference. 在第二种情况下,左链接会因差异而升高。
in the last case, a
0
difference could be due to the fact that the links were originally the same height, or that they’ve been previously adjusted (raising one link), and are now the same height. I’ve added a test to see if either link has an inline style. If an inline style is present*, it’s removed, setting both links back into vertical alignment.在最后一种情况下,差异为
0
可能是由于这些链接原本是相同的高度, 或者以前已经对其进行过调整(举起一个链接),而现在它们是相同的高度。 我添加了一个测试,以查看任一链接是否具有内联样式。 如果存在内联样式*,则会将其删除,将两个链接都重新设置为垂直对齐。
The function is called once on page load:
该函数在页面加载时被调用一次:
matchHeight();
The script needs to be called again whenever the link text wraps (changing the height of the element). It would be great if we could add an eventListener
to do that, but JavaScript doesn’t currently detect height changes on elements. I’d love to be able to use a transition
-triggered event like this one by David Walsh, but browsers don’t currently seem to detect that either, at least for flexbox elements. Instead, I resorted to calling the function efficiently on window resize with requestAnimationFrame
:
每当链接文本换行(更改元素的高度)时,都需要再次调用该脚本。 如果我们可以添加一个eventListener
来做到这一点, eventListener
了,但是JavaScript当前无法检测到元素的高度变化。 我很希望能够使用David Walsh这样的transition
触发事件 ,但是浏览器目前似乎也不能检测到这两个事件,至少对于flexbox元素而言。 相反,我诉诸于使用requestAnimationFrame
调整窗口大小时有效地调用该函数:
window.addEventListener("resize", function() {
window.requestAnimationFrame(matchHeight);
});
解决布局延迟 (Accounting For Layout Delay)
One curious problem I encountered in Chrome is that the browser would correctly align the text during initial page load, but not on refresh: in fact, it would report both elements as being the same height even if they were not. I suspect this is due to inefficiencies in browser layout: Chrome appears to be providing the elements with the same height during its first rendering pass after refresh, then refining the layout a little while later.
我在Chrome中遇到的一个奇怪的问题是,浏览器会在初始页面加载期间正确对齐文本,但在刷新时不会对齐:实际上,它会报告两个元素的高度相同,即使它们并非相同。 我怀疑这是由于浏览器布局效率低下造成的:Chrome似乎在刷新后的第一次渲染过程中为元素提供了相同的高度,然后过了一会儿完善布局。
Treating this problem proved frustrating: a setTimeout
did not work predictably; neither did an eventListener
for DOMContentLoaded
. JQuery's window load event was the only one that appeared to work predictably:
事实证明,处理此问题令人沮丧: setTimeout
无法正常工作; DOMContentLoaded
的eventListener
也没有。 JQuery的窗口加载事件是唯一可以正常运行的事件:
$(window).bind("load", function() {
matchHeight();
});
You can see the result in the example at the top of this article; you can also expect to see it applied to this site in the very near future.
您可以在本文顶部的示例中看到结果。 您也可以期望不久后它将应用于该网站。
翻译自: https://thenewcode.com/1110/Vertically-Aligning-Wrapped-Text-in-a-Flexbox-Layout
flexbox垂直居中