Skip to content

Conversation

@browner12
Copy link
Contributor

Motivation

Currently with .container and .container-fluid we have an all or nothing approach to either a full width or fixed width layout. I would like to make these containers responsive to give the end user full control over when the switch to a fixed width layout occurs.

It was brought up in PR #24903 , and discussed on the Slack channel. The use case I am addressing in this PR is actually the opposite of what's being asked in the other one, because I see this as the more 99% use case.

Example

The most common use case I see is the user who wants their extra small and small devices to maintain a fluid layout since real estate is at a premium, and only switch to a fixed layout on medium devices and larger where you have much more width.

Approach

If you dig into the source on containers you realize that on extra small devices, .container and .container-fluid are the same. It's not until you hit the larger sizes that max-widths start getting applied. The approach I use is similar to all the other responsive classes where styling is applied to the breakpoint and up. This PR introduces 4 new classes which can be used in place of existing container classes.

  • .container-sm
  • .container-md
  • .container-lg
  • .container-xl

As an example,

<div class="container-md"></div>

would mean the container stays fluid until you hit the medium breakpoint, and from there on up it would be fixed width. This table gives you a full breakdown.

XS Screen SM Screen MD Screen LG Screen XL Screen
.container fixed * fixed fixed fixed fixed
.container-sm fluid fixed fixed fixed fixed
.container-md fluid fluid fixed fixed fixed
.container-lg fluid fluid fluid fixed fixed
.container-xl fluid fluid fluid fluid fixed
.container-fluid fluid fluid fluid fluid fluid

As you can see, the .container and .container-fluid maintain the same functionality so backwards compatibility is maintained.

Next Steps

I imagine this PR will require a decent amount of discussion. One point to address is if it is worth it to be able to go the other direction as well, and switch from a fixed layout to a fluid layout after a certain breakpoint.

Also, I'm sure I could also use some help on optimizing the SCSS.

provide more flexibility and allow the user to determine when containers switch from fluid to fixed width.
@browner12
Copy link
Contributor Author

It might be easier to comprehend if you can see the (desired) compiled code, so here is the CSS:

.container,
.container-fluid,
.container-sm,
.container-md,
.container-lg,
.container-xl {
  width: 100%;
  padding-right: ($grid-gutter-width / 2);
  padding-left: ($grid-gutter-width / 2);
  margin-right: auto;
  margin-left: auto;
}

@media (min-width: 576px) {
  .container,
  .container-sm {
    max-width: 540px;
  }
}

@media (min-width: 768px) {
  .container,
  .container-sm,
  .container-md {
    max-width: 720px;
  }
}

@media (min-width: 992px) {
  .container,
  .container-sm,
  .container-md,
  .container-lg {
    max-width: 960px;
  }
}

@media (min-width: 1200px) {
  .container,
  .container-sm,
  .container-md,
  .container-lg,
  .container-xl {
    max-width: 1140px;
  }
}

@browner12
Copy link
Contributor Author

ping @chasepalmer

@andresgalante
Copy link
Collaborator

Hi @browner12 Thanks a lot for your contribution, the idea is clear and intresting, and I see how this can be useful.

I got your branch and test it out and it works as it should.

I don't know if the naming container-* represent what it does, but naming is really hard and I can't come up with a better option at the moment.

I'll be up to @mdo to decide on this one 😄

@andresgalante andresgalante requested a review from mdo February 15, 2018 12:42
@XhmikosR
Copy link
Member

This is something I always meant to look into myself since I needed it for a project, but worked around it locally and forgot about it :)

I'd like to see this merged too, so 👍 from me.

@fulldecent
Copy link
Contributor

fulldecent commented Feb 20, 2018

Why not use the same approach here as is already being done with rows/columns:

.container,
.container-fluid {
  width: 100%;
  padding-right: ($grid-gutter-width / 2);
  padding-left: ($grid-gutter-width / 2);
  margin-right: auto;
  margin-left: auto;
}

@media (min-width: 576px) {
  .container,
  .container-sm {
    max-width: 540px;
  }
  .container-sm-fluid {
    width: 100%;
    padding-right: ($grid-gutter-width / 2);
    padding-left: ($grid-gutter-width / 2);
    margin-right: auto;
    margin-left: auto;
  }
}

@media (min-width: 768px) {
  .container,
  .container-sm,
  .container-md {
    max-width: 720px;
  }
  .container-sm-fluid,
  .container-md-fluid {
    width: 100%;
    padding-right: ($grid-gutter-width / 2);
    padding-left: ($grid-gutter-width / 2);
    margin-right: auto;
    margin-left: auto;
  }
}

@media (min-width: 992px) {
  .container,
  .container-sm,
  .container-md,
  .container-lg {
    max-width: 960px;
  }
  .container-sm-fluid,
  .container-md-fluid,
  .container-lg-fluid {
    width: 100%;
    padding-right: ($grid-gutter-width / 2);
    padding-left: ($grid-gutter-width / 2);
    margin-right: auto;
    margin-left: auto;
  }
}

@media (min-width: 1200px) {
  .container,
  .container-sm,
  .container-md,
  .container-lg,
  .container-xl {
    max-width: 1140px;
  }
  .container-sm-fluid,
  .container-md-fluid,
  .container-lg-fluid,
  .container-xl-fluid {
    width: 100%;
    padding-right: ($grid-gutter-width / 2);
    padding-left: ($grid-gutter-width / 2);
    margin-right: auto;
    margin-left: auto;
  }
}

This will allow you to (if I did it right here) compose multiple like:

.container .container-lg-fluid

or

.container-fluid .container-lg

or

.container .container-lg-fluid .container-xl

@browner12
Copy link
Contributor Author

browner12 commented Feb 20, 2018

If we can give the user this full control for whether their breakpoint is fluid or fixed, I'm all for that. Even though I feel like switching from a fixed container on a smallish device to a fluid container on a largish device will be a very uncommon use case.

My one concern with your code is we will need to reset the max-width property for all higher breakpoints, since our media queries do not have an upper bound, but simply a min-width.

For example:

<div class="container-fluid container-sm container-md-fluid"></div>

The relevant media queries would be:

@media (min-width: 576px) {
  .container,
  .container-sm {
    max-width: 540px;
  }
  .container-sm-fluid {
    width: 100%;
    padding-right: ($grid-gutter-width / 2);
    padding-left: ($grid-gutter-width / 2);
    margin-right: auto;
    margin-left: auto;
  }
}

@media (min-width: 768px) {
  .container,
  .container-sm,
  .container-md {
    max-width: 720px;
  }
  .container-sm-fluid,
  .container-md-fluid {
    width: 100%;
    padding-right: ($grid-gutter-width / 2);
    padding-left: ($grid-gutter-width / 2);
    margin-right: auto;
    margin-left: auto;
  }
}

This would mean on a device >768px even though it has a width: 100% from the container-md-fluid, it still has the max-width:540px from the .container-sm. Therefore it would still (I believe) behave as a fixed width container at this point. It may be as simple as resetting it with max-width:none for those responsive fluid classes.

@browner12
Copy link
Contributor Author

any movement on this? I'm not sure what the turnaround time is like on new features in this repo.

@browner12
Copy link
Contributor Author

sorry @patrickhlauke, the way you read it is not at all the way I meant it.

just legitimately curious if we like to take the new features a little slower to flesh them out more. For the projects I contribute to, I have a better understanding of the pacing of things, and was just trying to get a feel for BS.

I absolutely share your sentiment on people feeling entitled to OSS, and thanks for all you do in this project.

@patrickhlauke
Copy link
Member

yeah sorry, flew off the handle there...hence deleted the comment. missed the context that this was a PR as well.

@mdo
Copy link
Member

mdo commented Apr 2, 2018

@browner12 Sorry for the delay! I'm going to pull this down and write some docs for it.

@mdo
Copy link
Member

mdo commented Apr 2, 2018

Checking it out locally, the code doesn't generate what you've put into your desired output comment.

@browner12
Copy link
Contributor Author

yah, i think i need some help with the Sass.

i'll give it a shot this week

@mdo
Copy link
Member

mdo commented Apr 2, 2018

Yeah, I'll see about trying to take another look, too :). These layers of loops, maps, and what not always trip me up.

this commit fixes the non-media portion of the generated CSS. I learned about the `@extends` directive and was able to put it to good use.

I create a new temporary map that contains all the main `$container-max-widths` and join it to our 2 special cases of 'xs' and 'fluid'.  Then we loop through that and, with the appropriate infixes, extend our placeholder
forgot to run my tests before the last push, i think these are better.
@browner12
Copy link
Contributor Author

@mdo I was able to clean up the top part with an @extend directive.

I'm running into an issue in the media queries where @extend returns the error

you may not extend an outer selector from within media

which I feel shouldn't apply because I'm trying to extend a selector from within the media query.

Any thoughts on that part?

using the `@extend` directive I was able to clean up this code
@browner12
Copy link
Contributor Author

alright @mdo the new commits are now generating the desired code so this should be ready for review.

@browner12
Copy link
Contributor Author

bump

@browner12
Copy link
Contributor Author

could we put this on either the 4.2 or 4.3 project board?

@midzer
Copy link
Contributor

midzer commented Jun 7, 2018

What is the purpose of this PR?
Afaik container class already scales for different viewports perfectly. Can OP olaborate why to add additional class for each viewport?

@browner12
Copy link
Contributor Author

the first comment is a pretty elaborate explanation of what it does and why it's needed. if there's a specific part you're confused about, I'd be happy to answer.

@mdo
Copy link
Member

mdo commented Jul 7, 2018

@browner12 Haven't forgotten about this. v4.2 is up after v4.1.2, so stay tuned!

@browner12
Copy link
Contributor Author

thanks @mdo ! 4.1 and 4.2 are looking great!

@Tylerian
Copy link

Tylerian commented Apr 30, 2019

Can someone who likes the alternate behavior please explain to me your reasoning and a possible use case? I am honestly struggling to see the benefit of that approach. Why would people want Bootstrap predefined max-widths when they could just add their own specific ones as needed?

<div class="container-sm"></div>

<div style="max-width:600px"></div>

Back in my original comment, I laid out a (IMO) very plausible use case, and one that I've run into many times

The most common use case I see is the user who wants their extra small and small devices to maintain a fluid layout since real estate is at a premium, and only switch to a fixed layout on medium devices and larger where you have much more width.

The purpose of the .container, as it currently stands is to be responsive and adapt to the growing screen width to use as much real estate as possible. We are trying to add to this ability to effectively use screen width by giving the user the ability to choose where the container switches from fluid to fixed.

The alternate behavior takes the responsive aspect of the .container away. I think it will also add to the confusion, because .container will behave differently than all of the others. With this approach, I can also see in the future people saying "Well, I want the <div> to be a .container-sm on small and medium devices, but I want it to be a .container-lg on large and extra large devices." and then we're basically back to where we started.

I usually find myself on the same boat and my solution matches the one from @mdo.

In my experience, when you build a mobile-first responsive website, you want your layout to take the full width of the device screen, usually up to an hd screen desktop.
Extrapolating that sentence to bootstrap language; you want your layout to fluidly grow in width up to the xl grid breakpoint.

With @mdo approach, you would set the .container-xl class in your container and it would do the job seamlessly, starting fluid and constraining on the xl breakpoint. Similarly, if you wanted your layout to grow up to the md breakpoint, you would set your container class to .container-md and you are done. On the other hand, with your approach, the container grows fluid up to the desired breakpoint, and then it adopts the behaviour of the default .container class, increasing in width at each grid breakpoint. This might feel good if your desired breakpoint is the largest one (xl), but when you aim for smaller breakpoints, this feels wrong and not the natural way to do. But hey, again, I'm talking based on my own experiences and of course, I might be wrong.

@browner12
Copy link
Contributor Author

@Tylerian so if I'm understanding you correctly, you would want .container.md to be fluid up til the MD breakpoint, and then stick at a defined width for all wider sizes? That would mean on a 2000px wide screen, the container would be 720px wide.

IMO, this looks silly, and is not a common use case. As I stated before, this takes away the responsiveness of the container, and people should write their own code for this.

Do you have a live example where you've used it this way? It might be helpful for me to see.

@browner12
Copy link
Contributor Author

If you liked the original functionality of this PR, please voice your concern on the new one. It has been merged, and completely changes how this feature will work.

#29095

mdo added a commit that referenced this pull request Jul 23, 2019
This PR fixes the responsive containers that were added in #29095, originally stubbed out in #25631. Apologies to @browner12 for getting that wrong.

Fixes #25631.
mdo added a commit that referenced this pull request Aug 2, 2019
This PR fixes the responsive containers that were added in #29095, originally stubbed out in #25631. Apologies to @browner12 for getting that wrong.

Fixes #25631.
mdo added a commit that referenced this pull request Aug 3, 2019
This PR fixes the responsive containers that were added in #29095, originally stubbed out in #25631. Apologies to @browner12 for getting that wrong.

Fixes #25631.
@mdo mdo closed this in #29118 Aug 5, 2019
mdo added a commit that referenced this pull request Aug 5, 2019
* Follow-up to #29095

This PR fixes the responsive containers that were added in #29095, originally stubbed out in #25631. Apologies to @browner12 for getting that wrong.

Fixes #25631.

* update navbar as well because we cannot reset all containers uniformly

* Update navbars example to include container-xl example to ensure containers match

* rewrite responsive containers docs, add table of max-widths

* Update container docs
- Move table up to the intro
- Remove the container example because it's actually hella confusing
- Update and link to grid example as a demo instead
@browner12
Copy link
Contributor Author

hallelujah, thanks guys!

@browner12 browner12 deleted the responsive-containers branch August 5, 2019 19:31
XhmikosR pushed a commit that referenced this pull request Aug 6, 2019
* Follow-up to #29095

This PR fixes the responsive containers that were added in #29095, originally stubbed out in #25631. Apologies to @browner12 for getting that wrong.

Fixes #25631.

* update navbar as well because we cannot reset all containers uniformly

* Update navbars example to include container-xl example to ensure containers match

* rewrite responsive containers docs, add table of max-widths

* Update container docs
- Move table up to the intro
- Remove the container example because it's actually hella confusing
- Update and link to grid example as a demo instead
XhmikosR pushed a commit that referenced this pull request Aug 10, 2019
* Follow-up to #29095

This PR fixes the responsive containers that were added in #29095, originally stubbed out in #25631. Apologies to @browner12 for getting that wrong.

Fixes #25631.

* update navbar as well because we cannot reset all containers uniformly

* Update navbars example to include container-xl example to ensure containers match

* rewrite responsive containers docs, add table of max-widths

* Update container docs
- Move table up to the intro
- Remove the container example because it's actually hella confusing
- Update and link to grid example as a demo instead
XhmikosR pushed a commit that referenced this pull request Aug 17, 2019
* Follow-up to #29095

This PR fixes the responsive containers that were added in #29095, originally stubbed out in #25631. Apologies to @browner12 for getting that wrong.

Fixes #25631.

* update navbar as well because we cannot reset all containers uniformly

* Update navbars example to include container-xl example to ensure containers match

* rewrite responsive containers docs, add table of max-widths

* Update container docs
- Move table up to the intro
- Remove the container example because it's actually hella confusing
- Update and link to grid example as a demo instead
@jandante
Copy link

Just for clarification. This will go into 4.4 as described by @browner12 in the initial post?

@MartijnCuppens
Copy link
Member

@jandante: Yes, you can view the ship list here: #29096

The v4.4.0 project board can be found here: https://github.com/twbs/bootstrap/projects/18

lucanos pushed a commit to lucanos/bootstrap that referenced this pull request Oct 27, 2019
* Follow-up to twbs#29095

This PR fixes the responsive containers that were added in twbs#29095, originally stubbed out in twbs#25631. Apologies to @browner12 for getting that wrong.

Fixes twbs#25631.

* update navbar as well because we cannot reset all containers uniformly

* Update navbars example to include container-xl example to ensure containers match

* rewrite responsive containers docs, add table of max-widths

* Update container docs
- Move table up to the intro
- Remove the container example because it's actually hella confusing
- Update and link to grid example as a demo instead
// few properties so that content nested within behave properly.
> .container,
> .container-fluid {
> [class^="container"] {
Copy link

@anstapol anstapol Dec 23, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That selector selects only items where class attribute starts with container word, this is more "secure" selector:

> [class^="container"],
> [class*=" container"] {

@include media-breakpoint-down($breakpoint) {
> .container,
> .container-fluid {
> [class^=".container"] {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above but the dot has to be removed:

> [class^="container"],
> [class*=" container"] {

// For nesting containers, have to redeclare for alignment purposes
> .container,
> .container-fluid {
> [class^=".container"] {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👆👆👆 same...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.