【问题标题】:Pseudo element not full container width when border used使用边框时伪元素不是完整的容器宽度
【发布时间】:2019-06-20 17:27:44
【问题描述】:

我有一段 html/css 代表一个带边框的按钮。

按钮具有覆盖按钮的伪元素 - 简单示例显示其中之一。

伪元素比原始元素高(使用 px 设置高度)但宽度相同(设置为 100%)。

在当前的设计中,有两个问题没有像我预期的那样工作:

  1. 尽管使用了 box-sizing:border-box,但伪宽度没有 包括边框。
  2. 伪元素是绝对定位的(顶部,左侧),但是这个 参考位置在父边框内。

这在 Chrome 和 Edge 中似乎是相同的,这表明我做的不对 - 但是,我对 box-sizing 感到特别困惑。

.container {
  padding: 50px;
}

.button {
  border: solid 4px red;
  box-sizing: border-box;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  height: 36px;
  padding: 0 16px;
  position: relative;
  z-index: 1;
}

.button::before {
  background-color: rgba(76, 255, 0, 0.8);
  box-sizing: inherit;
  content: "";
  display: block;
  position: absolute;
  top: -4px;
  left: 0;
  height: 44px;
  width: 100%;
  z-index: -1;
}
<div class="container">
  <a class="button">Button</a>
</div>

【问题讨论】:

  • 这是合乎逻辑的,边框在父元素而不是伪元素上,box-sizing 与那里无关.. 是的,参考是填充框,而不是边框​​框跨度>
  • 该位置在其父级内部,因为父级有position: relativejsbin.com/dupubutofa/edit?html,css,output
  • @TemaniAfif - 我不相信盒子大小是合乎逻辑的。比方说,父宽度是 100px,包括 8px 边框(4px x 2),我希望伪也有 100px 的宽度。
  • 不,元素的宽度将是父元素减去边框的宽度

标签: html css


【解决方案1】:

来自the specification

元素框的位置和大小有时是相对于某个矩形计算的,称为元素的包含块。元素的包含块定义如下:

....

  1. 如果元素具有“位置:绝对”,则包含块由最近的祖先建立,其“位置”为“绝对”、“相对”或“固定”,如下所示大大地:
    1. 在祖先是内联元素的情况下,包含块是围绕为该元素生成的第一个和最后一个内联框的填充框的边界框。在 CSS 2.1 中,如果内联元素被拆分为多行,则包含块是未定义的。
    2. 否则,包含块由祖先的填充边缘形成

然后

填充边缘围绕盒子填充。如果 padding 的宽度为 0,则 padding 边缘与内容边缘相同。四个填充边定义了盒子的填充框。

这解释了为什么您的元素在定位时不使用边框框作为参考,而是使用填充框。百分比宽度1 也是如此。使用width:100% 表示包含块的填充和内容。不计算边框。


关于box-sizing

... ,在元素上指定的任何填充或边框都会在此指定的宽度和高度内进行布局和绘制。

所以边框需要属于元素而不是父元素才能考虑box-sizing,这不是你的情况,因为边框没有应用于伪元素:


1 对于包含块基于块容器元素的绝对定位元素,百分比是根据填充框的宽度计算的 的那个元素。ref

.box {
  border:5px solid;
  padding:10px;
  background:red;
  min-height:100px;
  position:relative;
}
span:first-child {
  display:inline-block;
  width:100%;
  background:blue;
}
span:last-child {
  position:absolute;
  bottom:0;
  left:0;
  width:100%;
  background:green;
}
<div class="box">
  <span>I am a static element</span>
  <span>I am a absolute element</span>
</div>

获得你想要的东西的一个想法是使用 inset box-shadow 而不是边框​​:

.container {
  padding: 50px;
}

.button {
  box-shadow: inset 0 0 0 4px red;
  box-sizing: border-box;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  height: 36px;
  padding: 0 16px;
  position: relative;
  z-index: 1;
}
.button::before {
  background-color: rgba(76, 255, 0, 0.8);
  box-sizing: inherit;
  content: "";
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  z-index: -1;
}
<div class="container">
    <a class="button">Button</a>
</div>

【讨论】:

    【解决方案2】:

    尝试将伪元素的宽度与父级边框的大小一起增加,并用left: -4px将其向左移动:

    .container {
      padding: 50px;
    }
    
    .button {
      border: solid 4px red;
      box-sizing: border-box;
      display: inline-flex;
      justify-content: center;
      align-items: center;
      height: 36px;
      padding: 0 16px;
      position: relative;
      z-index: 1;
    }
    
    .button::before {
      background-color: rgba(76, 255, 0, 0.8);
      box-sizing: inherit;
      content: "";
      display: block;
      position: absolute;
      top: -4px;
      left: -4px;
      height: 44px;
      width: calc(100% + 8px);
      z-index: -1;
    }
    <div class="container">
      <a class="button">Button</a>
    </div>

    【讨论】:

    • border-box 告诉浏览器考虑您为元素的宽度和高度指定的值中的任何边框和填充。 developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
    • 我不知道为什么这个答案被标记了 - 如果 Temani Afif 说的是对的,那么唯一的解决方案就是使用这样的方法来修复它。
    猜你喜欢
    • 1970-01-01
    • 2019-07-14
    • 2011-02-14
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2018-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多