Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Respect width of multi-column text div alongside siblings in flexbox

Tags:

html

css

flexbox

I'm having trouble getting a text div to fit alongside a group of images in a flexbox row. These siblings currently only respect the column-width property of the text div as if it's a total width and overlap any width it has beyond this at various window sizes. The number of images and the length of the text is dynamic, as the content can change on page load. The layout is also responsive so I don't have the luxury of fixed dimensions in many cases. I believe I've reduced the problem to a working example with the following:

HTML:

<div id='maincontainer'>
  <div id='text'>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam quibus rebus efficiuntur voluptates, eae non sunt in potestate sapientis. In his igitur partibus duabus nihil erat, quod Zeno commutare gestiret. At cum de plurimis eadem dicit, tum certe
      de maximis. Pugnant Stoici cum Peripateticis. Qua tu etiam inprudens utebare non numquam. Duo Reges: constructio interrete.</p>

    <p>Beatus autem esse in maximarum rerum timore nemo potest. Quid est, quod ab ea absolvi et perfici debeat? Quarum ambarum rerum cum medicinam pollicetur, luxuriae licentiam pollicetur. Tubulum fuisse, qua illum, cuius is condemnatus est rogatione, P.
      Si id dicis, vicimus. Cur post Tarentum ad Archytam? Que Manilium, ab iisque M.</p>
  </div>
  <img class='img__gallery' src='https://placehold.it/200x300/a00/fff'>
  <img class='img__gallery' src='https://placehold.it/200x300/a00/fff'>
  <img class='img__gallery' src='https://placehold.it/200x300/a00/fff'>
  <img class='img__gallery' src='https://placehold.it/200x300/a00/fff'>
</div>

CSS:

#maincontainer {
    display: flex;
    position: absolute;
    min-height: 300px;
    max-height: 550px;
    height: 100%;
    width: 800px; // not in original. Used to force the issue to show.
}
#text {
    position: relative;
    display: block;
    padding-left: 20px;
    padding-right: 20px;
    column-width: 160px;
    height: 100%;
    column-gap: 20px;
    column-fill: auto;
}
.img__gallery {
  position: relative;
  display: block;
  margin-right: 20px;
}

Codepen: https://codepen.io/anon/pen/ModaEN

As intended, the text appears before the images. It creates however many columns of 160px it needs to fit the text content in. However, the images don't start after the text content, but overlap the div (you can barely make out the majority of the text div peaking out behind the images in the CodePen example). There's a solution to this also through javascript but it feels OTT. Surely a multi-column text div can make room for itself inside a flexbox without other items crowding over it?

In other words:

Is there a way for the flex items inside #maincontainer to respect and make room for the total width of #text (while #text respects its own column-width property at all window sizes)?

Currently, either the other flex items (the images) overlap and don't respect the total width of #text, or else #text shrinks its columns to sizes much smaller than column-width at smaller window sizes. Given that I've stated a column-width (160px) for #text, the next flex item should begin at 480px + padding, etc. to the right of the text if #text has 3 columns. 640px+padding if it has 4, etc.

If anybody is having trouble interpreting what I mean by respect, I'm inferring the action of making room for it. If an element's width ends at 200px, its next sibling should start at 200px+, etc. It's the behaviour most designers would be familiar with from relative positioning and/or floats. It's also the usual behaviour in flexboxes.


Update

Querying the element width of #text in javascript (well, jquery, using $("#textcontainer").width();) returns a value identical to my specified column-width value.

Javascript (and therefore, I guess, the browser) is seeing the total width of the #text element as the column-width value, which would make some sense of why the neighbouring flex items are overlapping #text up to the width of one column. I've confirmed this in both Chrome and Safari on the latest releases of both on macOS.

I've actually made a working solution using javascript but would still be eager to avoid using it. It just seems a bit ridiculous that this basic composition need is as convoluted to solve as this.

Update2

I'm not sure how this illustration better clarifies 'I need the sibling images to respect the total width of #text rather than overlapping it', but I'm including it incase it does, as requested. A is the required solution at all window sizes, B is what's happening:

enter image description here

like image 421
biscuitstack Avatar asked Jul 17 '17 19:07

biscuitstack


People also ask

How do I fix my flexbox width?

If you want to have a fixed-width column with Flexbox, you need to use the CSS flex or flex-basis property. First of all, we set the display of our <div> container to "flex". Then, we specify the flex of the "grey" class as "0 0 50px".

How do you show 3 items per row in flexbox?

For 3 items per row, add on the flex items: flex-basis: 33.333333% You can also use the flex 's shorthand like the following: flex: 0 0 33.333333% => which also means flex-basis: 33.333333% .

Which attribute has one the values as space evenly in the flexbox model?

The flex-grow property If we gave all of our items in the example above a flex-grow value of 1 then the available space in the flex container would be equally shared between our items and they would stretch to fill the container on the main axis. The flex-grow property can be used to distribute space in proportion.


1 Answers

AFAIK CSS columns and flexbox are basically incompatible with each other. A flex container takes no notice of column declarations. It would appear that giving an element columns effectively takes it out of the flex flow, hence why it allows the text to overlap with the other elements in the container.

I haven't read the specs for either to say in enough detail whether this behaviour is by design or not, it's just what I can observe. Sadly I think if you need the CSS columns in your div you will have go down the script route in order to correct it. I could be wrong but haven't seen a way round it as yet.

As IlyaStreltsyn pointed out, there's a also a bug with column-oriented flex containers (https://github.com/philipwalton/flexbugs#14-flex-containers-with-wrapping-the-container-is-not-sized-to-contain-its-items) which may be related to this as well.

like image 177
ADyson Avatar answered Sep 28 '22 03:09

ADyson