1

Is it possible to apply styles once an item wraps?

I have a 2 column flexbox where the first item sticks to the left and the one on the right should be in the center of the remaining space. The solution is to add margin: auto to the second item.

// Not relevant for the question - toggle container width
document.querySelector('button').addEventListener('click', () => {
  const flexbox = document.querySelector('#flexbox');
  if (flexbox.style.maxWidth) {
    flexbox.style.maxWidth = null;
  } else {
    flexbox.style.maxWidth = '300px';
  }
});
#flexbox {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  border: 2px solid #397298;
}

#flexbox>div {
  background: #8bc6e3;
  padding: 20px;
}

#item2 {
  margin: auto;
}
<div id="flexbox">
  <div id="item1">Flex item 1 with quite some content</div>
  <div id="item2">Flex item 2</div>
</div>

<button style="margin-top: 30px">Toggle shrink container</button>

Now the question is, how can I remove the margin: auto of #item2 if it's wrapped?
I want it to be on the left side and not centred.

This is what I want:

Not wrapped: enter image description here Wrapped: enter image description here

There were multiple other instances where I wanted to change the style of the flexbox items when they wrap.
I find it very hard sometimes to write general CSS rules on more complex responsive designs. Did a lot of fiddling with grid as well, but it seems that there is no option to customize the wrapped items, even though it changes the page layout and item arrangement quite a lot.

I'm looking forward to container queries that go in this direction, but it's not yet supported by all browsers.

Edit: the button is not question relevant

The items wrap because of a narrow screen size, not because a user makes an action that could be caught by JS.

Samuel Gfeller
  • 840
  • 9
  • 19
  • It may [not be possible](https://stackoverflow.com/questions/55073259/style-only-first-item-in-each-flexbox-row) just with flexbox & css – Cédric Nov 29 '22 at 15:19

1 Answers1

0

If you want to do this with pure css, you only choice is to use mediaqueries afaik. Usually you want to wrap the items when the app is used on phone or some other small device. You can also control the behavior in a more deterministic manner if you give the flex-items a basic width, so you are sure when they'll wrap and when not.

Let's say you want to have 2 rows of some fixed size content:

then you can give both

flex: 0 0 50%

This will make the flex-basis 50% of the parents width. now with a media control the wrapped state

@media(max-width 600px) { margin: none; }

I guess there is no way to achieve this without js in the first place, quoting a stackoverflow fellow from this post:

In CSS, once the browser renders the page on the initial cascade, it doesn't reflow the document when an element wraps. As a result, parent elements don't know when their children wrap.

DrGregoryHouse
  • 510
  • 5
  • 12
  • The width of the first flex item at least is determined by its content, which is variable. It can and should expand as needed and “push” the second item (with a max-width) down (wrap). Such a pity that there is no solution. "As a result, parent elements don't know when their children wrap." but the children themselves could know it by their own width and I think container queries will enable this. – Samuel Gfeller Nov 29 '22 at 14:26