I'm working on a web layout where I need to display a series of steps connected by a line. I've set up a flexbox layout with spheres representing each step and a line connecting them. However, there's too much space horizontally between the line and the spheres, while I want to bring the line closer to the spheres. Ideally it should be only a few pixels between them.
Here's the HTML and CSS code I'm using:
.steps-container,
.label-container {
display: flex;
flex-direction: row;
justify-content: center;
}
.step {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.sphere {
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
border-radius: 50%;
background-color: lightgrey;
color: white;
font-size: 32px;
}
.line {
position: relative;
top: 25px;
height: 3px;
background-color: lightgrey;
flex-grow: 1;
max-width: 150px;
}
.label {
text-align: center;
position: relative;
}
.spacer {
flex-grow: 1;
max-width: 150px;
}
<div class="steps-container">
<div class="step">
<div class="sphere">1</div>
<div class="label">First step label</div>
</div>
<div class="line"> </div>
<div class="step">
<div class="sphere">2</div>
<div class="label">Second step label</div>
</div>
</div>
I suspect the problem lies in my .line
CSS class.
I didn't manage to resolve the problem and I'm starting to doubt it is even possible to do what I'm trying to do. I tried moving the line using position: relative
but I can't adjust the length of the line that way. I also tried using position: absolute
but I just can't get the result I'm expecting and I don't really know how to position the line using absolute values correctly.
The line
is as wide as it can be with basic flexbox, if you put an outline on the step
elements you will see the problem.
.steps-container,
.label-container {
display: flex;
flex-direction: row;
justify-content: center;
}
.step {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
outline: 1px solid red;
}
.sphere {
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
border-radius: 50%;
background-color: lightgrey;
color: white;
font-size: 32px;
}
.line {
position: relative;
top: 25px;
height: 3px;
background-color: lightgrey;
flex-grow: 1;
max-width: 150px;
}
.label {
text-align: center;
position: relative;
}
.spacer {
flex-grow: 1;
max-width: 150px;
}
<div class="steps-container">
<div class="step">
<div class="sphere">1</div>
<div class="label">First step label</div>
</div>
<div class="line"> </div>
<div class="step">
<div class="sphere">2</div>
<div class="label">Second step label</div>
</div>
</div>
In addition, the label
is forcing the steps to be wider than the 50px of the "sphere" as you can see in the snippet above.
An option is to force the step
to only be as wide as the sphere
, which we can do by setting the width
to 0
but adding a min-width
of 100%
.
.steps-container,
.label-container {
display: flex;
flex-direction: row;
justify-content: center;
}
.step {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
outline: 1px solid red;
}
.sphere {
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
border-radius: 50%;
background-color: lightgrey;
color: white;
font-size: 32px;
}
.line {
position: relative;
top: 25px;
height: 3px;
background-color: lightgrey;
flex-grow: 1;
max-width: 150px;
z-index: 2
}
.label {
text-align: center;
position: relative;
width: 0;
min-width: 100%;
}
.spacer {
flex-grow: 1;
max-width: 150px;
}
<div class="steps-container">
<div class="step">
<div class="sphere">1</div>
<div class="label">First step label</div>
</div>
<div class="line"> </div>
<div class="step">
<div class="sphere">2</div>
<div class="label">Second step label</div>
</div>
</div>
This leaves us with the problem of the label
which we can solve by forcing nowrap
and adjusting to recenter the text with a transform.
.steps-container,
.label-container {
display: flex;
flex-direction: row;
justify-content: center;
}
.step {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.sphere {
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
border-radius: 50%;
background-color: lightgrey;
color: white;
font-size: 32px;
}
.line {
position: relative;
top: 25px;
height: 3px;
background-color: lightgrey;
flex-grow: 1;
max-width: 150px;
z-index: 2
}
.label {
text-align: center;
position: relative;
width: 0;
min-width: 100%;
white-space: nowrap;
translate: -50%;
}
.spacer {
flex-grow: 1;
max-width: 150px;
}
<div class="steps-container">
<div class="step">
<div class="sphere">1</div>
<div class="label">First step label</div>
</div>
<div class="line"> </div>
<div class="step">
<div class="sphere">2</div>
<div class="label">Second step label</div>
</div>
</div>