0

Sorry for the really vague question title but I have no idea how to best describe it...

Take the following code example:

.wrapper {
  border: 2px solid green;
}

.container { 
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  
  border: 2px solid red;
  margin: 5px;
  height: 64px;
}

.item {
  display: flex;

  border: 2px solid #0000ff;
  padding: 3px;
}

.left {
  justify-content: flex-end;
}

.right {
  justify-content: flex-start;
}
<div class="wrapper" style="width: 100%">
  <div class="container">
    <div class="item left">FIXED</div>
    <div class="item right">abc</div>
  </div>
  <div class="container">
    <div class="item">FIXED</div>
  </div>
  <div class="container">
    <div class="item left">FIXED</div>
    <div class="item right">abcdefgh</div>
  </div>
</div>
<br />
<div class="wrapper" style="width: 50%">
  <div class="container">
    <div class="item left">FIXED</div>
    <div class="item right">abc</div>
  </div>
  <div class="container">
    <div class="item">FIXED</div>
  </div>
  <div class="container">
    <div class="item left">FIXED</div>
    <div class="item right">abcdefgh</div>
  </div>
</div>

Observations:

  • FIXED represents an element of fixed size, always same width/height.
  • The right side element can vary on size (mostly width).
  • The right side element is always aligned to the left.
  • The left side element is always aligned to the left.

What I'm trying to achieve:

  • The FIXED element should always be centered on the red row.
  • THE FIXED element on the first/third rows needs to be aligned to the right side of the FIXED element on the second row.

Here's an image to better demonstrate what I'm looking for: enter image description here

EDIT: My final solution based on the @vals answer. I had to change this a bit because I'm using CSS Modules with selector composition in a React app and I need a single class per element.

.container {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  
  /* UNREQUIRED (FOR DEMONSTRATION ONLY) */
  border: 2px solid red;
  padding: 5px;
}

.container::before {
  content: "";
  flex: 1 0 14px; /* UNREQUIRED (FOR DEMONSTRATION ONLY) (14px -> 0) */
}

.container-single {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  
  /* UNREQUIRED (FOR DEMONSTRATION ONLY) */
  border: 2px solid red;
  padding: 5px;
}

.item {
  display: flex;
  flex: 0 0 auto;
  
  /* UNREQUIRED (FOR DEMONSTRATION ONLY) */
  border: 2px solid #0000ff;
  padding: 5px;
}

.item-right {
  display: flex;
  flex: 1 0 0;
  
  /* UNREQUIRED (FOR DEMONSTRATION ONLY) */
  border: 2px solid #0000ff;
  padding: 5px;
}

.item-left {
  display: flex;
  flex: 0 0 auto;
  margin-left: auto;
  
  /* UNREQUIRED (FOR DEMONSTRATION ONLY) */
  border: 2px solid #0000ff;
  padding: 5px;
}
<div class="container">
  <div class="item-left">FIXED</div>
  <div class="item-right">abc</div>
</div>
<br />
<div class="container-single">
  <div class="item">FIXED</div>
</div>
<br />
<div class="container">
  <div class="item-left">FIXED</div>
  <div class="item-right">abcdefgh</div>
</div>

For anyone interested, the CSS selector composition goes like this:

.container {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
}

.container::before {
    flex: 1 0 0;
    content: "";
}

.container-single {
    composes: container;
}

.item {
    display: flex;
    flex: 0 0 auto;
}

.item-right {
    flex: 1 0 0;

    composes: item;
}

.item-left {
    margin-left: auto;

    composes: item;
}
rfgamaral
  • 16,546
  • 57
  • 163
  • 275
  • why do you have `flex: 1 0 0` on the `FIXED` one too? and why `justify-content: flex-end` on it? – kukkuz Jan 21 '17 at 00:38
  • @kukkuz If I take that `flex` out, the `FIXED` element on the second row won't be aligned to the center. `justify-content: flex-end` is only on the `.left` class, to align the element to the right. Please note that I barely know anything about flexbox. – rfgamaral Jan 21 '17 at 00:44
  • okay, so the element on the second row must match the width of the elements on the first and third rows? – kukkuz Jan 21 '17 at 00:51
  • @kukkuz No, it doesn't need to match that width as long as it's centered inside the red row. In other words, I need the `FIXED` elements to be centered on all red rows. The ones that have side text on the right side of the `FIXED` elements, should be right next to them (keeping `FIXED` always centered). – rfgamaral Jan 21 '17 at 00:56
  • See boxes #71 - 78 here: http://stackoverflow.com/a/33856609/3597276 – Michael Benjamin Jan 21 '17 at 03:10
  • Also see here: http://stackoverflow.com/q/38948102/3597276 – Michael Benjamin Jan 21 '17 at 03:11
  • Neither of those give me what I'm looking for... – rfgamaral Jan 21 '17 at 08:02

1 Answers1

1

I have changed the layout slighty, I have add a class on the single container.

Is it ok for the right element to grow ?

.container {
  display: flex;
  flex-direction: row;
  border: 2px solid red;
  padding: 5px;
}
.item {
  display: flex;
  flex-basis: auto;
  flex-grow: 0;
  border: 2px solid #0000ff;
  padding: 5px;
}
.item.right {
  flex-basis: 0;
  flex-grow: 1;
}
.item.left {
  margin-left: auto;
}
.container:not(.single):before {
  content: "";
  flex-basis: 14px;  /* border 2px + padding 5px */
  flex-grow: 1;
}
.single .item {
  margin: 0px auto;
}
<div class="container">
  <div class="item left">FIXED</div>
  <div class="item right">abc</div>
</div>
<br />
<div class="container single">
  <div class="item">FIXED</div>
</div>
<br />
<div class="container">
  <div class="item left">FIXED</div>
  <div class="item right">abcdefgh</div>
</div>
vals
  • 61,425
  • 11
  • 89
  • 138
  • Sorry, it's a hard thing for me to explain with words... I've edited my example code and added an image to better demonstrate what I'm after. – rfgamaral Jan 21 '17 at 09:28
  • That works for me. CSS is definitely not my strong suite. However, I tweaked your code a bit because I'm using this on a React app with CSS Modules and selector composition, which requires me to have a single class per element. I've edited my question with my final solution. Thanks very much. – rfgamaral Jan 21 '17 at 10:38
  • Happy that it helped ! – vals Jan 21 '17 at 11:04