css 元素边框以奇怪的方式影响其他元素

css element border influence on other elements in a weird way

我遇到了一件奇怪的事情,我无法理解原因。 我已经创建了一个 fiddle to demonstrate 问题。

我无法理解的是为什么为三个画布之一设置边框会使我的另外两个 .headerMainDiv 从它们的原始位置下降(尝试调整边框的大小/删除边框并查看效果).

这是我的相关部分 html:

<header>
    <div class="headerMainDiv">         
        <div class="inner">         
            <canvas id="canvas1">

            </canvas>   
        </div>      
    </div>
    <div class="headerMainDiv">         
        <div class="inner">         
            <canvas id="canvas2">

            </canvas>   
        </div>      
    </div>
    <div class="headerMainDiv">
        <div class="inner">         
            <canvas id="canvas3">

            </canvas>   
        </div>      
    </div>
</header>

这里是相关的 css:

#canvas2{
  border:10px solid black;
}

.inner {
  margin-top: 2px;
}

.headerMainDiv {
  height: 100%;
  width: 30%;
  background-color:red;
}

body{
  margin: 0;        
}

header{
  height: 20%;
  width: 100%;
  top:0px;
  text-align: center;
  position: fixed;
  z-index: 5;
  background-color: blue;
}

header div {
  display: inline-block;
}

canvas {
  background-color: grey;
  width:100%;
  height:100%;
}

我不是在寻找问题的解决方案,而是在寻找对此“问题/行为”的解释。

非常感谢。 吉米男孩。

那是因为您在 canvas 元素上声明了 100% 的宽度,并在 之上添加了边框 。这会导致宽度超过100%,导致溢出。

您可以做的是强制浏览器计算边框宽度作为宽度声明的一部分。这可以通过在 canvas 元素上使用 box-sizing: border-box 来完成:

#canvas2{
  border:10px solid black;
}

.inner {
  margin-top: 2px;
}

.headerMainDiv {
  height: 100%;
  width: 30%;
  background-color:red;
}

body{
  margin: 0;        
}

header{
  height: 20%;
  width: 100%;
  top:0px;
  text-align: center;
  position: fixed;
  z-index: 5;
  background-color: blue;
}

header div {
  display: inline-block;
}

canvas {
  box-sizing: border-box; /* Force border widths to be part of declared width */
  background-color: grey;
  width:100%;
  height:100%;
}
<header>
    <div class="headerMainDiv">         
        <div class="inner">         
            <canvas id="canvas1">

            </canvas>   
        </div>      
    </div>
    <div class="headerMainDiv">         
        <div class="inner">         
            <canvas id="canvas2">

            </canvas>   
        </div>      
    </div>
    <div class="headerMainDiv">
        <div class="inner">         
            <canvas id="canvas3">

            </canvas>   
        </div>      
    </div>
</header>

但是,如果你想让所有的 div 看起来都一样高,你需要确保第二个 canvas 中的额外边框高度也添加到那些 canvases 无边框,作者:

  1. 使用上下透明边框
  2. 在第一个和第三个上使用顶部和底部边距canvas
  3. 在第一个和第三个的父元素上使用顶部和底部填充canvas

这里是使用第一个解决方案的解决方案:

#canvas1, #canvas3 {
  border: 10px solid transparent;
}
#canvas2{
  border: 10px solid black;
}
.inner {
  margin-top: 2px;
}

.headerMainDiv {
  height: 100%;
  width: 30%;
  background-color:red;
}

body{
  margin: 0;        
}

header{
  height: 20%;
  width: 100%;
  top:0px;
  text-align: center;
  position: fixed;
  z-index: 5;
  background-color: blue;
}

header div {
  display: inline-block;
}

canvas {
  box-sizing: border-box; /* Force border widths to be part of declared width */
  background-color: grey;
  width:100%;
  height:100%;
}
<header>
    <div class="headerMainDiv">         
        <div class="inner">         
            <canvas id="canvas1">

            </canvas>   
        </div>      
    </div>
    <div class="headerMainDiv">         
        <div class="inner">         
            <canvas id="canvas2">

            </canvas>   
        </div>      
    </div>
    <div class="headerMainDiv">
        <div class="inner">         
            <canvas id="canvas3">

            </canvas>   
        </div>      
    </div>
</header>

如果您需要边框不影响框的宽度,则需要指定 box-sizing 属性。

   #canvas2{
      border:10px solid black;
      box-sizing:border-box;
   }

将框大小设置为 border-box 可避免填充和边框,而不会影响您的宽度。看看这个

http://jsfiddle.net/d6tukcdz/6/

如果这不是你的问题,请解释得更好

这是因为边框增加了元素的宽度。使用 box-sizing: border-box 会将边框包含在元素的总宽度中。

display: inline-block; vertical-align: top; 添加到 .headerMainDiv 应该可以解决对齐问题 - 已更新 fiddle.

canvas {
    box-sizing: border-box;
    background-color: grey;
    width:100%;
    height:100%;
}

.headerMainDiv {
    display: inline-block;
    vertical-align: top;
    height: 100%;
    width: 30%;
    background-color:red;
}

这是因为您使用了 display 作为 inline-block。 vertical-align 属性 继承为 baseline。这就是您看到所有 div 都与父级 div 的地板对齐的原因。

what I am failing to understand is why setting a border to one of the three canvases makes my two other .headerMainDiv go down from their original position (try to play with the border's size / delete the border and see the effect).

我认为您指的是垂直对齐方式,默认情况下,对于内联块元素设置为 baseline...它包裹了您的 canvas 元素。

您真正需要做的就是设置:

header div {
    display: inline-block;
    vertical-align: top;
}

JSfiddle Demo

也就是说,使用 border-box 可能是一个不错的默认选项,因此我将其包含在演示中。