我发现里面的文字<button>是自动垂直居中的,而里面的文字<div>是顶部对齐的.
我试图找出哪个CSS规则有所不同但失败了.
div,
button {
width: 4em;
height: 4em;
background-color: red;
padding: 0;
border: 0;
margin: 1em;
font-size: 1em;
font-family: Arial;
}
div {
text-align: center;
display: inline-block;
cursor: default;
box-sizing: border-box;
}Run Code Online (Sandbox Code Playgroud)
<div>text text</div>
<button>text text</button>
<div>text text text text</div>
<button>text text text text</button>
<div>text text text text text text</div>
<button>text text text text text text</button>Run Code Online (Sandbox Code Playgroud)
至于上面的例子,比较Chrome中的所有计算CSS规则,我只能找到一个不同的对 - align-items: stretchfor <div>while align-items: flex-startfor <button>.
但分配align-items: flex-start并没有帮助.所以我完全糊涂了.
令我感到困惑的是,文本 - 垂直对齐是不同的<div>,<button>即使您使用相同的相应值设置所有CSS规则.换句话说,使用相同的CSS规则,<div>并且<button>行为不同.为什么?
引擎盖下的魔力是什么?
我可以垂直居中<div>(下面的例子)中的文字.我只是想知道导致文本垂直对齐之间差异的原因.
也许它不是由特定的CSS规则引起的,而是因为这两个元素的布局算法在浏览器中是不同的?
div,
button {
width: 4em;
height: 4em;
background-color: red;
padding: 0;
border: 0;
margin: 1em;
font-size: 1em;
font-family: Arial;
}
div { /* basic CSS rules to button-fy */
text-align: center;
display: inline-block;
cursor: default;
box-sizing: border-box;
}
/* Magic */
div, button {
vertical-align: middle;
}
div span {
display: inline-block;
position: relative;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}Run Code Online (Sandbox Code Playgroud)
<div><span>text text</span></div>
<button>text text</button>
<div><span>text text text text</span></div>
<button>text text text text</button>
<div><span>text text text text text text</span></div>
<button>text text text text text text</button>Run Code Online (Sandbox Code Playgroud)
Pra*_*man 16
由于您正在使用inline-block,您需要使用vertical-align默认值baseline:
魔术CSS:
vertical-align: middle;
Run Code Online (Sandbox Code Playgroud)
以上将解决它:
div,
button {
width: 4em;
height: 4em;
background-color: red;
padding: 0;
border: 0;
margin: 1em;
font-size: 1em;
font-family: Arial;
vertical-align: middle;
}
div {
text-align: center;
display: inline-block;
cursor: default;
box-sizing: border-box;
}Run Code Online (Sandbox Code Playgroud)
<div>text</div>
<button>text</button>Run Code Online (Sandbox Code Playgroud)
而对于div要居中的文本,你需要使用line-height到height的div.
魔术CSS:
line-height: 4em;
Run Code Online (Sandbox Code Playgroud)
div,
button {
width: 4em;
height: 4em;
background-color: red;
padding: 0;
border: 0;
margin: 1em;
font-size: 1em;
font-family: Arial;
vertical-align: middle;
line-height: 4em;
}
div {
text-align: center;
display: inline-block;
cursor: default;
box-sizing: border-box;
}Run Code Online (Sandbox Code Playgroud)
<div>text</div>
<button>text</button>Run Code Online (Sandbox Code Playgroud)
如果您查看 Chrome 源代码,您可以了解它是如何工作的,至少对于 Chrome 而言是这样。似乎有一个应用了特定样式的匿名弹性框。这不是那么简单——至少对我来说不是——但是,您仍然可以推断出应用于这个匿名元素的样式。你可以在这里看到:https : //cs.chromium.org/chromium/src/third_party/WebKit/Source/core/layout/LayoutButton.cpp?sq=package : chromium
有趣的部分:
void LayoutButton::updateAnonymousChildStyle(const LayoutObject& child,
ComputedStyle& childStyle) const {
ASSERT(!m_inner || &child == m_inner);
childStyle.setFlexGrow(1.0f);
// min-width: 0; is needed for correct shrinking.
childStyle.setMinWidth(Length(0, Fixed));
// Use margin:auto instead of align-items:center to get safe centering, i.e.
// when the content overflows, treat it the same as align-items: flex-start.
childStyle.setMarginTop(Length());
childStyle.setMarginBottom(Length());
childStyle.setFlexDirection(style()->flexDirection());
childStyle.setJustifyContent(style()->justifyContent());
childStyle.setFlexWrap(style()->flexWrap());
// TODO (lajava): An anonymous box must not be used to resolve children's auto
// values.
childStyle.setAlignItems(style()->alignItems());
childStyle.setAlignContent(style()->alignContent());
}
Run Code Online (Sandbox Code Playgroud)
这给出了这样的东西:
div span {
display: flex;
text-align: center;
min-width: 0px;
flex-grow: 1;
justify-content: center;
cursor: default;
margin: 0 auto;
height: 100%;
align-items: center;
align-content: center;
}
Run Code Online (Sandbox Code Playgroud)
然后您只需要将 div 内容包装在该跨度中并应用样式。所有这些规则可能并不都是必要或准确的,但结果似乎还可以:
void LayoutButton::updateAnonymousChildStyle(const LayoutObject& child,
ComputedStyle& childStyle) const {
ASSERT(!m_inner || &child == m_inner);
childStyle.setFlexGrow(1.0f);
// min-width: 0; is needed for correct shrinking.
childStyle.setMinWidth(Length(0, Fixed));
// Use margin:auto instead of align-items:center to get safe centering, i.e.
// when the content overflows, treat it the same as align-items: flex-start.
childStyle.setMarginTop(Length());
childStyle.setMarginBottom(Length());
childStyle.setFlexDirection(style()->flexDirection());
childStyle.setJustifyContent(style()->justifyContent());
childStyle.setFlexWrap(style()->flexWrap());
// TODO (lajava): An anonymous box must not be used to resolve children's auto
// values.
childStyle.setAlignItems(style()->alignItems());
childStyle.setAlignContent(style()->alignContent());
}
Run Code Online (Sandbox Code Playgroud)
div span {
display: flex;
text-align: center;
min-width: 0px;
flex-grow: 1;
justify-content: center;
cursor: default;
margin: 0 auto;
height: 100%;
align-items: center;
align-content: center;
}
Run Code Online (Sandbox Code Playgroud)