基本上,我在另一个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; }
视觉表示的问题
绿线表示父宽度与实际内容之间的差异。
代码&小提琴下面。
浏览器:Google Chrome 47.0.2526.106 m
小提琴:
https://jsfiddle.net/44gymmw2/6/
更新
当我删除文本缩进:100%;从.breadcrumb__text CSS定义,.breadcrumb按照预期呈现。但是,当我离开文本缩进位置,并在样式表顶部的定义后删除.breadcrumb__text ::(如上所述),它也正确呈现。
可能这个问题与FontAwesome还是文本缩进和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); 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引入了您的问题的一个重要组成部分,影响使用文本缩进。从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.
换句话说:文本缩进影响您应用它的框的尺寸。
你已经声明了overflow:hidden;在.breadcrumb__text上。显然,为了使声明具有预期的效果,你应用它的框需要一个宽度,否则它不会有一个剪辑边。
.breadcrumb__text应该从应用于它的flex-based声明(特别是flex:0 0 2em;)获取它的宽度。嗯,这没有发生,至少,不完全是你所期望的。即使它的宽度似乎是2em,由于某种原因,它不会触发溢出行为,因为它应该。这似乎是您使用的特定Chrome版本的错误,因为它在加那利(例如版本49及更高版本)固定。
所以:这似乎是Chrome中FlexBox实现的一个问题。也就是说,有了这个知识,你的问题可以通过多种方式来解决。一些例子:
文本缩进:-100%
使用text-indent:-100%可以解决您的问题,因为它会占用受影响元素右侧的额外空格。 (→jsfiddle)
宽度:2em
您可以将声明宽度:2em添加到.breadcrumb__text。这将修复flex-based声明的意外行为。 (→jsfiddle)
溢出:隐藏;在父容器上
添加overflow:hidden;在.breadcrumbs修复你的问题。现在,父容器有一个裁剪边,并处理由使用text-indent:100%引起的空格。 (→jsfiddle)
最后言论
FlexBox是一个强大的布局模式,它确实是伟大的实验。但是,这些算法是复杂的,浏览器的实现还没有解决问题。确保在使用flexBox时考虑到这一点。
查看代码时的另一个问题是使用flexBox的方式。 FlexBox可供您使用,但不一定需要替换处理布局的其他方式。显示:inline-block;或显示:表;甚至浮动可以做这个工作,而不会引入嵌套的flex容器的复杂性。