2

Open this page in Chrome and in Safari and we can see the difference.

In Safari the "Maths" keyword is not on the right side as in Chrome.

Also the widths of the item-3 div is different in Chrome and in Safari.

My issue is that why it is different in Safari and what is the fix (I want CSS fix on the item-3).

flex-wrap: wrap is not a acceptable solution.

.main-container {
  display: flex;
  flex-direction: column;
  width: 400px;
  height: 300px;
  border: 1px solid red;
}

.item-1 {
  display: flex;
  border: 1px solid blue;
}

.item-2 {
  display: flex;
  border: 1px solid green;
}

.item-3 {
  display: flex;
  margin-left: auto!important;
  border: 2px solid yellow;
}
<div class="main-container">
  <div class="item-1">Physics</div>
  <div class="item-2">Chemistry</div>
  <div class="item-3">Maths</div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Vishal Patil
  • 381
  • 3
  • 15

1 Answers1

1

The width of .item-3 is different than its siblings because margin-left: auto packs the flex item to the right side. That's normal behavior for flex auto margins.

The reason margin-left doesn't work in Safari is a mystery / bug.

However, for cross-browser support, there is a simple flex alternative to auto margins in this case: align-self: flex-end

.main-container {
  display: flex;
  flex-direction: column;
  width: 400px;
  height: 300px;
  border: 1px solid red;
}

.item-1 {
  display: flex;
  border: 1px solid blue;
}

.item-2 {
  display: flex;
  border: 1px solid green;
}

.item-3 {
  display: flex;
  align-self: flex-end;  /* NEW */
  border: 2px solid yellow;
}
<div class="main-container">
  <div class="item-1">Physics</div>
  <div class="item-2">Chemistry</div>
  <div class="item-3"><span>Maths</span></div>
</div>

If you want .item-3 to keep the full width of the container, then use justify-content: flex-end.

.main-container {
  display: flex;
  flex-direction: column;
  width: 400px;
  height: 300px;
  border: 1px solid red;
}

.item-1 {
  display: flex;
  border: 1px solid blue;
}

.item-2 {
  display: flex;
  border: 1px solid green;
}

.item-3 {
  display: flex;
  justify-content: flex-end;  /* NEW */
  border: 2px solid yellow;
}
<div class="main-container">
  <div class="item-1">Physics</div>
  <div class="item-2">Chemistry</div>
  <div class="item-3">Maths</div>
</div>

How align-self: flex-end works

With align-self: flex-end you're shifting .item-3 along the cross axis all the way to the right.

This works because the flex container (.main-container) has flex-direction: column, which makes the main axis vertical and cross axis horizontal.


How justify-content: flex-end works

With justify-content: flex-end you're shifting the children of .item-3 along the main axis all the way to the right.

This works because .item-3 is a flex container with flex-direction: row (by default), which makes the main axis horizontal and cross axis vertical.

Then, as per the specification, text in a flex container that is not explicitly wrapped by an element, is considered an anonymous flex item. This allows justify-content to work.

4. Flex Items

Each in-flow child of a flex container becomes a flex item, and each contiguous run of text that is directly contained inside a flex container is wrapped in an anonymous flex item.


Why text-align: right doesn't work

text-align: right won't work because flex items (including anonymous ones) are considered block-level elements. The text-align property applies only to inline-level content.


More information

Learn more about flex alignment along the main axis here:

Learn more about flex alignment along the cross axis here:

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701