15

Here's the scenario:

<!DOCTYPE html>
<html>
<head>
<style>
.flex-container {
    display: flex;
    border: 1px solid black;
}

.flex-item {
    background-color: cornflowerblue;
    height: 1.7rem;
    padding: 0 1.2rem;
    flex: 1 1 33.33333%;
    white-space: nowrap;
    max-width: 33.33333%;
}
</style>
</head>
<body>
  <div class="flex-container">
    <div class="flex-container">
      <button class="flex-item">Foo</button>
      <button class="flex-item">Bar</button>
      <button class="flex-item">Long ass text here</button>
    </div>
  </div>
</body>
</html>

The buttons are the same size but the problem is that they don't scale in size according to the flex item with longest content. Instead, the text of the last button here overflows. This is how it looks like:

enter image description here

And this is how I want it to look like:

enter image description here

So in short, I want 3 flex buttons with same width and height where the width should be determined according to button with the longest content. Also, I'd rather do this with CSS only (if it's possible).

EDIT: Because there seems to be some misunderstandings, I would like to clarify that the width should change dynamically and thus work with any texts given for the buttons, not just with the ones shown above. In other words, you can't just add e.g. width: 10rem for flex-item directly because it only works in specific situation.

JZ555
  • 617
  • 2
  • 7
  • 16
  • 1
    if it is about 3 elements, then display:grid might do it on second level inbrication : http://codepen.io/gc-nomade/pen/EWNoLa Still experimental, you need to set experimental CSS flag on in Firefox and chrome in order to test it . It is not yet usable for regular website :( https://css-tricks.com/snippets/css/complete-guide-grid/ `. .` :-: flex or table display are failing without a width specified on parent or child – G-Cyrillus Mar 07 '17 at 21:45
  • Does this answer your question? [Every item to have the same width as the widest element](https://stackoverflow.com/questions/31159732/every-item-to-have-the-same-width-as-the-widest-element) – leonheess Aug 16 '21 at 18:51
  • As the accepted answer is an obsolete Grid solution, I closed and re-directed to a modern Grid solution. – Michael Benjamin Jul 03 '22 at 15:22

3 Answers3

10

flex fails here for this kind of behavior :

Display:grid could do in the futur here.

Your question mention 3 elements:

A tutorial https://css-tricks.com/snippets/css/complete-guide-grid/

browser supports http://caniuse.com/#search=grid

a Polyfill https://github.com/FremyCompany/css-grid-polyfill/

http://gridbyexample.com/browsers/

.flex-container {
  display: flex;
  border: 1px solid black;
  margin: 1em;
}

.flex-container .flex-container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

.flex-item {
  background-color: cornflowerblue;
  height: 1.7rem;
  padding: 0 1.2rem;
  width: 100%;
  white-space: nowrap;
}

@supports (display: grid) {
  .discl {
    display: none
  }
}
<p class="discl"> grid CSS seems not supported by your browser</p>
<div class="flex-container">
  <div class="flex-container">
    <button class="flex-item">Foo</button>
    <button class="flex-item">Bar</button>
    <button class="flex-item">Long ass text here</button>
  </div>
</div>
<div class="flex-container">
  <div class="flex-container">
    <button class="flex-item">Foo</button>
    <button class="flex-item">Bar</button>
    <button class="flex-item">Long text & Long text here</button>
  </div>
</div>

Also, from a known amount of elements, column CSS might be usefull here

.flex-container {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  border: 1px solid black;
  margin:1em;
}

.flex-container .flex-container {
  display:block;
  -moz-column-count:3;
  -moz-column-gap:0;
  -webkit-column-count:3;
          column-count:3;
  -webkit-column-gap:0;
          column-gap:0;
}

.flex-item {
  background-color: cornflowerblue;
  height: 1.7rem;
  padding: 0 1.2rem;
  width: 100%;
  white-space: nowrap;
}
<div class="flex-container">
    <div class="flex-container">
      <button class="flex-item">Foo</button>
      <button class="flex-item">Bar</button>
      <button class="flex-item">Long ass text here</button>
    </div>
  </div>
  <div class="flex-container">
    <div class="flex-container">
      <button class="flex-item">Foo</button>
      <button class="flex-item">Bar</button>
      <button class="flex-item">Long ass text here Long ass text here</button>
    </div>
  </div>

In both cases , display flex is only usefull to shrink second container to its content.in a block parent, float or display:inline-block at that level would do too.

Community
  • 1
  • 1
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
  • Thanks for the answer. As it seems that you cannot use flex to achieve this I decided to just specify a width for the container. The grid would be great if it was usable. I'd rather not use the column tho because it makes the buttons way too wide. However, I will accept this as the answer because it covers the options I have at this point. – JZ555 Mar 11 '17 at 10:50
  • 1
    Awesome! CSS Grids rock. As of August 2017 CSS Grids are supported on all modern browsers. – brubs Aug 31 '17 at 08:06
  • Is there a way to do this using only css for an arbitrary/dynamic number of elements? – shadowcursor Sep 27 '17 at 21:36
  • I also looking for a way to have this with any number of items / columns. It would be needed for a dynamic component. – SaroGFX Jun 08 '21 at 11:34
1

Please try this one and let me know if it works.

.flex-container {
    display:flex;
    align-items: stretch;
    border: 1px solid black;
}

.flex-item {
    background-color: cornflowerblue;
    height: 1.7rem;
    width: 10rem;
    padding: 0 1.2rem;
    flex: 1 1 33.33333%;
    white-space: nowrap;
    max-width: 50%;
    flex-grow: 1;
    flex-basis: 0;
}

<div class="flex-container">
<div class="flex-container">
  <button class="flex-item">Foo</button>
  <button class="flex-item">Bar</button>
  <button class="flex-item">Long ass text here</button>
</div>
</div>
Narayan Bhandari
  • 426
  • 3
  • 11
  • Sorry, but it needs to work with 2 flex-containers. Also, as you can see in the pictures, inner flex-container should not take the whole width of the outer flex-container, only as much as is needed. That's why I drew the borders there to demonstrate this. Also, you removed the white-space: nowrap which needs to be there because otherwise long text goes to multiple lines and I want it always on single line. – JZ555 Mar 07 '17 at 19:55
  • 2
    @JZ555 did you check the edit answer ? cause this meets your needs. – G-Cyrillus Mar 07 '17 at 20:33
  • @GCyrillys This has the same problem as JCD's solution. You set the width directly, and thus, if I make the last button text even longer, it stops working. The width of the buttons should change dynamically, so no matter how long the text is, it always works. – JZ555 Mar 07 '17 at 20:40
  • Sorry, if the question was badly formulated. Added clarification also to the original post. Please check that also. – JZ555 Mar 07 '17 at 20:59
0

I put the display on solid. Just give a fix width and it should look now like you want it.

<!DOCTYPE html>
<html>
<head>
<style>
.flex-container {
    display: solid;
    border: 1px solid black;
}

.flex-item {
    background-color: cornflowerblue;
    height: 1.7rem;
    width: 10rem;
    padding: 0 1.2rem;
    flex: 1 1 33.33333%;
    white-space: nowrap;
    max-width: 50%;
}
</style>
</head>
<body>
  <div class="flex-container">
    <div class="flex-container">
      <button class="flex-item">Foo</button>
      <button class="flex-item">Bar</button>
      <button class="flex-item">Long ass text here</button>
    </div>
  </div>
</body>
</html>
JCD
  • 155
  • 1
  • 15
  • This only allows you to change the size of your buttons like you asked for – JCD Mar 07 '17 at 19:54
  • The problem here is that you set the width as 10rem. It needs to be dynamic. Like I said: "width should be determined according to button with the longest content". In other words your solution doesn't work anymore if I make the text in the last button even longer. Also, display: solid gives us weird gaps between the buttons which I don't want. – JZ555 Mar 07 '17 at 20:02