使用边框 属性 时如何将锚标记中的文本保持在同一位置

How to keep text in anchor tag in the same position when border property is used

我打算使用 Bootstrap 的 Scrollspy 组件来处理 <ul> 元素。

我的问题是,当我在 <li> 元素上使用 border-left 属性 时,锚标记中的文本会稍微向右移动。

我该怎么做才能解决这个问题?

请看笔:

https://codepen.io/AshNaz87/pen/QmVJVY

.wrapper {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

li {
  list-style: none;
  margin-bottom: 0.5rem;
  padding-left: 1rem;
}

li:last-child {
  margin: 0;
}

.with-border {
  border-left: 3px solid grey;
}

a {
  text-decoration: none;
  color: #000;
}
<div class="wrapper">
  <ul class="nav">
    <li class="with-border"><a href="#">Fortune</a></li>
    <li><a href="#">Favours</a></li>
    <li><a href="#">The</a></li>
    <li class="with-border"><a href="#">Brave</a></li>
  </ul>
</div>

您看到文本偏移不一致的原因是元素的边框实际上占据了布局中的物理空间 space。为避免这种情况,您需要考虑 space 边界将采用(参见解决方案 1),或使用不改变文档流的替代策略(参见解决方案 2 和 3)。

您可以使用:

  1. 所有元素 <li>
  2. 透明 left-border
  3. background-image 在视觉上模仿边框,或
  4. 绝对定位pseudo-element

解决方案一:透明左边框

此解决方案意味着在所有 <li> 元素上引入透明边框,并在需要时简单地更改 border-color 属性:

li {
  border-left: 3px solid transparent;
}

li.with-border {
  border-color: grey;
}

.wrapper {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

li {
  border-left: 3px solid transparent;
  list-style: none;
  margin-bottom: 0.5rem;
  padding-left: 1rem;
}

li:last-child {
  margin: 0;
}

li.with-border {
  border-color: grey;
}

a {
  text-decoration: none;
  color: #000;
}
<div class="wrapper">
  <ul class="nav">
    <li class="with-border"><a href="#">Fortune</a></li>
    <li><a href="#">Favours</a></li>
    <li><a href="#">The</a></li>
    <li class="with-border"><a href="#">Brave</a></li>
  </ul>
</div>


解决方案 2:background-image 模拟边框

或者,您可以使用线性渐变作为背景图像,并具有清晰的界限 border/breakpoint,以在视觉上模仿边框:

li.with-border {
  background-image: linear-gradient(90deg, grey 3%, transparent 3%);
}

.wrapper {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

li {
  list-style: none;
  margin-bottom: 0.5rem;
  padding-left: 1rem;
}

li:last-child {
  margin: 0;
}

li.with-border {
  background-image: linear-gradient(90deg, grey 3%, transparent 3%);
}

a {
  text-decoration: none;
  color: #000;
}
<div class="wrapper">
  <ul class="nav">
    <li class="with-border"><a href="#">Fortune</a></li>
    <li><a href="#">Favours</a></li>
    <li><a href="#">The</a></li>
    <li class="with-border"><a href="#">Brave</a></li>
  </ul>
</div>


解决方案 3:Absolutely-positionedpseudo-element

这个解决方案是最冗长的解决方案:它使用生成的 pseudo-element 绝对定位在 <li> 元素内以在视觉上模仿边框:

li {
  position: relative;
}

li::before {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 3px;
  display: none;
  content: '';
  background-color: grey;
}

li.with-border::before {
  display: block;
}

.wrapper {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

li {
  position: relative;
  list-style: none;
  margin-bottom: 0.5rem;
  padding-left: 1rem;
}

li:last-child {
  margin: 0;
}

li::before {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 3px;
  display: none;
  content: '';
  background-color: grey;
}

li.with-border::before {
  display: block;
}

a {
  text-decoration: none;
  color: #000;
}
<div class="wrapper">
  <ul class="nav">
    <li class="with-border"><a href="#">Fortune</a></li>
    <li><a href="#">Favours</a></li>
    <li><a href="#">The</a></li>
    <li class="with-border"><a href="#">Brave</a></li>
  </ul>
</div>