csscss-gridbootstrap-5container-queries

How to use specific divs to measure Bootstrap's breakpoints?


Can Bootstrap 5 provide responsive layouts for two columns whose mutual, vertical border can be dragged? Answer: Yes, by reconfiguring Bootstrap to use container queries rather than media queries. Container queries are supported by major browsers since Feb 2023.

Background: Two divs are stacked side-by-side as columns. Between them is a draggable separator affordance. E.g., the leftmost div has the css resize property set to horizontal, while the rightmost has Bootstrap class flex-grow-1. The user can then drag the separator affordance to the left or right.

Desired outcome: Bootstrap's grid tiers inside the column divs should be chosen based on the divs' individual widths as opposed to relying on the viewport width.

Illustration (all gray divs have class="col-sm-12 col-md-6 col-lg 4"):

enter image description here

So, when using the col-sm-12 col-md-6 col-lg 4classes etc. in Bootstrap, how to best add logic to “do measurements based on the parent div” or “div with id #X”?


Solution

  • For each desired Bootstrap class, e.g. col-sm-6,col-md-4 and col-lg-3, override the width set by Bootstrap's media queries and use a width based on container queries, as below. This allows the changes to be done only in CSS, with no changes to the HTML and no JavaScript, using vanilla Bootstrap classes, just adding a ucq (“use container queries”) class where desirable.

    CSS:

    .container-query-target { container-type: inline-size; }
    
    /* ucq: use container queries */
    .ucq .col-sm-6,
    .ucq .col-md-4,
    .ucq .col-lg-3,
    { width: 100%; }
    
    @container (min-width:576px) {
        .ucq .col-sm-6 { width: 50%; }
    }
    @container (min-width:768px) {
        .ucq .col-md-4 { width: 33.33333333%; }
    }
    @container (min-width:992px) {
        .ucq .col-lg-3 { width: 25%; }
    }
    

    HTML:

    <div class="row container-query-target ucq">
        <div class="test col-sm-6 col-md-4 col-lg-3">Sample content</div>
    </div>