0

I have four buttons (a-elements) that should take up the entire available horizontal space of a div with some margin space in between. The four buttons should all have equal width (their contents may flow). I currently do this as follows:

css:

div {
    text-align: justify;
}
div::after {
    content: "";
    display: inline-block;
    width: 100%;
}
a {
    display: inline-block;
    text-align: left;
    width: 20%;       /* not precisely 20% and 4%, that's just for */
    margin-right: 4%; /* the sake of the question                  */
    min-width: 10em;
}

html:

<div>
    <a href="/">btn 1</a>
    <a href="/">btn 2</a>
    <a href="/">btn 3</a>
    <a href="/">btn 4</a>
</div>

When the page gets narrower, the buttons shrink until they are 10em wide. Then they break the row, leaving three buttons on row 1 and one button on row 2.

However, the buttons are now still at 10em. I would like them to grow to a little less (to allow for margins) than 33%. If the page gets even narrower, and the buttons shrink again down to 10em, the row should break again, leaving two buttons on row 1 and two buttons on row 2. These buttons should take up a little less than 50%.

And finally, if the outer div shrinks to less than 20em, four rows are expected with buttons of 100% wide (the outer div may have a minimum width of 10em here, that's fine).

To get an ASCII-art impression (I'm no artist):

initial "full" page width

+-----------------------------------+
|[ab    ] [cdef  ] [ghi   ] [jk lm ]|
|[      ] [      ] [      ] [      ]|

page shrinks

+-------------------------------+---+
|[ab   ] [cdef ] [ghi  ] [jk lm]|
|[     ] [     ] [     ] [     ]|

page shrinks further, last btn flows its content

+---------------------------+-------+
|[ab  ] [cdef] [ghi ] [jk  ]|
|[    ] [    ] [    ] [lm  ]|

shrinking even further, too narrow for four btn's row 1 has 3 btn's, full width, row 2 has 1 btn, equal width

+-----------------------+-----------+
|[ab   ] [cdef ] [ghi  ]|
|[     ] [     ] [     ]|

|[jk lm]                |
|[     ]                |

shrinking even further, all four btn's shrink

+--------------------+--------------+
|[ab  ] [cdef] [ghi ]|
|[    ] [    ] [    ]|

|[jk  ]              |
|[lm  ]              |

shrinking even further, too narrow for three btn's

+-----------------+-----------------+
|[ab    ] [cdef  ]|
|[      ] [      ]|

|[ghi   ] [jk lm ]|
|[      ] [      ]|

shrinking further

+-------------+---------------------+
|[ab  ] [cdef]|
|[    ] [    ]|

|[ghi ] [jk  ]|
|[    ] [lm  ]|

shrinking further, too narrow for two btn's

+---------+-------------------------+
|[ab     ]|
|[       ]|

|[cdef   ]|
|[       ]|

|[ghi    ]|
|[       ]|

|[jk lm  ]|
|[       ]|

Thus, actual result:

+-----------------+-----------------+
|[ab  ]   [cdef]  |
|[    ]   [    ]  |

|[ghi ]   [jk  ]  |
|[    ]   [lm  ]  |

Intended result:

(optimal width of buttons)

+-----------------+-----------------+
|[ab    ] [cdef  ]|
|[      ] [      ]|

|[ghi   ] [jk lm ]|
|[      ] [      ]|

Tried

I have tried to use flexbox. However, I still do not feel confortable using it because of older browsers (and with such a big break, much usability is at stake) and moreover, I could not get further than having the last button take up the entire space (and thus becoming 3x bigger than the other buttons). Such as:

+-----------------------+-----------+
|[ab   ] [cdef ] [ghi  ]|
|[     ] [     ] [     ]|

|[jk lm                ]|  <-- this btn is as wide as _three_ other buttons
|[                     ]|

I have also tried display: table. However, this does not account for the "equal width" requirement and the cells do not break if the page is too narrow, instead the 100% width table grows beyond its container.

How is this solvable?

I am looking for a solution WITHOUT javascript.

Asons
  • 84,923
  • 12
  • 110
  • 165
Marten Koetsier
  • 3,389
  • 2
  • 25
  • 36
  • 1
    There is no solution...that's not the way the line-box model works. – Paulie_D Jun 21 '17 at 15:19
  • Probable duplicate - https://stackoverflow.com/questions/34995740/css-when-inline-block-elements-line-break-parent-wrapper-does-not-fit-new-width – Paulie_D Jun 21 '17 at 15:21
  • I do not agree on the dupe-suggestion. They have a 'button' on a fixed width and need the container to wrap, I need a maximum-width container with maximum (flexible) width content (not necessarily inline). But you seem to be right on the "there is no solution"-part. – Marten Koetsier Jun 21 '17 at 18:42
  • Reading through your ASCII artwork, I can't see how my answer doesn't solve each state. Could you let me know what you see doesn't do according to the same? – Asons Jun 22 '17 at 15:14
  • @LGSon I'm still hesitant to accept the answer because of browser compatibility. As mentioned, rekonq 2.4.2. is still a browser under current OS support. But also IE11 does not get this (tested this just now): the buttons do not extend beyond their min-size. Even one miss for one customer (God knows, they might be on WinXP) is not acceptable. I do like the idea (hence the +1). – Marten Koetsier Jun 22 '17 at 19:57
  • That's perfectly fine. This is as good as it gets, today, and without script, and the browser compatibility will catch up eventually :) ... and when they do, you have your answer – Asons Jun 22 '17 at 20:02

1 Answers1

1

With Flexbox you can mimic that behavior.

The main trick here is the 2 pseudo elements that acts as ghost's and make the 4th button continue to shrink even after it wrapped into a second line, so all buttons have same width all the time.

Fiddle demo

Stack snippet

div {
  display: flex;
  flex-wrap: wrap;
}

a {
  flex: 1 0 calc(25% - 16px);
  margin: 2px 8px;
  text-align: left;
  min-width: 6em;
  padding: 10px;
  border: 1px solid black;
  box-sizing: border-box;
}

div::after, div::before {
  content: '';
  flex: 1 0 calc(25% - 16px);
  margin: 0 8px;
  min-width: 6em;
  padding: 10px 10px;
  border: 1px solid transparent;
  box-sizing: border-box;
  order: 1;
}
<div>
  <a href="/">btn 1</a>
  <a href="/">btn 2 long</a>
  <a href="/">btn 3 long</a>
  <a href="/">btn 4</a>
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
  • This looks good in Chromium (v58), but not in Firefox (v54): the wrapping button spans the full width, and not in rekonq (v2.4.2, don't know the webkit version): the buttons are not of equal width and wrapping is "in text", the borders overlap, and wrapping is even inside one button. This makes me not less afraid of using flexbox :( – Marten Koetsier Jun 21 '17 at 18:10
  • @MartenKoetsier Sorry...made mistake with my fiddle, was not same a stack snippet, try this one: https://jsfiddle.net/aykx377u/2/ ...tested with success in Chrome, FF, IE, Edge – Asons Jun 21 '17 at 18:14
  • @MartenKoetsier Regarding Rekonq 2.4.2, it was released in 2014, and one can't expect those older one's to keep up. Also, to do this without script you need Flexbox. Maybe a fallback to script for those older can be an option – Asons Jun 21 '17 at 18:18
  • I see the omission in the Fiddle. This is indeed much better, +1. Do you happen to know anything about support in Safari? I have users on AppleWebkit v602. And I found out rekonq 2.4.2 is at Webkit v537. Btw 2014 is still a supported version of my OS with latest updates on rekonq, thus not that old; it's not IE8... – Marten Koetsier Jun 21 '17 at 18:36
  • @MartenKoetsier Took an extra look if I could spot any Safari issue in this code snippet but no, so this will work in Safari as well. – Asons Jun 21 '17 at 18:42