I'd like to use flex to create something similar to this with CSS:
What I've tried so far is this code:
#dot-container {
position: absolute;
width: 30vw;
background: black;
height: 8vw;
justify-content: center;
align-items: center;
display: flex;
}
.dot {
border-radius: 100%;
width: 2vw;
height: 2vw;
margin: 3.2%; /*(30-2*7) / (7-2)*/
background: green;
}
<div id="dot-container">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
But I cannot really get it working such that the leftmost and rightmost dots are exactly at the left and the right corner like you can see it in my image above.
Note: also justify-content: space-between;
seems not to work because the dots themselves are most left but not dots center!
This can be done using justify-content: space-between
and using a negative margin
.
#dot-container {
position: absolute;
width: 30vw;
background: black;
height: 8vw;
justify-content: space-between;
align-items: center;
display: flex;
}
.dot {
border-radius: 100%;
width: 2vw;
height: 2vw;
margin: -3.2%; /*(30-2*7) / (7-2)*/
background: green;
}
<div id="dot-container">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
Or, if you do not want to calculate margins you can add a child element with absolute positioning, and change number of div.dot
elements like you wish:
#dot-container {
position: relative;
width: 30vw;
height: 6vw;
justify-content: space-between;
align-items: center;
display: flex;
}
#dot-container-inner {
position: absolute;
left: 3%;
top: 0;
z-index: -1;
height: 100%;
width: 95%;
background: black;
}
.dot {
border-radius: 100%;
width: 2vw;
height: 2vw;
background: green;
}
<div id="dot-container">
<div id="dot-container-inner">
</div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
If possible, you can try multiple backgrounds instead of flexboxes. The idea is to use a radial gradient for the circles and a linear gradient for the background - see the demo below:
div{
width: 30vw;
height: 8vw;
margin: 10px;
background: radial-gradient(circle, green calc(1vw - 2px) calc(1vw - 1px), transparent 1vw) center / calc(100% / var(--n)) 2vw repeat-x,
linear-gradient(black, black) center / calc(100% - 100% / var(--n)) 100% no-repeat;
}
<div style="--n:5"></div>
<div style="--n:9"></div>
Now you can have a fixed width for the black background by changing the width of the div
based on the number of circles - see demo below with a red background to show the actual boundaries:
div {
height: 8vw;
margin: 10px calc(-15vw / var(--n));
position: relative;
width: calc(30vw + 30vw / var(--n));
background: radial-gradient(circle, green calc(1vw - 2px) calc(1vw - 1px), transparent 1vw) 0 50% / calc(30vw / var(--n)) 2vw repeat-x,
linear-gradient(black, black) center / calc(100% - 30vw / var(--n)) 100% no-repeat, red;
}
<div style="--n:3"></div>
<div style="--n:5"></div>
<div style="--n:9"></div>
Finish it up using a pseudo element to apply the background and having the width specified on the div
for generality - final result below:
div {
--w: 30vw;
height: 8vw;
width: var(--w);
margin: 10px;
position: relative;
}
div:after {
content: '';
position: absolute;
height: 100%;
width: calc(100% + 100% / var(--n));
margin: 0 calc(-1 * var(--w) / var(--n) / 2);
background: radial-gradient(circle, green calc(1vw - 2px) calc(1vw - 1px), transparent 1vw) 0 50% / calc(var(--w) / var(--n)) 2vw repeat-x,
linear-gradient(black, black) center / calc(100% - var(--w) / var(--n)) 100% no-repeat;
}
<div style="--n:3"></div>
<div style="--n:7"></div>
<div style="--n:9"></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With