Cray
Cray

Reputation: 5513

Let image overflow the grid in Bootstrap 4

I want to display an image like in the screenshot below. It should start inside the grid but scale to the left or right of the screen.

At the moment, I'm not sure how to achieve this because the container limits the with. But I need the container to let it start inside the grid?!

enter image description here

I've tried this: Extend bootstrap row outside the container

Here's the code:

#main {
    background: lightgreen;
    height: 100vh;
}

#main > .row {
    height: 100vh;
}

.left {
    background: red;
    position: relative;
    top: 50%;
    transform: translateY(-50%);
}

.left:before {
    left: -999em;
    background: red;
    content: '';
    display: block;
    position: absolute;
    width: 999em;
    top: 0;
    bottom: 0;
}
<div class="container" id="main">
    <div class="row">
        <div class="col-lg-6 left">
            ..
        </div>
    </div>
</div>

But the solution isn't working with images.

Upvotes: 1

Views: 904

Answers (2)

Heidel
Heidel

Reputation: 3262

It's not very beautiful solution, but it works

HTML

<div class="container">
    <div class="row">
        <div class="col-12 pb-3 mb-3 block bg-start">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate, cum. Illum unde dolorum, quos tempore dicta velit accusamus saepe praesentium fugiat cumque nulla animi ipsa! Earum id beatae, ullam nulla.
        </div>
    </div>
    <div class="row">
        <div class="col-12 pb-3 mb-3 block bg-end">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate, cum. Illum unde dolorum, quos tempore dicta velit accusamus saepe praesentium fugiat cumque nulla animi ipsa! Earum id beatae, ullam nulla.
        </div>
    </div>
    <div class="row">
        <div class="col-12 pb-3 mb-3 block bg-start">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate, cum. Illum unde dolorum, quos tempore dicta velit accusamus saepe praesentium fugiat cumque nulla animi ipsa! Earum id beatae, ullam nulla.
        </div>
    </div>
</div>

CSS

.container {
  position: relative;
}

.container:before {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  display: block;
  content: '';
  background-color: rgba(255,0,0,0.5);
}

.block {
  position: relative;
  color: #fff;
}

.block:before {
  position: absolute;
  top: 0;
  bottom: 0;
  background-color: #000;
  content: '';
  display: block;
  width: 200%;
  z-index: -1;
}

.block.bg-start:before {
  left: -100%;
  right: 100%;
}

.block.bg-end:before {
  left: 0;
  right: -100%;
}

https://jsfiddle.net/sfh76q6q/37/

Of course, you can set any background image for .container:before insteaf of background-color

  background-image: url('example.png');
  background-repeat: repeat;
  background-position: 0 0;

Upvotes: 2

tao
tao

Reputation: 90312

Here's how I'd do it.

JS

function extendables() {
  $('.extend-left,.extend-right').each(function(i, e) {
    let w = ($(window).width() - $(e).closest('[role="main"]').width()) / 2;
    $(e).css({
      position: "relative",
      width: $(this).closest('[class^="col-"]').width() + w + 'px'
    })
    if ($(e).is('.extend-left')) {
      $(e).css({
        left: '-' + w + 'px'
      });
      if ($(e).is('.extend-right')) {
        $(e).width($('body').width() + 'px')
      }
    }
  })
}

$(window).on('load resize', extendables);

CSS

/* 
 * You don't really need this. I only added it to make images
 * grow to 100% width of their container when they are too small.
 */
[class^="extend-"] img {
  display: block;
  width: 100%;
  height: auto;
}

Markup

<div class="extend-left"> <!-- or "extend-right", or both... -->
  <img src="http://via.placeholder.com/350x150" class="img-fluid" alt="Responsive image">
</div>
  • the markup should be placed inside the column you want to extend.
  • it assumes a column extended to the left is already touching the left side of the container and a column extended to the right already touches the right side of the container.
  • adding both classes inside a col-12 column will extend to full width.
  • if you use it extensively (over 10 cases per page, with lots of contents) and page seems sluggish on resize event, you might want to throttle the call on extendables() at 10ms, maybe 20ms.
  • main advantage over similar methods being it does not need position:absolute on the extended element, so it can naturally grow the height of parent according to contents
  • you can safely change the class names from extend-left/right to whatever you want, in case there is any clashing with theme class names. Just change them everywhere (markup, js + css).

Proof of concept:

function extendables() {
  $('.extend-left,.extend-right').each(function(i, e) {
    let w = ($(window).width() - $(e).closest('[role="main"]').width()) / 2;
    $(e).css({
      position: "relative",
      width: $(this).closest('[class^="col-"]').width() + w + 'px'
    })
    if ($(e).is('.extend-left')) {
      $(e).css({
        left: '-' + w + 'px'
      });
      if ($(e).is('.extend-right')) {
        $(e).width($('body').width() + 'px')
      }
    }
  })
}

$(window).on('load resize', extendables);
[class^="extend-"] img {
  display: block;
  width: 100%;
  height: auto;
}

/* Everything below is not needed for .extend-* classes to work
 * I simply copied it from the Bootstap sticky footer example
 */
 
/* Sticky footer styles
-------------------------------------------------- */

html {
  position: relative;
  min-height: 100%;
}

body:not(#_) {
  /* Margin bottom by footer height */
  margin-bottom: 60px;
}

.footer {
  position: absolute;
  bottom: 0;
  width: 100%;
  /* Set the fixed height of the footer here */
  height: 60px;
  line-height: 60px;
  /* Vertically center the text there */
  background-color: #f5f5f5;
}


/* Custom page CSS
-------------------------------------------------- */


/* Not required for template or sticky footer method. */

body>.container {
  padding: 60px 15px 0;
}

.footer>.container {
  padding-right: 15px;
  padding-left: 15px;
}

code {
  font-size: 80%;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

<header>
  <!-- Fixed navbar -->
  <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
    <a class="navbar-brand" href="#">Fixed navbar</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
    <div class="collapse navbar-collapse" id="navbarCollapse">
      <ul class="navbar-nav mr-auto">
        <li class="nav-item active">
          <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Link</a>
        </li>
        <li class="nav-item">
          <a class="nav-link disabled" href="#">Disabled</a>
        </li>
      </ul>
      <form class="form-inline mt-2 mt-md-0">
        <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
        <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
      </form>
    </div>
  </nav>
</header>
<main role="main" class="container">
  <h1 class="mt-5">Lorem ipsum...</h1>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vel erat ligula. Nulla vehicula molestie nulla id eleifend. Nam sodales augue nisi, id laoreet orci tristique nec. Aliquam laoreet felis eget enim rhoncus placerat. Cras sit amet elementum mi, eu placerat ante. Fusce blandit urna sit amet eros hendrerit, ut scelerisque <code>metus mollis</code>. Duis molestie ligula vel ipsum tristique, eu congue odio vehicula. Sed turpis ex, tincidunt vitae nunc in, egestas dictum nibh.
  <p>Pellentesque nec viverra libero. Vivamus ac commodo sem. Vestibulum suscipit euismod consequat. Aliquam ut nibh et arcu accumsan malesuada. Suspendisse volutpat tortor ligula, nec ultricies enim laoreet at. Nunc ligula metus, porttitor at faucibus vitae, tristique quis justo. Integer euismod ultricies neque sit amet fringilla. Nunc <code>volutpat dui</code> sed ante <code>volutpat pharetra</code>. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus consectetur tincidunt turpis vel posuere. Phasellus convallis ex odio, porttitor varius quam eleifend at. Phasellus accumsan velit metus, in mollis est porttitor in.

  <div class="row">
    <div class="col-9">
      <div class="extend-left">
        <img src="http://via.placeholder.com/350x150" class="img-fluid" alt="Responsive image">
      </div>
      <p class="lead">Mauris fermentum magna nec est tincidunt, sit amet commodo leo lacinia. Sed in ligula sit amet nisi vestibulum eleifend. Suspendisse potenti. Vestibulum nibh lectus, facilisis et placerat non, posuere nec tellus. Suspendisse potenti. Maecenas elit nunc, volutpat dignissim volutpat a, convallis sagittis velit. Etiam molestie dolor vitae posuere ornare. Sed commodo nibh at felis scelerisque euismod. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed iaculis est a tellus auctor cursus. Cras porttitor bibendum metus, id hendrerit tortor pretium eu. Sed sed pulvinar arcu.
    </div>
  </div>
  <div class="row">
    <div class="col-6 offset-6">
      <div class="extend-right">
        <img src="http://via.placeholder.com/650x350" class="img-fluid" alt="Responsive image">
      </div>
      <p class="lead">In eget mollis mauris. Suspendisse semper dui non felis eleifend rutrum. Nunc tempus nulla vitae bibendum ultricies. Praesent convallis varius odio et condimentum. Mauris ut convallis quam. Sed ac neque mauris. Vestibulum tincidunt eu urna ut convallis. Fusce et pellentesque lacus. Integer lorem ante, placerat at posuere id, vulputate at erat. Curabitur eget risus quis nisl eleifend tristique. Donec tincidunt congue nibh, eu dignissim erat.
    </div>
  </div>
  <div class="row">
    <div class="col-12">
      <div class="extend-left extend-right">
        <img src="http://via.placeholder.com/1200x150">
      </div>
    </div>
  </div>
  <h1 class="mt-5">Lorem ipsum...</h1>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vel erat ligula. Nulla vehicula molestie nulla id eleifend. Nam sodales augue nisi, id laoreet orci tristique nec. Aliquam laoreet felis eget enim rhoncus placerat. Cras sit amet elementum mi, eu placerat ante. Fusce blandit urna sit amet eros hendrerit, ut scelerisque <code>metus mollis</code>. Duis molestie ligula vel ipsum tristique, eu congue odio vehicula. Sed turpis ex, tincidunt vitae nunc in, egestas dictum nibh.
  <p>Pellentesque nec viverra libero. Vivamus ac commodo sem. Vestibulum suscipit euismod consequat. Aliquam ut nibh et arcu accumsan malesuada. Suspendisse volutpat tortor ligula, nec ultricies enim laoreet at. Nunc ligula metus, porttitor at faucibus vitae, tristique quis justo. Integer euismod ultricies neque sit amet fringilla. Nunc <code>volutpat dui</code> sed ante <code>volutpat pharetra</code>. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus consectetur tincidunt turpis vel posuere. Phasellus convallis ex odio, porttitor varius quam eleifend at. Phasellus accumsan velit metus, in mollis est porttitor in.
</main>
<footer class="footer">
  <div class="container">
    <span class="text-muted">Place sticky footer content here.</span>
  </div>
</footer>

Upvotes: 1

Related Questions