【问题标题】:Outline on border-box [behaviour inconsistent on Chrome]边框上的轮廓 [Chrome 上的行为不一致]
【发布时间】:2016-02-26 21:05:33
【问题描述】:

给定 divtabindex="0" 我在 Firefox 和 Chrome 上得到了这种奇怪的 outline 行为。

.inner {
  margin-left: -20px;
  padding-left: 20px;
}

.context {
  margin-left: 40px;
  background-origin: content-box;
  background-color: limegreen;
}

.custom_outline:focus {outline: 3px solid blue;}
<div class="context" tabindex="0">
  <h1>Wrong outline on Firefox</h1>
  <h2>... but on Chrome is even WORSE</h2>
  <div>
    <div class="inner">Foo</div><div class="inner">Bar</div>
  </div>
</div>

<div class="context custom_outline" tabindex="0">
  <h1>Wrong outline on Firefox</h1>
  <h2>... but on Chrome is BETTER if I set an explicit outline</h2>
  <div>
    <div class="inner">Foo</div><div class="inner">Bar</div>
  </div>
</div>

默认情况下:

  • Firefox 的轮廓包裹了div包括它内部的负边距;这将绘制一个矩形。
  • Chrome 的轮廓包裹了div包括它内部的负边距;这绘制了一个多边形,它偏离负边距。

设置明确的大纲:

  • Firefox 的轮廓包裹了div包括它内部的负边距;这将绘制一个矩形。 [没有任何改变。行为一致,至少]
  • Chrome的轮廓包裹了div考虑到它内部的负边距;这绘制了一个忽略负边距的矩形

为什么会出现这种不一致的行为?是什么触发了 Chrome 的差异?谁更尊重 W3C 规范?

我想要实现的结果是 Chrome 的最后一种情况,轮廓包裹div 并忽略负边距(仅考虑 border-box ,就像 background-origin 属性发生的那样)

我该怎么做?

【问题讨论】:

    标签: css google-chrome cross-browser outline


    【解决方案1】:

    规范没有准确定义轮廓是如何绘制的,只是它们不影响布局,并且它们可能是非矩形的。触发 Chrome 差异的原因可能首先在于它是如何实现默认大纲的——你可以看出它看起来像使用纯 CSS 无法完成的事情。

    为了达到您想要的结果,您可以通过将轮廓添加到绝对定位的::before 焦点上的伪元素(并禁用元素本身的轮廓)来作弊:

    .inner {
      margin-left: -20px;
      padding-left: 20px;
    }
    
    .context {
      margin-left: 40px;
      background-origin: content-box;
      background-color: limegreen;
    }
    
    .custom_outline:focus {
      position: relative;
      outline: 0;
    }
    
    .custom_outline:focus::before {
      content: '';
      position: absolute;
      top: 0; right: 0; bottom: 0; left: 0;
      outline: 3px solid blue;
      z-index: -1;
    }
    <div class="context" tabindex="0">
      <h1>Default outline</h1>
      <div>
        <div class="inner">Foo</div><div class="inner">Bar</div>
      </div>
    </div>
    
    <div class="context custom_outline" tabindex="0">
      <h1>Custom outline</h1>
      <div>
        <div class="inner">Foo</div><div class="inner">Bar</div>
      </div>
    </div>

    【讨论】:

    • 非常好的解决方案 :) ... 但是z-index:-1 的原因(这是强制性的),顶部轮廓从相邻的 div.header 上方覆盖div.context(参见修改后的小提琴:jsfiddle.net/ushwmcs0)。当轮廓直接位于div.context 上而没有伪元素时,不会发生这种情况。怎么解决?
    • @Kamafeather:如果您负担得起使用pointer-events: none(我不确定浏览器对它的支持程度),请用它替换z-index: -1
    【解决方案2】:

    chrome 绘制区域的边缘而不是聚焦:

    您可以将outline 重置为none 并改用box-shadow

    .inner {
      margin-left: -20px;
      padding-left: 20px;
    }
    .context {
      margin-left: 40px;
      background-origin: content-box;
      background-color: limegreen;
    }
    .custom_outline:focus {
      box-shadow: 0 0 0 3px blue;
      outline: none;
    }
    <div class="context custom_outline" tabindex="0">
      <h1>box-shadow outlining Firefox</h1>
      <h2>... but on Chrome reset outline to none too</h2>
      <div>
        <div class="inner">Foo</div>
        <div class="inner">Bar</div>
      </div>
    </div>

    测试 chrome 的默认行为:查看它绘制可聚焦区域的边缘

    .inner {
      margin-left: -20px;
      padding-left: 20px;
      pointer-events: none;
    }
    .context {
      margin-right: 60%;
      margin-left: 40px;
      background-origin: content-box;
      background-color: limegreen;
    }
    .context:hover {
      outline-color: red;
      /* color  reset , if style is reset, behavior is reset too*/
    }
    h2:before {
      content: '';
      display: inline-block;
      width: 1em;
      padding: 1em;
      position: relative;
      left: 105%;/* outside the box */
    }
    <div class="context" tabindex="0">
      <h1>no outline on Firefox</h1>
      <h2>... but on Chrome ...</h2>
      <div>
        <div class="inner">Foo</div>
        <div class="inner">Bar</div>
      </div>
    </div>
    其中 FF 将在一个框中包含所有内容:

    .inner {
      margin-left: -20px;
      padding-left: 20px;
      pointer-events: none;
    }
    .context {
      margin-right: 60%;
      margin-left: 40px;
      background-origin: content-box;
      background-color: limegreen;
    }
    .context:focus {
      outline: solid 3px blue;
    }
    h2:before {
      content: '';
      display: inline-block;
      width: 1em;
      padding: 1em;
      position: relative;
      left: 105%;/* outside the box */
    }
    <div class="context" tabindex="0">
      <h1>Wrong outline on Firefox</h1>
      <h2>... but on Chrome is even WORSE</h2>
      <div>
        <div class="inner">Foo</div><div class="inner">Bar</div>
      </div>
    </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-22
      • 2014-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-26
      相关资源
      最近更新 更多