沿垂直轴对齐具有不同水平位置的元素,无需硬编码

Aligning elements with different horizontal position along vertical axis, without hardcoding

我有一个包含两个元素的容器,如下所示:

<div id="container">
    <div id="button-container">
        <!-- sometimes other buttons as well in this part -->
        <input type="button" value="EXIT">
    </div>
    <h1 id="title-h1">Page Title</h1>
</div>

我想将 #button-container#title-h1 垂直对齐 - 也就是说,我希望它们都位于 #container div 的垂直中心。

相比之下,我希望 #button-container 被推到左边缘,而 #title-h1 应该在 #container 的水平中心。

最后,我想在不对任何值进行硬编码的情况下执行此操作。

以下内容无效 CSS(也许应该有效)但它是我要完成的伪代码:

#button-container {
    position: align-to-parent(left, middle);
}
#title-h1 {
    position: align-to-parent(middle, middle);
}

我能想到的最好办法是像这样硬编码按钮容器的位置:

#container {
    padding: 5px;
    vertical-align: middle;
    text-align: center;
    position: relative;
}

#button-container {
    position: absolute;
    left: 5px; /* since the padding has no effect on it */
    top: 33%; /* not very resilient */
    display: inline-block;
}

#title-h1 { 
    display: inline-block;
}

JSFiddle

我怎样才能做到这一点,以便它在各种容器和字体的大小方面更具弹性?

对于完全动态的垂直居中,可以使用CSS将元素的top设置为50%,然后使用CSS3 transform-translate属性将元素偏移其高度的一半。例如:

#button-container {
    position: absolute;
    top: 50%;
    -webkit-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    transform: translateY(-50%);
}

这是一个 jsFiddle 演示:http://jsfiddle.net/6hku6gdo/

如果您不想使用翻译,只要您知道元素的高度,您可以改为设置负边距。我会倾向于使用这种方法,除非元素的高度可能会改变。

#button-container {
    position: absolute;
    top: 50%;
    margin-top: -20px; /* assuming the height is 40px */
}

为了水平居中,您可以使用 display: inline-blocktext-align: center,或者使用与上述类似的方法,使用 left: 50% 并设置负边距,或者使用供应商前缀translateX(-50%) 个属性。

将两个元素垂直对齐并使它们的中间相互对齐的最简单方法是使它们都成为内联块,并为它们提供 vertical-align 属性:

#button-container, h1 {
    display : inline-block;
    vertical-align : middle;
}
#container { border: 1px solid red; }

(我还为容器添加了边框以更清楚地显示正在发生的事情。)

在这种情况下,将 h1 水平居中变得棘手,因为现在一行同时包含标题和按钮,但您可以算出标题的宽度,然后选择一个百分比偏移(实验以获得最佳值) 从容器右侧:

h1 { 
    position : relative;
    right : -30%;
}

随着屏幕变窄,它会根据屏幕宽度漂移 off-centre(但您可以添加一两个媒体查询来弥补这一点)。