CSS定位相对:宽度无效

4

我尝试构建 一个纯CSS树形结构。我在块之间的水平线(两个块处于同一级别)遇到了问题。我在以下jsfiddles中分离了问题:

https://jsfiddle.net/8Lsv1ypd/3/

https://jsfiddle.net/8Lsv1ypd/4/

Html:

<span class="first">First</span>
<span class="second">Second</span>

CSS:
.first {
  background-color: #dc3545;
  color: #fff;
  font-size: 1.2rem;
  border: 1px #ccc solid;
  border-radius: 20px;
  padding: 5px 10px;
  margin-top: 10px;
}

.second {
  background-color: #6f42c1;
  color: #fff;
  font-size: 1.2rem;
  border: 1px #ccc solid;
  border-radius: 5px;
  padding: 5px 10px;
  margin-top: 10px;
  margin-left: 10px;
}

.second::before {
  content: "";
  position: relative;
  top: -13px;
  left: -30px;
  border-left: 1px solid #aaa;
  border-bottom: 1px solid #000;
  border-radius: 0 0 0 0px;
  height: 26px;
  width: 50px !important;
}

当CSS位置(在.second :: before中)设置为相对时,宽度(以像素为单位固定)不会被考虑,只显示垂直线,并且宽度由浏览器“强制”为1像素。

当CSS位置(在.second :: before中)设置为绝对时,宽度不被考虑,水平线被显示,但该线未连接两个块。

我已经尝试了以下选项的许多组合:

  • position:absolute / relative / static / fixed
  • display:block / inline
  • overflow:auto / visible;

我已经查看了以下问题:

以下是需要翻译的文章:

https://alistapart.com/article/css-positioning-101


3
你需要使用 inline-block。伪元素默认为内联元素。当设置为绝对定位时,它们变成块级元素,但是当相对定位时仍保持内联。 - Temani Afif
1
对于第二个问题,position:absolute需要一个参考点,因此您需要将position:relative;添加到span元素中,以使left/top按照您的要求工作。 - Temani Afif
我同意@TemaniAfif的观点,display: inline-blockposition: relative是正确的选择。 - Jake
是的...很棒的建议:https://jsfiddle.net/bhn4kso9/ 但我无法去掉文本“Second”前面的空格。 - Fifi
是的,使用float:left;代替inline-block可以避免display:inline-block始终占用一些空间 :) - Amarjit Singh
1个回答

4
当CSS的position属性(在.second::before中)被设置为relative时,只显示垂直线而不考虑宽度(以像素为固定单位),并且浏览器会将其宽度“强制”设为1像素。伪元素默认是内联元素,设置position:relative不会改变这一点,因此无法对该元素应用width和height。然后,浏览器不会强制将宽度设置为1px,而是等于设置的边框为1px。高度也无效,元素和边框的高度由字体属性定义。增加高度,您将看到没有任何变化。

.first {
  background-color: #dc3545;
  color: #fff;
  font-size: 1.2rem;
  border: 1px #ccc solid;
  border-radius: 20px;
  padding: 5px 10px;
  margin-top: 10px;
}

.second {
  background-color: #6f42c1;
  color: #fff;
  font-size: 1.2rem;
  border: 1px #ccc solid;
  border-radius: 5px;
  padding: 5px 10px;
  margin-top: 10px;
  margin-left: 10px;
}

.second::before {
  content: "";
  top: -13px;
  left: -30px;
  border-left: 1px solid #aaa;
  border-bottom: 1px solid #000;
  border-radius: 0 0 0 0px;
  height: 600px;
  width: 50px !important;
}
<span class="first">First</span>
<span class="second">Second</span>

现在增加font-size,你将看到一些变化。

.first {
  background-color: #dc3545;
  color: #fff;
  font-size: 1.2rem;
  border: 1px #ccc solid;
  border-radius: 20px;
  padding: 5px 10px;
  margin-top: 10px;
}

.second {
  background-color: #6f42c1;
  color: #fff;
  font-size: 1.2rem;
  border: 1px #ccc solid;
  border-radius: 5px;
  padding: 5px 10px;
  margin-top: 10px;
  margin-left: 10px;
}

.second::before {
  content: "";
  top: -13px;
  left: -30px;
  border-left: 1px solid #aaa;
  border-bottom: 1px solid #000;
  border-radius: 0 0 0 0px;
  height: 600px;
  font-size:50px;
  width: 50px !important;
}
<span class="first">First</span>
<span class="second">Second</span>

当CSS位置(在.second::before中)设置为绝对定位时,宽度不会被考虑,水平线会显示,但是该线不会连接两个块。
当添加position:absolute后,该元素将变成块级元素,因此您可以控制其宽度和高度,并且在您的情况下两者都会被考虑,但是由于没有定位祖先,因此该元素相对于视口进行定位。它被隐藏了,因为您设置了负左值,因此您无法看到您设置的边框。
您需要使span position:relative以使伪元素相对于span定位:

.first {
  background-color: #dc3545;
  color: #fff;
  font-size: 1.2rem;
  border: 1px #ccc solid;
  border-radius: 20px;
  padding: 5px 10px;
  margin-top: 10px;
}

.second {
  background-color: #6f42c1;
  color: #fff;
  font-size: 1.2rem;
  border: 1px #ccc solid;
  border-radius: 5px;
  padding: 5px 10px;
  margin-top: 10px;
  margin-left: 10px;
  position:relative;
}

.second::before {
  content: "";
  position: absolute;
  top: -13px;
  left: -30px;
  border-left: 1px solid #aaa;
  border-bottom: 1px solid #000;
  border-radius: 0 0 0 0px;
  height: 26px;
  width: 50px !important;
}
<span class="first">First</span>
<span class="second">Second</span>


10.3.1 内联非替换元素

'width' 属性不适用 参考


10.6.1 内联非替换元素

'height' 属性不适用。内容区域的高度应该基于字体 参考


浮动、绝对定位元素、非块级盒子(例如内联块、表格单元格和表格标题)以及 'overflow' 值为非 'visible' 的块级盒子 (除非该值已传播到视口) 会为其内容建立新的块级格式化上下文参考


在绝对定位模型中,盒子明确相对于包含块偏移

如果元素具有'position: absolute',则包含块由具有 'position' 为 'absolute'、'relative' 或 'fixed' 的最近祖先元素建立,... 如果没有这样的祖先元素,则包含块是初始包含块参考



太好了!完美而棒的答案。我还需要进行一些调整,但主要核心已经在这里:https://jsfiddle.net/hkuwgpms/ 非常感谢你。 - Fifi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接