Search code examples
htmlcsslayoutcss-grid

A smarter way to "offset" an element from its container (with background)?


I've got to do a layout like this:

enter image description here

As you can see, the hero image is 'offsetted', background being shorter of it. I managed to do it with nested css grids and a 'dummy' element to add background, but I was wondering if there are smarter ways than using a dummy element... I'm posting a codepen because this built-in editor seems not to correctly render the code I used. I commented it all to explain the important bits.

https://codepen.io/stratboy/pen/YzbbXVa

I'm forced by Stackoverflow to write some code.. Here is some HTML:

<div class="wrapper">
  <div class="container">
    <div class="bg">
    </div>
    <div class="child">
      <div class="offset image">offset</div>
      <div class="text">Lorem Ipsum</div>
    </div>
  </div>
</div>

And (S)CSS:

    .wrapper{ // just to simulate real website
      width: 1200px;
      margin: 0 auto;
    }
    
    .container{ // main grid
      display: grid;
      grid-template-rows: 80px auto 120px;
      grid-template-columns: 1fr;
    
      // full width
      margin-left: calc(-50vw + 50%);
      margin-right: calc(-50vw + 50%);
    }
    
    .bg{ // dummy element  for background
      background-color: teal;
      grid-row: 1 / 3;
      grid-column: 1 / 2;
    }
    
    .child{  
      width: 1200px;
      margin: 0 auto;
      grid-row: 2 / 4; // offset for simulated padding
      grid-column: 1 / 2;
      
      display: grid; // it is a grid itself, so I can offset the "image"
      grid-template-rows: 1fr 120px;
      grid-template-columns: 50% 50%;
    }
    
    .offset.image{
      grid-column: 1 / 2;
      grid-row: 1 / 3;
      background-color: cyan;
    }
    
    .text{
      grid-column: 2 / 3; // restrict to first 2 rows to create the image offset
      grid-row: 1 / 2;
      background-color: green;
      padding-bottom: 80px; // just to test
    }


Solution

  • Just use a linear-gradient that stops a certain distance from the bottom of the containing element.

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    div {
      height: 90vh;
      padding: 20px;
      background-image: 
      linear-gradient(to bottom, pink calc(100% - 50px), transparent calc(100% - 50px));
    }
    
    img {
      height: 100%;
      width: auto;
    }
    <div>
      <img src="https://images.unsplash.com/photo-1717496001989-0a0f32386d12?crop=entropy&cs=srgb&fm=jpg&ixid=M3wzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3MTk1NzU3MzR8&ixlib=rb-4.0.3&q=85" alt="">
    </div>