404

https://jsfiddle.net/vhem8scs/

Is it possible to have two items align left and one item align right with flexbox? The link shows it more clearly. The last example is what I want to achieve.

In flexbox I have one block of code. With float I have four blocks of code. That is one reason why I prefer flexbox.

HTML

<div class="wrap">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>

<!-- DESIRED RESULT -->

<div class="result">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>

CSS

.wrap {
  display: flex;
  background: #ccc;
  width: 100%;
  justify-content: space-between;
}

.result {
  background: #ccc;
  margin-top: 20px;
}

.result:after {
  content: '';
  display: table;
  clear: both;
}

.result div {
  float: left;
}
.result div:last-child {
  float: right;
}
isherwood
  • 58,414
  • 16
  • 114
  • 157
Jens Törnell
  • 23,180
  • 45
  • 124
  • 206

5 Answers5

908

To align one flex child to the right set it withmargin-left: auto;

From the flex spec:

One use of auto margins in the main axis is to separate flex items into distinct "groups". The following example shows how to use this to reproduce a common UI pattern - a single bar of actions with some aligned on the left and others aligned on the right.

.wrap div:last-child {
  margin-left: auto;
}

Updated fiddle

.wrap {
  display: flex;
  background: #ccc;
  width: 100%;
  justify-content: space-between;
}
.wrap div:last-child {
  margin-left: auto;
}
.result {
  background: #ccc;
  margin-top: 20px;
}
.result:after {
  content: '';
  display: table;
  clear: both;
}
.result div {
  float: left;
}
.result div:last-child {
  float: right;
}
<div class="wrap">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>

<!-- DESIRED RESULT -->
<div class="result">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>

Note:

You could achieve a similar effect by setting flex-grow:1 on the middle flex item (or shorthand flex:1) which would push the last item all the way to the right. (Demo)

The obvious difference however is that the middle item becomes bigger than it may need to be. Add a border to the flex items to see the difference.

Demo

.wrap {
  display: flex;
  background: #ccc;
  width: 100%;
  justify-content: space-between;
}
.wrap div {
  border: 3px solid tomato;
}
.margin div:last-child {
  margin-left: auto;
}
.grow div:nth-child(2) {
  flex: 1;
}
.result {
  background: #ccc;
  margin-top: 20px;
}
.result:after {
  content: '';
  display: table;
  clear: both;
}
.result div {
  float: left;
}
.result div:last-child {
  float: right;
}
<div class="wrap margin">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>

<div class="wrap grow">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>

<!-- DESIRED RESULT -->
<div class="result">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>
Danield
  • 121,619
  • 37
  • 226
  • 255
  • Thanks! I tried another thing that worked before I read this. It was to set flex-grow: 1 on the element that should push the other. It worked as well. Do you know which of them are better and why? – Jens Törnell Feb 08 '16 at 15:09
  • 6
    @JensTörnell, the `auto` margin uses the empty space in the container to separate the flex items. The `flex-grow`/`flex` property takes that empty space, gives it to the flex item, which expands by that amount. As mentioned by Danield, the latter method makes flex item TWO bigger, which you may not want. – Michael Benjamin Feb 08 '16 at 20:12
  • 1
    Any way to align more that one item to the right (or left)? – user1063287 Jun 06 '18 at 07:46
  • 2
    @user1063287 to align multiple elements to the right just apply margin-left: auto on the first element which need to be aligned right. So let's say you want the last 4 elements aligned to the right, you'd do this: `div:nth-last-child(4) { margin-left: auto }` https://codepen.io/danield770/pen/ERyoar – Danield Jun 06 '18 at 07:53
75

For a terse, pure flexbox option, group the left-aligned items and the right-aligned items:

<div class="wrap">
  <div>
    <span>One</span>
    <span>Two</span>
  </div>
  <div>Three</div>
</div>

and use space-between:

.wrap {
  display: flex;
  background: #ccc;
  justify-content: space-between;
}

This way you can group multiple items to the right(or just one).

https://jsfiddle.net/c9mkewwv/3/

spflow
  • 1,010
  • 7
  • 12
  • 1
    This works, but if you don't change the elements inside each group to be `display: inline;` or `display: inline-block;`, then they get stacked instead of all in a row like flexbox otherwise would have them. – The DIMM Reaper Sep 21 '17 at 18:46
  • @TheDIMMReaper I'm not sure I see the problem. Could you expand? – spflow Sep 26 '17 at 17:57
  • I just mean how you changed the tags immediately wrapping `One` and `Two` from `div`s to `span`s - if they were still `display: block;` then they would flow to separate lines. Since the OP originally had `div`s, I just wanted to point out that simply putting them inside another `div` wouldn't work without changing the display of the original tags. – The DIMM Reaper Sep 26 '17 at 18:15
  • 1
    Yes, since the elements are now down a level, `display: flex` is no longer influencing their layout. If you want to use div's, yes, `inline` or `inline-block` would work. But also, obviously, `flex`, since we're using it for the default `flex-direction: row` with parent div's already. ex. https://jsfiddle.net/ynbb5964/2/ – spflow Sep 28 '17 at 04:16
  • Thanks, I tried align-self: flex-end, but why it doesn't work? – Anand Mar 14 '18 at 05:35
  • Oh ok, just found that align-self only works on cross-axis. – Anand Mar 14 '18 at 05:44
9

To align some elements (headerElement) in the center and the last element to the right (headerEnd).

.headerElement {
    margin-right: 5%;
    margin-left: 5%;
}
.headerEnd{
    margin-left: auto;
}
Satvik Vats
  • 91
  • 1
  • 2
6

You can do either

margin-left: auto;

or

position absolute;
right: 0px;

This will move the item to the right side. The px value you give will push the item from the right to the left.

sifferman
  • 2,955
  • 2
  • 27
  • 37
raoul baddawi
  • 77
  • 1
  • 1
  • 2
    hello @raoul. thanks for answering, but the question is about flexbox. Please read the title of a question more carefully. – Manticore Dec 08 '22 at 09:33
-3

Here is what I did (with tailwind but it's just CSS):

<nav class="border-b border-black flex">
  <div class="border border-red-600 w-12">Back</div>
  <div class="border border-blue-600 w-12">Logo</div>
  <div class="border border-green-600 flex-grow text-center">Socializus</div>
  <div class="border border-orange-600 w-24">
    <div class="w-12 ml-auto border border-pink-600">Menu</div>
  </div>
</nav>

The idea is that the two parts on left and right are the same width, then a subpart of the right takes less space

menu centered

Dorian
  • 7,749
  • 4
  • 38
  • 57