首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >哪种神奇的CSS导致了<button>和<div>文本垂直对齐的不同?

哪种神奇的CSS导致了<button>和<div>文本垂直对齐的不同?
EN

Stack Overflow用户
提问于 2016-10-10 19:48:41
回答 3查看 691关注 0票数 17

我发现<button>中的文本自动垂直居中,而<div>中的文本是顶部对齐的。

我试着找出是哪个CSS规则造成了不同,但失败了。

代码语言:javascript
复制
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;
}
代码语言:javascript
复制
<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>

对于上面的例子,比较所有从Chrome计算出来的CSS规则,我只能找到一对不同的规则-- align-items: stretch用于<div>align-items: flex-start用于<button>

但是分配align-items: flex-start并没有什么帮助。所以我完全搞糊涂了。

让我困惑的是,即使所有的CSS规则都设置为相同的相应值,<div> <button> 和的文本垂直对齐方式也是不同的。换句话说,对于相同的CSS规则,<div><button>的行为也不同。为什么?

引擎盖下的魔法是什么?

我可以在<div>中垂直居中文本(如下例所示)。我只是好奇是什么导致了文本垂直对齐之间的差异。

也许这不是由特定的CSS规则引起的,而是因为这两个元素在浏览器中的布局算法不同?

代码语言:javascript
复制
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%);
}
代码语言:javascript
复制
<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>

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-21 11:06:29

如果你看一下Chrome的源代码,你可以看到它是如何工作的,至少对Chrome是这样的。似乎有一个应用了特定样式的匿名flex box。这不是那么简单-至少对我来说不是-但你仍然可以推断出应用于这个匿名元素的样式。你可以在这里看到:https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/layout/LayoutButton.cpp?sq=package:chromium

有趣的部分:

代码语言:javascript
复制
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());
}

结果如下所示:

代码语言:javascript
复制
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;
}

然后,您只需要将div内容包装在该跨度中,并应用样式。所有这些规则可能并不都是必要的或准确的,但结果似乎还可以:

代码语言:javascript
复制
div,
button {
  width: 4em;
  height: 4em;
  background-color: red;
  padding: 0;
  border: 0;
  margin: 1em;
  font-size: 1em;
  font-family: Arial;
  float: left;
}
div span {
  display: flex;
  text-align: center;
  min-width: 0px;
  flex-grow: 1;
  justify-content: center;
  cursor: default;
  margin: 0 auto;
  width: 100%;
  height: 100%;
  align-items: center;
  align-content: center;
}
代码语言:javascript
复制
<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>

票数 6
EN

Stack Overflow用户

发布于 2016-10-10 19:52:03

由于您使用的是inline-block,因此需要使用vertical-align,因为缺省值为baseline

魔力CSS:

代码语言:javascript
复制
vertical-align: middle;

上面的代码可以解决这个问题:

代码语言:javascript
复制
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;
}
代码语言:javascript
复制
<div>text</div>
<button>text</button>

要使div中的文本居中,您需要使用line-height指向divheight

魔力CSS:

代码语言:javascript
复制
line-height: 4em;

代码语言:javascript
复制
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;
}
代码语言:javascript
复制
<div>text</div>
<button>text</button>

票数 17
EN

Stack Overflow用户

发布于 2016-10-23 22:33:55

我认为您可以考虑以下解决方案之一

解决方案#1

将这些代码添加到div样式中

显示:表格单元格;

垂直对齐:居中;

如果你仍然需要使用内联块显示,你可以使用嵌套的div,父div将显示为( inline-block ),子div将显示为(table-cell),这就是文本的中间位置。

解决方案#2

您可以使用jQuery动态设置div填充和行高。这将在运行时完成,并将根据div中内容的大小进行调整。你可以查看这个问题jquery set line-height equal to parent container height

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39957592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档