6

.wrapper {
  border: 5px solid pink;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.a-fc {
  background-color: purple;
  width: 300px;
  /*height: 100px;*/
}

.b-fc {
    background-color: orange;
    display: flex;
    flex-direction: column;
    /*flex-wrap: wrap;*/
    flex-basis:70px;
    flex-grow:1;
}

.b-fc > * {
  flex-grow: 1;
  flex-basis: 100px;
}

.b-fc > *:nth-child(1) {
  background-color: red;
}

.b-fc > *:nth-child(2) {
  background-color: blue;
}

.b-fc > *:nth-child(3) {
  background-color: green;
}
<div class="wrapper">
  <div class="a-fc">
   <div>a1</div>
  </div>
  <div class="b-fc">
  <div>b1</div><div>b2</div><div>b3</div>
  </div>
</div>

FC = flex-container. FI = flex-item.

I am able to place .b-fc onto a new row when the space left for it to exist on the original row goes below 70px.

My task: I want b-fc's FIs to stack vertically when no new row is created/they don't wrap. I want b-fc's FIs to align horizontally when b-fc wraps.


Current solution

In the code-snippet above, I've tried to achieve my task by writing one set of properties that work for both scenarios by setting a `flex-basis` on `.b-fc`'s FIs. If the space left for `.b-fc`'s FIs is less than this flex-basis (100px), the FIs will stack vertically. The weakness: i) if `.b-fc`'s `width`'s larger than 300px, its FIs align horizontally ii) When `.b-fc` wraps, its FIs wrap when `.bf-c` is less than 300px.

Therefore, I'm figuring it'd be more powerful to be able to apply CSS when .b-fc wraps. Is this possible?

*Idea 1: CSS variables & JS*

Perhaps using CSS variables/SASS I could continually assess whether FC - .a-fc <= than 70px. If true, apply stylings to .b-fc.

Idea 2: media-queries

Another option is to test when row2 is made, use media queries to capture this and apply CSS to .b-fc with media queries.


P.S. Similar question has been asked here before in 2015. Maybe new techniques have transpired since.

tonitone120
  • 1,920
  • 3
  • 8
  • 25
  • Sounds more like you're asking for a code review in terms of optimization, rather than how to complete the task at hand. One thing to keep in mind is that if the task can be solved purely through CSS, then that is preferred as JavaScript is heavier to run. – Martin Jan 08 '21 at 20:41
  • 1
    Definitely not looking for a code-review. The question in it is: is there any obvious way to apply CSS to a flex-item when that flex-item wraps? I have provided 2 possible ideas. – tonitone120 Jan 08 '21 at 21:24

1 Answers1

2

For this particular case you can consider the use of max() combined with flex-basis. The trick is to either have 0px (horizontal item) or a very big value (vertical items).

You will note that this is not a generic solution and the value is based on your html structure:

395px = 300px (width of a-fx) + 70px (flex-basis of b-fc) + 10px (border of wrapper) + 16px (default body margin) - 1px

.wrapper {
  border: 5px solid pink;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.a-fc {
  background-color: purple;
  width: 300px;
}

.b-fc {
  background-color: orange;
  display: flex;
  flex-wrap: wrap;
  flex-basis: 70px;
  flex-grow: 1;
}

.b-fc>* {
  flex-grow: 1;
  flex-basis: max(0px, (100vw - 395px)*100);
  height: 100px;
}

.b-fc>*:nth-child(1) {
  background-color: red;
}

.b-fc>*:nth-child(2) {
  background-color: blue;
}

.b-fc>*:nth-child(3) {
  background-color: green;
}
<div class="wrapper">
  <div class="a-fc">
    <div>a1</div>
  </div>
  <div class="b-fc">
    <div>b1</div>
    <div>b2</div>
    <div>b3</div>
  </div>
</div>

So to answer your question: No, we cannot apply CSS on wrapping (CSS cannot detect wrapping) but we can always find workaround of each case.

Similar questions:

Without media queries how to achieve 3 column desktop to 1 column mobile layout

CSS grid maximum number of columns without media queries

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • caniuse.com tells me `max()` is supported in all modern browsers but as it's relatively new i'm concerned it'll perform differently amongst browsers as I've observed flexbox (and possibly css-grid) to do. Have you experienced cross-browser inconsistencies using `max()`? – tonitone120 Jan 29 '21 at 14:19
  • @tonitone120 max() is not that new. it has been around for a while so you shouldn't have any issue especially when using it with easy calculation like the one I made – Temani Afif Jan 29 '21 at 14:22
  • I was hoping I could use `auto` as one of `max/min()`'s arguments. I hoped the 'computed value' would be determined from 'auto'. `auto` doesn't seem to be working for me - can I confirm it doesn't? – tonitone120 Jan 29 '21 at 15:11
  • @tonitone120 no, you cannot use auto within min/max ... even `0` is not allowed: https://stackoverflow.com/a/62523544/8620333 – Temani Afif Jan 29 '21 at 15:13
  • It also doesn't take CSS variables does it – tonitone120 Jan 29 '21 at 17:41
  • @tonitone120 it does if you use them correctly – Temani Afif Jan 29 '21 at 19:15
  • To me, this solution relies on one interesting bit of knowledge - is it true that for flex-items, specifying a dimension for `width/flex-basis` greater than the relevant flex-container dimension *does not* cause overflow. Am I right in thinking flex-items are quite unique in this ability? E.g. for a regular `div` within a `div`, if the child `div`'s `width` was set to a larger value than its parent, it would stretch parent or cause overflow. – tonitone120 Mar 28 '21 at 14:18
  • 1
    @tonitone120 this is the `shrink` factor, check this : https://stackoverflow.com/a/49492522/8620333 – Temani Afif Mar 28 '21 at 14:33