skip to Main Content

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
    }

2

Answers


  1. Could you just use a pseudo element to provide a background that only extends down as far as the overhang? That’s the simplest way I can think of

    .content {
      position: relative;
      display: grid;
      grid-template-columns: 2fr 1fr;
      --overhang: 2rem;
    }
    
    .content::after {
      content: "";
      position: absolute;
      inset: 0 0 var(--overhang) 0;
      background-color: #F0EEE9;
      z-index: 2;
    }
    
    .text, .image {
      z-index: 3;
      padding: 0.5rem;
    }
    
    .text {
      padding-bottom: var(--overhang); /* just make sure the text doesn't encroach over the overhung region */
    }
    <div class="content">
      <div class="image">
        <img src='https://picsum.photos/id/237/300/200'>
      </div>
      <div class="text">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam orci ex, ullamcorper id ultrices vel, lacinia ut elit. Maecenas at justo a mauris cursus
      </div>
    </div>
    Login or Signup to reply.
  2. 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>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search