为什么改变一个元素的宽度会影响它的兄弟?

Why changing an element's width affects its sibling?

这不是第一次发生了,我一直没有找到好的解释。

在这种特殊情况下,我在 div 中有一个 h3 和一个 p。一旦我更改了 pwidthh3 的宽度也发生了变化,就像将宽度应用于它们的父级一样。

  1. 为什么会这样?

  1. 我发现在我的案例中,修复(或至少一个修复)是将 display: inline-block 应用到 h3。如果删除它,您会看到该按钮占用段落的宽度 95vw。这怎么行?

谢谢

let button = document.querySelector('.button')
let body = document.querySelector('.body')
let container = document.querySelector('.container')

button.addEventListener('click', ()=> {
  let colorOne = parseInt((Math.random() * 255) + 1)
  let colorTwo = parseInt((Math.random() * 255) + 1)
  let colorThree = parseInt((Math.random() * 255) + 1)

  let colorOneOne = parseInt((Math.random() * 255) + 1)
  let colorTwoTwo = parseInt((Math.random() * 255) + 1)
  let colorThreeThree = parseInt((Math.random() * 255) + 1)

  let deg = parseInt((Math.random() * 360) + 1)

  body.style.background = 'linear-gradient(' + deg + 'deg' + ', ' + 'rgb(' + colorOne + ', ' + colorTwo + ', ' + colorThree + ')' +  ',' + 'rgb(' + colorOneOne + ',' + colorTwoTwo + ',' + colorThreeThree + '))'
  //linear-gradient(45deg, rgb(28,28,84), rgb(38,58,119))

  document.querySelector('.color').innerText = 'linear-gradient(' + deg + 'deg' + ', ' + 'rgb(' + colorOne + ', ' + colorTwo + ', ' + colorThree + ')' +  ',' + 'rgb(' + colorOneOne + ',' + colorTwoTwo + ',' + colorThreeThree + '))'

  button.style.border = 'none'
  document.querySelector('.scrollto').style.display = 'block'
})

window.addEventListener('touchmove', ()=> {
  body.style.background = 'white'
  document.querySelector('.color').innerText = ''
  document.querySelector('.scrollto').style.display = 'none'
  button.style.border = '1px solid black'
})
.button {
  font-family: 'Poppins', sans-serif;
  border-radius: .5em;
  padding: .3em .7em;
  font-size: 1.1em;
  position: relative;
  background: white;
  mix-blend-mode: screen;
  border: 1px solid black;
  display: inline-block;
}

@media screen and (max-width: 382px) {
  .button {
    width: 10em;
  }
}

body {
  min-height: 100vh;
  margin: 0;
}

.color {
  font-family: 'Poppins', sans-serif;
  color: white;
  text-shadow: 1px 1px 3px black;
  letter-spacing: 1px;
  display: block;
  width: 95vw;
  border: 2px solid black;
}

.container {
  text-align: center;
  position: absolute;
  top: 40vh;
  left: 50vw;
  transform: translate(-50%, -50%);
}

.scrollto {
  position: absolute;
  bottom: 10px;
  left: 50vw;
  transform: translateX(-50%);
  font-family: 'Poppins', sans-serif;
  font-size: .7em;
  display: none;
}
<body class="body">
  
    <div class="container">
      <h3 class="button">Generate Gradient</h3>
      <p class="color"></p>
    </div>
  
    <div class="line">
      <p class="scrollto">swipe on screen to reset</p>
    </div>

如果您从 h3 中删除 inline-block,它将获得其默认显示 block,这意味着 占据父元素的全宽.

现在,诀窍是 position:absolute 父元素的宽度。它的宽度由 shrink-to-fit 算法定义,这意味着宽度基于其内容。

内容是一个 h3 块元素和一个 p 块元素。您只定义了 p 的宽度,因此这将定义 position:absolute 元素的宽度,然后 h3 将是其父元素的全宽,因此它在逻辑上将遵循设置为 [=17= 的宽度].

这里有不同案例的说明,以便更好地理解:

.container {
  position:absolute;
  border:1px solid;
}
.container > * {
  border:1px solid red;
}
<div class="container">
  <h3 class="button">Generate Gradient</h3>
  <p class="color">some text </p>
</div>

<div class="container" style="top:150px">
  <h3 class="button">Generate Gradient</h3>
  <p class="color">a text longer than the above one</p>
</div>

<div class="container" style="left:250px">
  <h3 class="button" style="display:inline-block">Generate Gradient</h3>
  <p class="color">a text longer than the above one</p>
</div>

您可以看到,默认情况下两者都应为父宽度的 100%,较长的内容将定义该宽度。如果你制作一个元素 inline-block 它将简单地适应它的内容并且不再遵守块元素规则,即父元素的宽度为 100%。


这是一个简化的解释,如果您想要更准确的细节,您需要参考规范并了解每种情况下宽度的计算方式。

块元素:https://www.w3.org/TR/CSS21/visudet.html#blockwidth

行内块元素:https://www.w3.org/TR/CSS21/visudet.html#inlineblock-width

绝对定位元素:https://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width