-1

i have a horizontal bar made from flexbox.

If there are 2 or more items, I want each items separated as far as possible, so I set justify-content: space-between.

But if there is only 1 item, I want the item placed at the end, so I set justify-content: flex-end.

The items are ordered from left to right. So setting flex-direction: row-reverse wouldn't work.

How I combine the first, second & third terms? The items are dynamically added/removed.

Heyyy Marco
  • 633
  • 1
  • 12
  • 22
  • 1
    You can use JS to dynamically add your styles based on the no. of items – Anand Apr 09 '21 at 17:45
  • You can't really do this with `flexbox`. If you are dynamically generating the content, you could add a class to the wrapping element to denote a single element and use `justify-content: flex-end`. https://stackoverflow.com/questions/49658425/flexbox-justify-self-flex-end-not-working – disinfor Apr 09 '21 at 17:50

4 Answers4

2

Leverage :only-child

.wrap {
  display: flex;
  margin-bottom: 1em;
  justify-content: space-between;
  width: 50%;
  border: 1px solid grey;
  padding: .25em;
}

.item {
  border: 1px solid red;
  padding: 1em;
  background: pink;
}

.item:only-child {
  margin-left: auto;
}
<div class="wrap">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

<div class="wrap">
  <div class="item"></div>
  <div class="item"></div>
</div>

<div class="wrap">
  <div class="item"></div>
</div>
Paulie_D
  • 107,962
  • 13
  • 142
  • 161
0

You can do this using the + which selects the next sibling. This method uses justify-content: flex-end

.flex {
  display: flex;
  justify-content: flex-end;
  background: grey;
}

.item+.item {
  margin-left: auto;
}

.item {
  width: 10px;
  height: 10px;
  background: red;
}
<div class="flex">
  <div class="item"></div>
  <div class="item"></div>
</div>

<br/><br/><br/>

<div class="flex">

  <div class="item"></div>
</div>

<br/><br/><br/>

<div class="flex">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

OR

You can also target the first child with :first-child:last-child which allows you to set this up a different way. This method uses justify-content: space-between

.flex {
  display: flex;
  justify-content: space-between;
  background: grey;
}

.item {
  width: 10px;
  height: 10px;
  background: red;
}

.item:first-child:last-child {
  margin-left: auto;
}
<div class="flex">
  <div class="item"></div>
  <div class="item"></div>
</div>

<br/><br/><br/>

<div class="flex">

  <div class="item"></div>
</div>

<br/><br/><br/>

<div class="flex">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
Huangism
  • 16,278
  • 7
  • 48
  • 74
0

thanks to @Paulie_D

The idea is using combination margin-left (or margin-inline-start) and :first-child:last-child (the only child).

I was spent a hours for solving this problem without success. Now works!

enter image description here

Heyyy Marco
  • 633
  • 1
  • 12
  • 22
-1

Maybe use justify-self: flex-end; on the first item

.items {
    justify-content: space-between;
    .item:first-of-type {
        justify-self: flex-end;
    }
}
Zach
  • 36
  • 8