html - 使用 FontAwesome 时 Flexbox 大小调整无法正常工作

标签 html css flexbox font-awesome

我的页面布局遇到了非常奇怪的 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;
}

问题的可视化表示

绿线表示父级宽度与其实际内容之间的差异。

Visual representation of the issue

下面的代码和 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 of overflow 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/

相关文章:

jquery - 如何获取表单值并在我的 html 中显示?

javascript - 使用ajax调用时如何实现next/back函数?

html - 在我的垂直菜单中悬停时出现边框问题

html - 如何使用附近的动态宽度按钮将标题居中?

html - 如何删除 Twig 中的空格

javascript - 我们如何才能防止行隐藏

css - 使用 CSS 更改事件菜单项的文本颜色

html - 无法将 flexbox child 的宽度设置为 100%

css - 拉伸(stretch) CSS Flexbox 网格中的元素

html - 更改弹出菜单按钮的颜色