Mathijs
Mathijs

Reputation: 357

Bootstrap grid: fluid to "one side"

I'm working on a lay-out using Bootstrap's grid system. I currently have something like this:

<div class="container">
    <div class="col-xs-8">...</div>
    <div class="col-xs-4">...</div>
</div>

What I actually want to achieve is for the second column to take up the rest of the horizontal space available, i.e. the second column behaves as if it is in a fluid container but the first column still behaves as if in a fixed container.

I tried using the :after pseudo-selector to introduce a block that appears next to the second column (this would be okay since the "whole-width-column"-thing is purely for cosmetic reasons), but I couldn't get it to take up all space.

If anyone has any ideas on how to achieve this in a nice way, that would be very much appreciated.

Edit: to make things a bit more visual: An example of what I want to achieve

The red block is what I currently have (a column of width 4), the green block is what I'd like to be there.

Upvotes: 5

Views: 11858

Answers (10)

sawacrow
sawacrow

Reputation: 331

https://codepen.io/sawacrow/pen/Jjmvydx

      <div class="container-fluid-sticky-right bg-success"><h1>sticky right container</h1></div>

  <div class="container "><h1>normal container</h1></div>

  <div class="container-fluid-sticky-left bg-warning"><h1>sticky left container</h1></div>

js

    function containerFluidder() {
  var container = document.querySelector('.container');
  var distanceFromWindow = container.offsetLeft;
  var containerStyles = window.getComputedStyle(container);
  var paddingOneSide = parseInt(containerStyles.paddingLeft)
  distanceFromWindow = distanceFromWindow + paddingOneSide;
    document.querySelectorAll('.container-fluid-sticky-left').forEach((el) => {
    el.style.marginRight = distanceFromWindow + 'px';
    });
    document.querySelectorAll('.container-fluid-sticky-right').forEach((el) => {
    el.style.marginLeft = distanceFromWindow + 'px';
    });
}
containerFluidder();
//add event listener to window resize and call containerFluidder
window.addEventListener('resize', containerFluidder);

Upvotes: 0

MarcGuay
MarcGuay

Reputation: 768

Version for Bootstrap 5 if you're using the pre-compiled CSS. Hat tip to https://stackoverflow.com/a/64542602/1096128

.container-fluid-right {
    margin-right: 0;
    padding-right: 0;

    .row{
        margin-right: 0;
        
        > [class*=' col-']:last-child,
        > [class^='col-']:last-child{
            padding-right: 0;
        }
    }
}

@media (min-width: 576px) {
    .container-fluid-right {
        max-width: calc( 100% - (100% - 540px) / 2 );
    }
}

@media (min-width: 768px) {
    .container-fluid-right {
        max-width: calc( 100% - (100% - 720px) / 2 );
    }
}

@media (min-width: 992px) {
    .container-fluid-right {
        max-width: calc( 100% - (100% - 960px) / 2 );
    }
}

@media (min-width: 1200px) {
    .container-fluid-right {
        max-width: calc( 100% - (100% - 1200px) / 2 );
    }
}

@media (min-width: 1400px) {
    .container-fluid-right {
        max-width: calc( 100% - (100% - 1320px) / 2 );
    }
}

Upvotes: 0

RAMIREZ
RAMIREZ

Reputation: 198

Alternative solution if you're using bootstrap's SASS:

// Custom mixin to generate container-fluid-left and container-fluid-right (fluid on the left/right and normal max width on the other)
// For each breakpoint, define the maximum width of the container in a media query
@mixin make-container-fluid-side-max-widths($side, $max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {
  margin-#{$side}: 0;
  padding-#{$side}: 0; 

  .row{
    margin-#{$side}: 0;
  }

  .col, .col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col-auto, .col-lg, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-auto, .col-md, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md-auto, .col-sm, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-auto, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl-auto{
    padding-#{$side}: 0;
  }

  @each $breakpoint, $container-max-width in $max-widths {
    @include media-breakpoint-up($breakpoint, $breakpoints) {
      max-width: calc( 100% - (100% - #{$container-max-width}) / 2 );
    }
  }
}


.container-fluid-left {
  @include make-container();
  @include make-container-fluid-side-max-widths('left');
}

.container-fluid-right {
  @include make-container();
  @include make-container-fluid-side-max-widths('right');
}

Generates two classes - container-fluid-left and container-fluid-right - which will be fluid on the left/right side and only ocupy on the same space as a normal container on the other.

Upvotes: 9

Muhammad Waqas Ansari
Muhammad Waqas Ansari

Reputation: 41

This code work screen size limit 1200px to greater. check this code only in device greater than 1200px. if device size smaller then 1200px layout is normal Demo

.main-box {
  background-color: #ccc;
}

.col-sm-6 {
  height: 50px;
}

.first-col {
  background-color: #f4b334;
}

@media only screen and (min-width: 1200px) {
  .first-col {
    padding-left: calc((100% - 1160px) / 2);
    /* 1160px is your container width or web width*/
  }
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>


<div class="container-fluid main-box">
  <div class="row">
    <div class="col-sm-6 first-col">
      <h2>Hello World</h2>
      <p>this is example text</p>

    </div>

    <div class="col-sm-6">
    </div>
  </div>
</div>

Upvotes: 2

Mikael Eriksson
Mikael Eriksson

Reputation: 1

I had the same problem and decided to just skip the .container class altogether. I created a class called .container-only-left like this

.container-only-left {
    margin-left: calc(50% - 255px);

    @media (min-width: 768px) {
        margin-left: calc(50% - 345px);
    }

    @media (min-width: 992px) {
        margin-left: calc(50% - 465px);
    }

    @media (min-width: 1200px) {
        margin-left: calc(50% - 555px);
    }
}

As long as the .container-only-left class is put inside an element that covers 100vw this works for me.

Upvotes: 0

Hisham Buteen
Hisham Buteen

Reputation: 81

I have found an elegant solution to this. The wrapping container class is used to change the behavior of the containers under it rather than changing it globally.

Also, margin-right: 0 is used to set the container fluid from the right, you can use margin-left: 0 to set it fluid to the other side.

N.B: If the container didn't reach the edge of the screen, just remove the padding from the column.

@media (min-width:768px) {
  .YourWrappingContainerClass .container {
    width: calc(((100% - 750px) / 2) + 750px) !important;
    margin-right: 0;
  }
}

@media (min-width:992px) {
  .YourWrappingContainerClass .container {
    width: calc(((100% - 970px) / 2) + 970px) !important;
    margin-right: 0;
  }
}

@media (min-width:1200px) {
  .YourWrappingContainerClass .container {
    width: calc(((100% - 1170px) / 2) + 1170px) !important;
    margin-right: 0;
  }
}

Upvotes: 8

morksinaanab
morksinaanab

Reputation: 732

I struggled with the same thing as well. I made a version right now that works for 1/3 column on the left and 2/3 + full width column on the right. If time left, I can add all the options based on all col-- options.

What I did is use the 100vw and deduct (with SASS variables ) the fixed width and half of this to add to the left margin, and on the right hand side 0 marging. The columns i split up into 1/3 and 2/3 + the margin again:

.container-fluid-right {
    width:calc(100vw - 30px) !important;
    overflow-x:visible;
    padding-left:0px;
    padding-right:0px;

    > .row > :first-child {
        padding-left:15px;
        padding-right:15px;
    }
    > .row > :last-child {
        padding-right:0px;
        padding-left:0px;
        float:right;
        margin-right: 0px;

    }


    @include when-sm { 
        > .row > :first-child {
            width:calc(#{$screen-sm-min} * 1 / 3);
            margin-left: calc((100vw - #{$screen-sm-min}) / 2);
        }
        > .row > :last-child {
            width:calc((#{$screen-sm-min} * 2 / 3) +((100vw - #{$screen-sm-min}) / 2));
        }
    }
    @include when-md { 
        > .row > :first-child {
            width:calc(#{$screen-md-min} * 1 / 3);
            margin-left: calc((100vw - #{$screen-md-min}) / 2);
        }
        > .row > :last-child {
            width:calc((#{$screen-md-min} * 2 / 3) +((100vw - #{$screen-md-min}) / 2));
        }
    }
    @include when-lg { 
        > .row > :first-child {
            width:calc(#{$screen-lg-min} * 1 / 3);
            margin-left: calc((100vw - #{$screen-lg-min}) / 2);
        }
        > .row > :last-child {
            width:calc((#{$screen-lg-min} * 2 / 3) +((100vw - #{$screen-lg-min}) / 2));
        }
    }
}

I used when-sm / when-md / when-lg from another poster, these are the mixins:

@mixin when-xs() { @media (max-width: $screen-xs-max) { @content; } }
@mixin when-sm() { @media (min-width: $screen-sm-min) { @content; } }
@mixin when-md() { @media (min-width: $screen-md-min) { @content; } }
@mixin when-lg() { @media (min-width: $screen-lg-min) { @content; } }

For the original posters layout (8 left 4 right) the only difference would be switching the 1/3 and 2/3 around

Upvotes: 0

Tricky12
Tricky12

Reputation: 6820

All you need to do is set the right padding of the container to 0 and override the max-width that bootstrap puts on it.

.container {
    padding-right: 0px;
    max-width: none;
}

Demo

EDIT: One more solution you can try is this:

.container {
    padding-left: 0px;
    padding-right: 0px;
    margin-right: 0px;
    max-width: none;
}

New Demo

Upvotes: 4

Christina
Christina

Reputation: 34642

enter image description here

DEMO: http://jsbin.com/titik/1/

HTML

<div class="container">
    <div class="col-xs-8">Content</div>
  <div class="col-xs-4"><div class="well">Words go in here words go in here Words go in here words go in here Words go in here words go in here Words go in here words go in here Words go in here words go in here </div></div>
</div>  

CSS

body {overflow-x:hidden}

.well {
    z-index: 3;
    border: 0px;
    background: red;
    position: relative;
}
.well:after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left:80%;
    right:-3000px;
    background: red;
    z-index: -1;
}

Upvotes: 3

Zac
Zac

Reputation: 1072

 .container {
    margin: 0 0 0 auto;
    padding-right: 0;
  }

This applies a margin of 0 to all sides except the left, which is set to auto. Then to get the second column to butt against the right hand side remove the padding.

Demo

Upvotes: 1

Related Questions