我的页面布局遇到了非常奇怪的 flexbox 行为。我正在使用 FontAwesome 来呈现某些符号。
基本上,我在另一个 flexbox 元素中有 2 个 flexbox 元素,并且这些子元素渲染得比父元素宽。
1) 我有一个 .content__header
对象,它在另一系列的 flexbox 对象中呈现为 flexbox 对象。
2).content__header
对象包含 2 个子对象:.breadcrumb
和 .page_tools
。这些子对象也呈现为 flex 元素。
3) 在 .breadcrumb
对象中,我有一些 span
对象 (.breadcrumb__test
),它们的内容被 FontAwesome 替换了图标。替换是使用 ::after
伪元素的绝对定位完成的。
4) 当我删除所有 .breadcrumb__text
HTML 元素或只是从我的样式表中删除 .breadcrumb__text::after
定义时 - 它定义了FontAwesome 字体 - 子对象(.breadcrumb
和 .page_tools
)以正确的宽度呈现。 所以我猜这与替换为FontAwesome 图标。
.breadcrumb__text::after {
font-family: "FontAwesome";
font-weight: 400;
}
问题的可视化表示
绿线表示父级宽度与其实际内容之间的差异。
下面的代码和 fiddle 。
浏览器:谷歌浏览器 47.0.2526.106 m
fiddle :
https://jsfiddle.net/44gymmw2/6/
更新
当我从 .breadcrumb__text
CSS 定义中删除 text-indent: 100%;
时,.breadcrumb
按预期呈现。但是,当我保留 text-indent
并删除样式表顶部的 .breadcrumb__text::after
定义时(如上所述),它也正确呈现。
这个问题可能与 FontAwesome 或 text-indent
和 flexbox 有关吗?
代码
HTML
<body>
<div class="layout_wrapper">
<div class="layout_container__content">
<div class="content">
<header class="content__header">
<div class="breadcrumb">
<span class="breadcrumb__text breadcrumb__text--first">From </span><a class="breadcrumb__link" href="#">Dashboard</a><span class="breadcrumb__text"> to </span><a class="breadcrumb__link" href="#">Find records</a><span class="breadcrumb__text"> to </span>
<h1 class="breadcrumb__current">Kylo Ren’s Command Shuttle™</h1>
</div>
<ul class="page_tools">
<li class="page_tools__item">
<button type="button" class="button button--primary">Save</button>
</li>
<li class="page_tools__item">
<button type="button" class="button">Cancel</button>
</li>
</ul>
</header>
</div>
</div>
<div class="layout_container__sidebar">
<div class="sidebar">
<article class="widget">
<h2 class="widget__title">Widget</h2>
</article>
</div>
</div>
</div>
</body>
CSS
/* Removing this makes it work */
.breadcrumb__text::after {
font-family: "FontAwesome";
font-weight: 400;
}
/* Don't remove anything below */
.breadcrumb__text--first {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
* {
box-sizing: inherit;
}
html {
box-sizing: border-box;
}
html, body {
padding: 0;
margin: 0;
}
body {
display: flex;
flex-flow: column nowrap;
align-items: stretch;
}
.layout_wrapper {
flex: 1 1 auto;
display: flex;
flex-flow: row nowrap;
align-items: stretch;
}
.layout_container__content {
flex: 0 0 75vw;
}
.layout_container__sidebar {
flex: 0 0 25vw;
}
.content {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: stretch;
}
.content__header {
outline: 1px solid blue;
background-color: #434649;
color: #ffffff;
flex: 0 0 100%;
display: flex;
flex-flow: row nowrap;
}
.breadcrumb {
outline: 3px dashed purple;
flex: 1 1 auto;
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
}
.breadcrumb__text {
flex: 0 0 2em;
overflow: hidden;
text-indent: 100%;
white-space: nowrap;
position: relative;
text-align: center;
}
.breadcrumb__text::after {
content: '\f105';
padding: 0;
text-indent: 0;
position: absolute;
top: 0;
right: 0;
width: 100%;
}
.breadcrumb__text--first {
flex: 0 0 0;
}
.breadcrumb__text--first::after {
content: none;
}
.breadcrumb__link {
flex: 0 0 auto;
display: inline-block;
font-size: 0.8571rem;
}
.breadcrumb__current {
flex: 0 0 100%;
margin: 0;
}
.page_tools {
outline: 3px dashed red;
flex: 0 0 auto;
display: flex;
flex-flow: row nowrap;
list-style: none outside none;
}
最佳答案
我刚刚审查完您的代码并注意到以下几点:
- 存在不必要的(嵌套的) flex 容器(由使用
display: flex;
引起)。 - 有不必要的 flex 相关声明(只是声明默认行为,例如
flex-flow: row no-wrap;
和align-items: stretch
)。 - 在各种不相关的选择器的上下文中有几个不必要的声明。可能在测试/调试时留下了声明。
也就是说,让我们继续您的问题。这并不明显,因此需要一些介绍。
Pangloss介绍了您的问题的一个重要组成部分,它会影响 text-indent
的使用。来自 W3 :
The box is indented with respect to the left (or right, for right-to-left layout) edge of the line box. User agents must render this indentation as blank space.
[...]
If the value of
text-indent
is either negative or exceeds the width of the block, that first box, described above, can overflow the block. The value ofoverflow
will affect whether such text that overflows the block is visible.
换句话说:text-indent
会影响应用它的框的尺寸。
您已在 .breadcrumb__text
上声明了 overflow: hidden;
。显然,要使该声明具有预期的效果,您应用它的框需要 width
,否则它不会有剪裁边。
.breadcrumb__text
应该从应用于它的 flex-basis
声明(特别是 flex: 0 0 2em;
)中获取它的宽度。好吧……这并没有发生,至少,没有像您期望的那样完全。尽管它的宽度似乎是 2em
,但出于某种原因,它并没有像它应该的那样触发溢出行为。这似乎是您使用的特定 Chrome 版本中的错误,因为它已在 Canary 中修复(例如版本 49 及更高版本)。
所以:这似乎是 Chrome 中 flexbox 实现的问题。也就是说,有了这些知识,您的问题可以通过多种方式解决。一些例子:
文本缩进:-100%
使用 text-indent: -100%
解决了您的问题,因为它消除了受影响元素右侧的额外空白。 (→ jsfiddle )
宽度:2em
您可以将声明 width: 2em
添加到 .breadcrumb__text
。这将修复 flex-basis
声明的意外行为。 (→ jsfiddle )
overflow: hidden;
在父容器上
在 .breadcrumbs
上添加 overflow: hidden;
可以解决您的问题。现在父容器有一个裁剪边缘,并处理使用 text-indent: 100%
引起的空白。 (→ jsfiddle )
最后的评论
Flexbox 是一种强大的布局模式,值得尝试。但是,算法很复杂,浏览器实现也并非没有问题。确保在使用 flexbox 时考虑到这一点。
查看代码时的另一个问题是使用 flexbox 的方式。 Flexbox 可供您使用,但它不一定要取代所有其他处理布局的方式。 display: inline-block;
或 display: table;
,甚至 float
都可以在不引入嵌套 flex 容器的复杂性的情况下完成这项工作。
关于html - 使用 FontAwesome 时 Flexbox 大小调整无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34434542/