【问题标题】:Wrapping a link around an image destroys flexbox layout and causes browser rendering quirks将链接包裹在图像周围会破坏 flexbox 布局并导致浏览器呈现怪癖
【发布时间】:2020-01-08 13:59:05
【问题描述】:

努力寻找正确的标题,而不仅仅是“帮助”和“什么,CSS,为什么?!”的混合体所以希望你们中的几个天才会发现这个......!

我有两列。它们中的每一个都有一个包含徽标的全角 div。这些图像是完全不同的形状,一个是正方形,一个是更全景的纵横比。为了获得平衡的外观,图像设置为最大宽度为 50%,最大高度为 100%。 Flexbox 用于将图像水平和垂直居中。

它们看起来非常好。

// working before wrapping images with links
section.working {
  div.flex {
    display: flex;
    justify-content: center;
    align-items: center;

    img {
      max-width: 50%;
      max-height: 100%;
    }
  }
}

然后我需要添加链接。

https://codepen.io/lenoz/pen/VwZyeOG

这是最简单的问题,因为底行是我用来获得完美布局的原始代码,顶行显示了当图像被包装在标签中以使其链接时会发生什么。一些注意事项:

  • 添加颜色只是为了帮助稍微区分边界 - 用于检测链接(红色背景)何时不再受限于其中的图像大小(理想情况下应该如此)
  • 这两列在代码中是分开的,而不是共享容器的一部分 - 即,一列无法告知另一列的高度(希望使用 CSS 而不是 JS 来解决此问题)

我应该提一下,当然,添加链接是不可能的.

非常感谢您能帮我找到 CSS 解决方案。


还在吗?如果您想了解有关我尝试修复的更多信息,请继续阅读,其中包含 Chrome 的怪异部分。

不用说,我已经花了很长时间摆弄这个,所以这里有另一个链接,显示了我已经接近的一些努力:https://codepen.io/lenoz/pen/pozpjVq

顶行 (section.help) 是我最近的尝试,但有点混乱只是因为我在中途停下来,遭受了足以导致我发这篇文章的挫败感。

中间一排,我称之为section.weirdness,实际上似乎是一个炎热的时刻的解决方案。如果您像我一样使用 Chrome,当您查看 Codepen 链接时,您可能在这些蓝色块上什么也看不到?

但是尝试从div.flex 中删除display: flex 属性,如果您的Chrome 与我的Chrome 一样,您会看到:

现在,将 same display: flex 属性添加回 same div.flex 选择器,您会发现蓝色块突然不是空白的:

这有多奇怪?浏览器渲染错误还是什么?

现在找到div.image 上的max-widthmax-height 属性,关闭其中一个,然后再次打开,您会发现一切突然又恢复正常了:

不知何故,除了切换它之外没有更改任何 CSS,我们已经从根本不显示链接到它们显示出来并且看起来很完美。你可以看到我是如何设法让自己误以为我已经成功了!

【问题讨论】:

    标签: css flexbox centering


    【解决方案1】:

    这是一个简单的解决方案:

    我已将列更改为 flex 上下文,但保留了一个内部 div 作为 50% 宽度约束。当imgs 被允许明确地设置他们自己的高度时,他们周围的所有其他约束都会毫不费力地流入到位,并且由于锚点没有任何布局规则,他们设法避免在他们的图像之外有任何可点击区域.

    图像的最大高度相同,只要它们的容器宽度相同,它们就会以与.working 类相同的方式匹配。

    section {
      width: 800px;
      display: flex;
    }
    
    .column {
      background-color: blue;
      margin: 5px;
      width: 50%;
    
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .column > div {
      max-width: 50%;
    }
    
    img {
      display: block; /* get rid of bottom gap */
      max-width: 100%;
      max-height: 80px;
    }
    <section>
      <div class="column">
        <div>
          <a href="#">
            <img src="https://via.placeholder.com/500x500.png" />
          </a>
        </div>    
      </div>
      <div class="column">
        <div>
          <a href="#">
            <img src="https://via.placeholder.com/1000x300.png" />
          </a>
        </div>
      </div>
    </section>

    【讨论】:

    • 是的,这是不错的海王星,谢谢。我希望能够修复它,而无需在图像上指定与主容器高度相同的最大高度,但当然这是一个很好的修复。这个问题绝对是关于通过关卡传递高度和最大高度的理解,即使你的解决方案没有解决那个,它仍然解决了我的主要问题。也许我不应该以解决更大的问题为目标!再次感谢,除非出现任何不需要指定图像高度的情况,否则会将您的解决方案标记为解决方案!
    • 嗯,事实上,使用这种方法,您根本不需要在主容器上设置高度。容器严格关注宽度,图像将用尽所有宽度,直到达到最大高度。容器将垂直扩展以包含您选择为图像提供的任何高度:)
    • 啊,但是为了从容器 div (.column) 中删除最大高度,您将 display: flex 添加到该部分。真实页面比我的简化示例复杂得多,而且我不能乱用部分样式,这就是为什么我在原始帖子中的一个规范指出它们不是(在真实页面上)的一部分一个共享容器 - 根据此处使用的示例,section 元素实际上并不存在。无论如何,再次感谢您的原始版本 - 我现在正在使用它,并且必须在两个地方指定 max-height 并不是世界末日。
    • 酷,我很高兴能帮上忙。如果两个地方的最大高度相同,那可能是 CSS 变量的好地方。
    【解决方案2】:

    尝试将此添加到您的 Codepen 示例中:

    .flex > a {
      flex: 0 0 50%;
      height: 100%;
      display: flex;
    }
    
    div.flex a > img {
      max-width: 100% !important;
      max-height: 100% !important;
      margin: auto;
    }
    

    具有display: flex 的容器的任何直接子级都是弹性项目。为了防止该项目增长或缩小,我们必须将flex-growflex-shrink 属性设置为0。在我的例子中,我使用了flex: 0 0 50% 的简写。最后一个 50% 的值来自您的初始图像 max-width 属性。 + height:100% 将确保 &lt;a&gt; 的行为类似于原始示例中的图像。 现在有趣的部分:在&lt;a&gt; 上再次使用display: flex 来再次制作image flex 项目。由于&lt;a&gt; 的大小已经合适,我们可以将max-widthmax-height 设置为`00% 以填充可用空间。

    使用margin: auto 是一种巧妙的技巧,可以在 flex 容器中水平和垂直居中 flex 子项(仅在有一个子项时有效)。

    旁注:我使用important 覆盖特异性而不更改标记,但我建议不要这样做,并在aimg 上添加新的CSS 类。


    更新

    工作叉(仅限 Chrome):https://codepen.io/teodragovic/pen/wvwpWbx?editors=1100

    section.broken {
      .flex {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
      }
    
      a {
        max-width: 50%;
        max-height: 100%;
      }
    
      img {
        max-width: 100%;
        max-height: 100%;
        display: block;
      }
    }
    

    【讨论】:

    • 感谢您的帮助 Teo!在您的 fork 中,您可以看到链接不再局限于应有的子图像的大小(所有红色背景)。我可能忘记在我的帖子中提及这是一项要求 - 抱歉 - 但我认为找到一个没有可见红色背景的解决方案会更加用户友好。
    • @MattMorrison 我更新了我的叉子,没有红色背景:)
    • 检查了您的新链接 - 1000x300 图像上没有悬垂链接(红色),但 500x500 有悬垂链接,甚至不再居中。对不起! i.imgur.com/aM4ryAv.png
    【解决方案3】:

    只需将 style="display: contents" 添加到您的锚点

    • "display: contents" 使元素的子元素看起来好像是元素父元素的直接子元素,忽略元素本身
     <div>
          <a style="display: contents" href="#">
            <img src="https://via.placeholder.com/1000x300.png" />
          </a>
        </div>
    

    【讨论】:

      猜你喜欢
      • 2012-01-29
      • 2020-11-17
      • 2020-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-16
      • 1970-01-01
      相关资源
      最近更新 更多