为什么当父元素的宽度改变时,子元素的宽度也会改变?

why is child element's width changing when parent's width changes?

我正在尝试创建一个最小宽度为 50 像素、最大宽度为 200 像素的工具提示元素。我将 tooltip 元素放在另一个元素中,这样我就可以轻松地控制在父元素上有悬停事件时 tooltip 何时出现或消失。

我遇到的问题是工具提示元素的宽度似乎由父元素的宽度控制,即使我指定子元素(工具提示)具有绝对位置。

let p = document.getElementById( 'parent' );
let b = true;
setInterval( ()=> {
  b = !b;
  let w = 10;
  if( b ) {
    w = 300;
  }
  p.style.width = `${w}px`
}, 5000 );
#parent {
  background-color: cyan;
  width: 100px;
  height: 25px;
  position: relative;
  transition: width 2s;
}

#tooltip {
  position: absolute;
  top: calc( 100% + 5px );
  left: 5px;
  min-width: 50px;
  max-width: 200px;
  background-color: yellow;
  padding: 5px;
  border: 1px solid black;
}
<div id="parent">
  <div id="tooltip">
    My long tooltip text that wraps to multiple lines as needed.
  </div>
</div>

在此示例中,我希望工具提示(黄色 div)的大小保持在 200px,但我们可以看到,当父级更改宽度时,工具提示宽度也会更改。为什么?

有办法解决这个问题吗?

澄清:在这个例子中:https://codepen.io/anon/pen/ePPWER我们看到工具提示文本在一行上看起来不错。我不希望工具提示的 div 在父级更改宽度时更改其宽度,因为它强制工具提示文本换行到 2 行,这是不希望的。

ID Tooltip 正在 Parent 下使用。当父级的宽度发生变化时,它也会提示 tooltip 的总宽度发生变化。由于您使用了 mix-width 和 max-width,它将扩展直到达到 max-width。如果你想固定它那么简单使用宽度。

因为.parent有个position: relative。这将保留所有children(包括position: absolute)由parent div.

限制

不确定这是否对您有用,因为它将 tooltip 从 parent 中拉出来,并用 span 包装文本使其成为自己的。或者,您需要将 parent 更改为 relative 否则它会持续影响 child.

let p = document.getElementById('parent');
let b = true;
setInterval(() => {
  b = !b;
  let w = 10;
  if (b) {
    w = 300;
  }
  p.style.width = `${w}px`
}, 5000);
#parent {
  background-color: cyan;
  width: 100px;
  height: 25px;
  transition: width 2s;
  position: relative;
}

#root {
  position: relative;
}

#tooltip {
  width: 100%;
}

#tooltip span {
  position: absolute;
  top: calc( 100% + 5px);
  left: 5px;
  min-width: 50px;
  max-width: 200px;
  background-color: yellow;
  padding: 5px;
  border: 1px solid black;
}
<div id="root">
  <div id="parent"></div>
  <div id="tooltip">
    <span>My long tooltip text that wraps to multiple lines as needed.</span>
  </div>
</div>

如果我们检查相关规范 to the width of absolutely positioned element 我们可以读到:

  1. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right'

因此在您的情况下,元素的宽度会缩小以适合:

Calculation of the shrink-to-fit width is similar to calculating the width of a table cell using the automatic table layout algorithm. Roughly: calculate the preferred width by formatting the content without breaking lines other than where explicit line breaks occur, and also calculate the preferred minimum width, e.g., by trying all possible line breaks. CSS 2.1 does not define the exact algorithm. Thirdly, calculate the available width: this is found by solving for 'width' after setting 'left' (in case 1) or 'right' (in case 3) to 0.

Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).

为了简单起见,在不考虑 min/max-width 的情况下,您的元素的宽度将尝试适应内容而不超过其父容器(包含块)的宽度。通过添加 min/max-width,您只需添加更多约束。

修复它的一个想法是从父元素中删除 positon:relative,这样它就不再是 position:absolute 元素的包含块(it will be the initial containing block 足够宽以避免可用宽度 约束)。

然后用保证金代替top/left来控制仓位:

let p = document.getElementById( 'parent' );
let b = true;
setInterval( ()=> {
  b = !b;
  let w = 10;
  if( b ) {
    w = 300;
  }
  p.style.width = `${w}px`
}, 5000 );
#parent {
  background-color: cyan;
  width: 100px;
  height: 25px;
  transition: width 2s;
}

#tooltip {
  position: absolute;
  margin-top: 30px;
  min-width: 50px;
  max-width: 200px;
  background-color: yellow;
  padding: 5px;
  border: 1px solid black;
}
<div id="parent">
  <div id="tooltip">
    My long tooltip text that wraps to multiple lines as needed.
  </div>
</div>