The issue with the inconsistent offset of text is due to the physical space taken up by the border of an element in the layout. To address this, you have a couple of options - either adjust for the space the border occupies (solution 1), or explore alternative approaches that maintain the document flow (solutions 2 and 3).
You can implement:
- A transparent left-border on all
<li>
elements,
- Use of a
background-image
to simulate a border visually, or
- An absolutely positioned pseudo-element.
Solution 1: Transparent left border
This method involves adding a transparent border to all <li>
elements and changing the border-color
property as needed:
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>
Solution 2: Using background image for border
Alternatively, you can employ a linear gradient as a background image with a distinct border/breakpoint to mimic a border visually:
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>
Solution 3: Using Absolutely Positioned Pseudo-Element
This approach utilizes a generated pseudo-element that is absolutely positioned within the <li>
element to replicate a border visually:
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>