4

I would like to make a row consisting of three columns, where the left column is always on the left, and the right two columns are joined together (i.e. wrap together to the next line, if there is not enough space). This is easily achievable using flex and may look like this: https://jsfiddle.net/znxn9x1r/

When there is enough space When there is not enough space

The catch here is that I would also like the middle column (violet colored always-right/left) to be shrinkable up to some min-width using text-overflow: ellipsis. This means that when I start lowering the width of the page, the middle column should first start shrinking, and only after it is no longer possible, then the right two columns should wrap to the next line.

A mockup of what I want to achieve:

Ellipsis in the middle column

Then when the shrinking reaches the min-width of the middle column, it should wrap to the next line as before:

Min-width reached

Now if there was no left yellow column and the whole row consisted only from the two right columns, I could use the answer from the following question: How to keep a flex item from overflowing due to its text?

This really behaves like it should, but only after the right group already wraps:

Correct ellipsis on second line

It does not shrink the middle column when it is still on the same line as the first yellow column:

This should not happen

^^ This should not happen, there is enough space for an ellipsis!

Here is my code, is it possible to achieve what I want with pure HTML/CSS?

* {
  padding: 5px;
}
#container {
  background-color: lightgreen;
  display: flex;
  flex-wrap: wrap;
}
#always-left {
  background-color: yellow;
  margin: auto;
  margin-left: 0;
}
#right-group {
  margin: auto;
  margin-right: 0;
  display: flex;
}
#shrinkable {
  background-color: violet;
  vertical-align: middle;
  order: 1;
  flex: 0 1 auto;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}
#not-shrinkable {
  background-color: lightblue;
  vertical-align: middle;
  order: 2;
  flex: 1 0 auto;
}
<div id="container">
  <div id="always-left">
    always-left
  </div>
  <div id="right-group">
    <div id="shrinkable">
      always-right / left
    </div>
    <div id="not-shrinkable">
      always-right / right
    </div>
  </div>
</div>

https://jsfiddle.net/mnmyw245/

Community
  • 1
  • 1
TomsonTom
  • 742
  • 7
  • 22

1 Answers1

1

One method that may work for you involves disabling flex-wrap: wrap on the flex container.

#container {
  background-color: lightgreen;
  display: flex;
  /* flex-wrap: wrap;        <-- REMOVE THIS */
}

This forces everything to stay on the same line.

Then, when you feel it's okay for wrapping to begin, restore wrap with a media query.

This takes wrap control away from the browser and puts it in your hands.

Here's an example:

@media ( max-width: 200px ) {
  #container { flex-wrap: wrap; }
}

revised fiddle

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    This is certainly a method that works, but requires manually setting up the breakpoint, so this method is not dynamic with relation to content. However if no one comes up with a better solution, it may mean that there is not any CSS solution available and I will accept your answer. :) – TomsonTom Nov 20 '16 at 14:52