WebGL Tutorial
and more

垂直水平居中标签

撰写时间:2025-03-08

修订时间:2025-03-26

这里集中列出使用CSS在垂直及水平方向上居中放置标签的各种方案。

flex

#container { width: 100px; height: 100px; background: #2F3F3F; display: flex; justify-content: center; align-items: center; } #child { width: 50px; height: 50px; background: darkcyan; }

grid

#container { width: 100px; height: 100px; background: #2F3F3F; display: grid; place-items: center; } #child { width: 50px; height: 50px; background: darkcyan; }

grid还可通过在子标签中设定margin: auto的方式来快速实现垂直与水平居中。

#container { width: 100px; height: 100px; background: #2F3F3F; display: grid; } #child { margin: auto; width: 50px; height: 50px; background: darkcyan; }

absolute + transform

#container { width: 100px; height: 100px; background: #2F3F3F; position: relative; } #child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 50px; height: 50px; background: darkcyan; }

absolute根据父容器的值来调整位置,而transform则再根据自身的大小来调整位置。

absolute + margin

#container { width: 100px; height: 100px; background: #2F3F3F; position: relative; } #child { position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; width: 50px; height: 50px; background: darkcyan; }

加入fit-content属性值,也可适用于自身本无大小、但需要根据自身内容来设置大小的标签,例如p, span等。

#container { width: 100px; height: 100px; background: #2F3F3F; position: relative; } #child { position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; width: fit-content; height: fit-content; color: #FFF; padding: 1em; background: darkcyan; }

Hello

table

#container { background: #2F3F3F; display: table; padding: 1em; } #child { display: table-cell; vertical-align: middle; text-align: center; width: 50px; height: 50px; background: darkcyan; }

对于使用display: table的标签,没必要设置尺寸大小,而应在该标签内设置padding属性,然后再在使用display: table-cell的标签中设置大小。这样,表格的大小就能从内到外通过计算自动设定。

line-height + inline-block

#container { width: 100px; height: 100px; background: #2F3F3F; line-height: 100px; text-align: center; } #child { width: 50px; height: 50px; display: inline-block; vertical-align: middle; margin-top: -5px; background: darkcyan; }

先在父容器设置line-height,再在子标签设置display: inline-block,则可像设置字符一样安排其垂直方向的对齐方式。

由于子标签确实没有文本的基线 (baseline) 等基本特征,因此默认情况下不能在垂直方向上精准地对齐,此时可使用margin-top来进行细微调节。

应用篇

居中正方形子容器

本例中,我们在整个客户端中自动居中放置一个正方形的子容器。

最简单的方式。

:root { --top-margin-value: 20px; } div { height: calc(100vh - var(--top-margin-value) * 2); margin: var(--top-margin-value) auto; aspect-ratio: 1 / 1; background-color: #2F3F3F; }

这种方式只需指定子容器上边距的值,然后自动计算出其heightmargin属性值,即可自动居中。

下面为较完善的方式。

html, body { margin: 0; padding: 0; border: 0.5px solid green; box-sizing: border-box; min-height: 100vh; display: grid; } div { margin: auto; width: calc(min(100vw, 100vh) * 0.8); aspect-ratio: 1 / 1; box-sizing: border-box; border: 5px solid gray; background: #2F3F3F; }

htmlbodymarginpadding均设为0,再将其最小高度min-height设置为整个客户端的高度。使用min-height而不是height的原因在于,当子容器的高度大于客户端的高度时,允许htmlbody的高度值被自动拉伸。

子容器div的宽高比为1,因此只需计算一个width属性值即可。

从客户端的宽度值与高度值中取最小值,可确保子容器的内容不会超出客户端的范围。将此值乘以缩放因子0.8,则在父容器与子容器之间自动产生一个1 - 0.8 = 0.2em的留白。

如果缩放因子在某些情况下必须大于1.0,则将divmargin属性值改为margin: 1em auto,则可在自动左右居中的同时,在上下两端留出特定的留白。

将子标签高度限制在视口内

在一个单页 (single page) 的 Web app 中,我们希望将整个内容都限制在视口范围内

html, body { margin: 0; padding: 0; } html { box-sizing: border-box; border: 1px solid red; height: 100vh; display: flex; flex-direction: column; } body { flex: 1; border: 1px solid green; margin: 1em; } h1 { color: mediumaquamarine; border: 1px solid gray; }

Auto Fit in Maximized Viewport

Some texts.

Some texts.

Some texts.

输出面板的高度已被设置为固定的300px

根元素html设置为flex后,其唯一的子元素body的高度被设置为自动占满整个flex容器的空间。因此,当body内容比较少时,绿色边框也能铺满整个视口。

但是,当body的内容增加到10个段落文本时,绿色方框随之扩展,而超出了红色方框所代表的视口范围。

html, body { margin: 0; padding: 0; } html { box-sizing: border-box; border: 1px solid red; height: 100vh; display: flex; flex-direction: column; } body { flex: 1; border: 1px solid green; margin: 1em; } h1 { color: mediumaquamarine; border: 1px solid gray; }

Auto Fit in Maximized Viewport

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

问题是绿色方框超出了红色方框,且绿色方框内没有出现滚动条。

以下使用flexmin-height来解决问题:

html, body { margin: 0; padding: 0; } html { box-sizing: border-box; border: 1px solid red; height: 100vh; display: flex; flex-direction: column; } body { border: 1px solid green; margin: 1em; flex: 1; display: flex; flex-direction: column; min-height: 0; } div { border: 1px solid gray; flex: 1; overflow: scroll; } h1 { color: mediumaquamarine; border: 1px solid gray; }

Auto Fit in Maximized Viewport

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

flex子元素的min-height属性值默认为auto,导致body拒绝受到父容器高度的约束,从而继续撑开浏览器客户端下面的空间。将min-height的值设置为0,则body的高度值可以受父容器高度的约束。

推而广之,将上面的技术应用于多级嵌套的子元素中:

html, body { margin: 0; padding: 0; } html { box-sizing: border-box; border: 1px solid red; height: 100vh; display: flex; flex-direction: column; } body { border: 1px solid green; margin: 1em; flex: 1; display: flex; flex-direction: column; min-height: 0; } main { flex: 1; display: flex; flex-direction: column; min-height: 0; } div { border: 1px solid gray; flex: 1; overflow: scroll; } h1 { color: mediumaquamarine; border: 1px solid gray; }

Auto Fit in Maximized Viewport

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

Some texts.

此为独立运行的范例

参考资源

  1. CSS Backgrounds and Borders Module Level 3