Search code examples
htmlcsscss-positionbootstrap-5

Layering a Bootstrap column on top of another column


How does one overlay a bootstrap column on top of another column, but also keep its size and responsiveness?

For example, I have 4 columns in a row:

enter image description here

When I click on the Overlay btn, it should show the E column over B:

enter image description here

I currently have this test code I am playing with:

Live jsfiddle: https://jsfiddle.net/8pmt6ck2/2/

$(".a .btn").click(function() {
  $(".e").toggleClass("d-none");
});
.one .a {
  background-color: red;
}

.one .b {
  background-color: blue;
}

.one .c {
  background-color: green;
}

.one .d {
  background-color: pink;
}

.one .e {
  background-color: orange;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">

<div class="container one">
  <div class="row">
    <div class="col-sm-3 a">
      <div class="vh-100 text-center">
        <span>A</span>
        <button class="btn btn-primary">Overlay btn</button>
      </div>
    </div>
    <div class="col-sm-3 b">
      <div class="vh-100">
        <span>B</span>
      </div>
    </div>
    <div class="col-sm-3 c">
      <div class="vh-100">
        <span>C</span>
      </div>
    </div>
    <div class="col-sm-3 d">
      <div class="vh-100">
        <span>D</span>
      </div>
    </div>
    <div class="col-sm-3 e position-absolute d-none">
      <div class="vh-100">
        <span>E</span>
      </div>
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>

I am using d-none for E because it does not take up space, otherwise it'll cause Bootstrap to think there are 5 columns, when it's actually 4 columns and one overlay column (on top of B).

The above code sort of works due to position-absolute, but it's in the wrong location, and the column size is not the same as the other 4 columns (appears wider):

enter image description here

Part of the confusion also stems from the bootstrap documentation. It appears if I use position-absolute, I can only position things in certain quadrants of the screen, using top-, start-, end-, and bottom-:

https://getbootstrap.com/docs/5.0/utilities/position/

But because I need this to be responsive and match the column width and such of existing columns in the row, those positioning classes don't help me much here.


How can I overlay my E column properly? Ideally the solution should work for any number of columns in a row, not just 4 like I have above.


Solution

  • Absolute positioning is often problematic and unnecessary. Just toggle the columns in standard layout.

    $(".a .btn").click(function() {
      $(".b, .e").toggleClass("d-none");
    });
    .one .a {
      background-color: red;
    }
    
    .one .b {
      background-color: blue;
    }
    
    .one .c {
      background-color: green;
    }
    
    .one .d {
      background-color: pink;
    }
    
    .one .e {
      background-color: orange;
    }
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
    
    <div class="container one">
      <div class="row">
        <div class="col-sm-3 a">
          <div class="vh-100 text-center">
            <span>A</span>
            <button class="btn btn-primary">Overlay btn</button>
          </div>
        </div>
        <div class="col-sm-3 b">
          <div class="vh-100">
            <span>B</span>
          </div>
        </div>
        <div class="col-sm-3 e d-none">
          <div class="vh-100">
            <span>E</span>
          </div>
        </div>
        <div class="col-sm-3 c">
          <div class="vh-100">
            <span>C</span>
          </div>
        </div>
        <div class="col-sm-3 d">
          <div class="vh-100">
            <span>D</span>
          </div>
        </div>
      </div>
    </div>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>

    If you actually need both columns visible, I'd propose toggling contents instead of columns. Here you will use absolute positioning. I'm also toggling the style class on the column.

    $(".a .btn").click(function() {
      $('.b-e').toggleClass('b e');
      $(".b-e .col-overlay").toggleClass("d-none");
    });
    .one .a {
      background-color: red;
    }
    
    .one .b {
      background-color: blue;
    }
    
    .one .c {
      background-color: green;
    }
    
    .one .d {
      background-color: pink;
    }
    
    .one .e {
      background-color: orange;
      left: 0;
      right: 0;
    }
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
    
    <div class="container one">
      <div class="row">
        <div class="col-sm-3 a">
          <div class="vh-100 text-center">
            <span>A</span>
            <button class="btn btn-primary">Overlay btn</button>
          </div>
        </div>
    
        <div class="col-sm-3 b-e b position-relative">
          <div class="vh-100 col-overlay position-absolute d-none">
            <span>E</span>
          </div>
    
          <div class="vh-100">
            <span>B</span>
          </div>
        </div>
    
        <div class="col-sm-3 c">
          <div class="vh-100">
            <span>C</span>
          </div>
        </div>
    
        <div class="col-sm-3 d">
          <div class="vh-100">
            <span>D</span>
          </div>
        </div>
      </div>
    </div>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>