Add a dividing line between the elements of flexibility with equal distribution of space

I have a list with various elements that have an automatic width (in my case, a fixed width cannot be set). I use justify-content: space-between because my first element should start at the beginning of the container and my last element at the end.

All of the above works fine, but whenever I try to add a line between these list items, problems begin to appear. I have no way to determine how many pixels or% I need to arrange these lines. Is there a way to β€œdynamically” arrange lines between different list items or not?

The HTML file we use cannot be edited, because it is displayed in the CMS we use.

Here is what I have:

This is what I have

This is what I'm trying to achieve.

Here is what I would like to achieve

Here is the code I have

 html { box-sizing: border-box; } .Container { max-width: 70%; margin-right: auto; margin-left: auto; background: blue; padding-top: 20px; padding-bottom: 20px; } .Flex { display: flex; flex-flow: row wrap; justify-content: space-between; list-style: none; margin: 0; padding: 0; } .Flex-item { background: red; position: relative; } .Flex-item:after { content: ""; position: absolute; background: white; width: 1px; height: 40px; top: 50%; transform: translateY(-50%); } 
 <div class="Container"> <ul class="Flex"> <li class="Flex-item">Lorem</li> <li class="Flex-item">consectetur</li> <li class="Flex-item">vestibulum</li> <li class="Flex-item">nec</li> <li class="Flex-item">condimentum</li> </ul> </div> 
+14
html css flexbox css3
source share
6 answers

I use this solution in the project I'm working on.

It sets justify-content: space-between; on flex container and flex: 1 1 auto; on children with a left frame on all children except the first.

I modified your CSS example so that you can take a look. I was not sure that you would have a background color for the children, so I just used the line height to get big borders.

 html { box-sizing: border-box; } .Container { max-width: 70%; margin-right: auto; margin-left: auto; background: blue; padding-top: 20px; padding-bottom: 20px; } .Flex { display: flex; flex-flow: row wrap; justify-content: space-between; list-style: none; margin: 0; padding: 0; } .Flex-item { flex: 1 1 auto; background: red; position: relative; text-align: center; line-height: 40px; } .Flex-item + .Flex-item { border-left: solid 1px white; } /** Optional for OPs exact layout */ .Flex-item:first-child { text-align: left; } .Flex-item:last-child { text-align: right; } 
 <div class="Container"> <ul class="Flex"> <li class="Flex-item">Lorem</li> <li class="Flex-item">consectetur</li> <li class="Flex-item">vestibulum</li> <li class="Flex-item">nec</li> <li class="Flex-item">condimentum</li> </ul> </div> 

No change to HTML.

+12
source share

You can make it work using nested flexbox es - I understand you cannot change the markup, but at least you have to wrap the contents of li in a span , as I here

  • Make the .flex-item also a flexbox with the text in the span (now it will have a red background), and the separator as an element :after

  • Apply flex-grow and flex-shrink to 1 and flex-basis to auto for Flex-item .

  • flex: 0 to the last Flex-item and margin-auto to :after also contributes to the effect.

The demonstration may explain this better - see below:

 html { box-sizing: border-box; } .Container { max-width: 70%; margin-right: auto; margin-left: auto; background: blue; padding-top: 20px; padding-bottom: 20px; } .Flex { display: flex; justify-content: space-between; list-style: none; margin: 0; padding: 0; } .Flex-item { display: flex; justify-content: space-between; align-items: center; flex: 1 1 auto; } .Flex-item span { background: red; } .Flex-item:not(:last-child):after { content: ""; border: 1px solid white; height: 40px; margin: auto; } .Flex-item:last-child { flex: 0; } 
 <div class="Container"> <ul class="Flex"> <li class="Flex-item"> <span>Lorem</span> </li> <li class="Flex-item"> <span>consectetur</span> </li> <li class="Flex-item"> <span>vestibulum</span> </li> <li class="Flex-item"> <span>nec</span> </li> <li class="Flex-item"> <span>condimentum</span> </li> </ul> </div> 
+4
source share

Instead :after try using the set <li class="separator"></li>

 .Container { max-width: 70%; margin: 0 auto; background: blue; } .Flex { display: flex; justify-content: space-between; list-style: none; padding: 20px 0; margin:0; } .Flex-item { background: red; } .separator { background: white; width: 1px; } 
 <div class="Container"> <ul class="Flex"> <li class="Flex-item">Lorem</li> <li class="separator" aria-hidden="true" role="presentation"></li> <li class="Flex-item">consectetur</li> <li class="separator" aria-hidden="true" role="presentation"></li> <li class="Flex-item">vestibulum</li> <li class="separator" aria-hidden="true" role="presentation"></li> <li class="Flex-item">nec</li> <li class="separator" aria-hidden="true" role="presentation"></li> <li class="Flex-item">condimentum</li> </ul> </div> 

PS: yes, I first tried using display: list-item on the alias :after , but naah.

+2
source share

I think the only way to accomplish this with flexbox is to wrap the text in a new element, as @Kukkuz made another answer .

Without this extra shell, you can still get equal spaced separators, but the red background is not limited by the length of the text.

The following is an example:

  • No changes to HTML.
  • No need for pseudo-elements.
  • There is no need for absolute positioning.

If the background color for the text is not needed, delete it, and that should be all you need.

 .Flex { display: flex; list-style: none; margin: 0; padding: 0; } .Flex-item { flex: 1 1 auto; background: red; } .Flex-item { text-align: center; } .Flex-item:first-child { text-align: left; } .Flex-item:last-child { text-align: right; } .Flex-item + .Flex-item { border-left: 1px solid white; } .Container { max-width: 70%; margin-right: auto; margin-left: auto; background: blue; padding-top: 20px; padding-bottom: 20px; } 
 <div class="Container"> <ul class="Flex"> <li class="Flex-item">Lorem</li> <li class="Flex-item">consectetur</li> <li class="Flex-item">vestibulum</li> <li class="Flex-item">nec</li> <li class="Flex-item">condimentum</li> </ul> </div> 

If you can add a span around the text, which allows you to limit the red background to the length of the text, then you will all set:

 .Flex { display: flex; list-style: none; margin: 0; padding: 0; } .Flex-item { flex: 1 1 auto; display: inline-flex; justify-content: center; } .Flex-item span { background-color: red; } .Flex-item:first-child span { margin-right: auto; } .Flex-item:last-child span { margin-left: auto; } .Flex-item + .Flex-item { border-left: 1px solid white; } .Container { max-width: 70%; margin-right: auto; margin-left: auto; background: blue; padding-top: 20px; padding-bottom: 20px; } 
 <div class="Container"> <ul class="Flex"> <li class="Flex-item"><span>Lorem</span></li> <li class="Flex-item"><span>consectetur</span></li> <li class="Flex-item"><span>vestibulum</span></li> <li class="Flex-item"><span>nec</span></li> <li class="Flex-item"><span>condimentum</span></li> </ul> </div> 
+1
source share

try it

 html { box-sizing: border-box; } .Container { max-width: 90%; margin-right: auto; margin-left: auto; background: blue; padding-top: 11px; padding-bottom: 50px; } .Flex { list-style: none; margin: 0; padding: 0; position: relative; left: 50%; transform: translateX(-50%); float: left; } .Flex-item { position: relative; float: left; padding: 5px 10px; border-right:1px solid #fff; } .Flex-item:last-child{border-right:none;} .Flex-item >div{ margin:0 5px; background:red; padding:5px; } 
 <div class="Container"> <ul class="Flex"> <li class="Flex-item"><div> Lorem </div></li> <li class="Flex-item"><div> consectetur </div></li> <li class="Flex-item"><div> vestibulum </div></li> <li class="Flex-item"><div> nec </div></li> <li class="Flex-item"><div> condimentum </div></li> </ul> </div> 
0
source share

if you create flex , you can get something closed by what you are trying to do, without additional markup.

It includes aliases, order selectors and css3 (on the flex side).

http://codepen.io/gc-nomade/pen/BpzYWP

 body { margin:0; } .Flex, .Flex-item { display:flex; padding:0.5em 0; margin:0; } .Flex-item { flex:1;/*spray them evenly*/ } .Flex-item:before, .Flex-item:after {/* add pseudos to fill extra space */ content:''; flex:1;/* thats where it takes room not use by the text */ margin:-1em 0;/* grow them taller */ border-right:solid 1px white; } .Flex-item:first-child:before { order:2;/* put both pseudo after text*/ flex:.5;/* shrink that one can be .75 to .25 */ border:none; /* remove the border useless for the show */ } .Flex-item:last-child:after { order:-1;/* put both pseudos before text */ flex:0.5;/* shrink that one can be .75 to .25 */ } .Flex-item:first-child + .Flex-item:before , .Flex-item:nth-last-child(1):after{ border:none; /* remove the border useless for the show */ } body, :after, :before { background:tomato;/* pseudo will hide li background */ } li { background:turquoise; } /* give some space around the text */ .Flex-item:first-child { padding-left:1em; } .Flex-item:last-child { padding-right:1em; } .Flex-item:before { border:none;/* we do not need those after all */ margin-right:1em; } .Flex-item:after { margin-left:1em; } .Flex-item:first-child:before { margin:-1em 0; }.Flex-item:last-child:after { margin:-1em 0; } 
 <div class="Container"> <ul class="Flex"> <li class="Flex-item">Lorem</li> <li class="Flex-item">consectetur</li> <li class="Flex-item">vestibulum</li> <li class="Flex-item">nec</li> <li class="Flex-item">condimentum</li> </ul> </div> 
0
source share

All Articles