Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I spread out my flex items to more than the width of a container?

Tags:

html

css

flexbox

I'd like to use flex to create something similar to this with CSS:

Click to see the image in fullscreen


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!

like image 674
Jonas Avatar asked Jan 27 '23 07:01

Jonas


2 Answers

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>
like image 123
Anurag Srivastava Avatar answered Jan 29 '23 20:01

Anurag Srivastava


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>
like image 40
kukkuz Avatar answered Jan 29 '23 21:01

kukkuz