Search code examples
csscss-grid

Scaling and aligning a simplistic website with image content


I am working on a simplistic website to show pictures in a single stream. To keep javascript to a minimum (just lazy loading), I only use a single relatively high-resolution version of each image and then rely on CSS to resize.

My question is how the rest of the website, at least the logo and the menu, can be best resized relative to the size of the images. After reading the CSS grid guide I decided to use a grid with grid-auto-flow: row.

The problem: I want the logo to flush left with the left of the top image and the menu to flush right with the right of the top image (all horizontal images have the same width).

My current code either aligns logo and menu to the corners of the page (as with the code below) or centers both (if I move the header into the grid as first item)

#main{
    height: max-content;
    display: grid;
    grid-auto-flow: row;
    grid-row-gap: 8em;
    place-items: center center;
}

.photo_horizontal, .photo_vertical{
    object-fit: contain;
    height: auto;
}

.photo_horizontal{   
    width: 80vw;
    max-height: 80vh;
}

.photo_vertical{
    width: 60vw;
    max-height: 90vh;
}

/* THE HEADER */
header{
    display: grid;
    grid-auto-flow: column;
}

#logo{
    width: 15em;
    justify-self: start;
}

header > div{
    margin: auto 0 0 auto;
}
<header>
  <img id="logo" src="https://via.placeholder.com/500x100/ff7f7f/333333?text=some%20website"/>
  <div>
    <a href="">menu1</a>
    <a href="">menu2</a>
  </div>
</header>
    
<div id="main">
    <img class="photo_horizontal" src="https://picsum.photos/3000/2000"/>
    <img class="photo_vertical" src="https://picsum.photos/2000/3000" />
    <img class="photo_vertical" src="https://picsum.photos/2000/3000" />
    <img class="photo_horizontal" src="https://picsum.photos/3000/2000" />
</div>

Is there an elegant way to resize images relative to the viewport but still align other content accordingly? I tried to pad logo and menu left/right but the necessary padding depends on the actual size of the image.

A pen can be found here.

To clarify, this is how it currently is and this is what I want.


Solution

  • Thanks to the answers here I figured out a solution. There are three components:

    1. As @Zohir Salak pointed out, much simpler CSS can be obtained using flexbox.
    2. The header can be part of main even though this is not essential to the solution.
    3. As @kmoser pointed out, the max-height constraint on images makes it hard to set a proper max-width constraint for the header, a problem that isn't solved by 1. and 2. yet. However, since all of my pictures are 3:2 ratio, a max-height constrained can be turned into a max-width constrained easily and then combined with a min via max-width: min(80vw, 3 / 2 * 80vh);.

    /* Nothing wrong with CSS grid, just Flexbox is simpler */
    
    #main {
      display: flex;
      flex-direction: column;
      align-items: center;
      border: 1px solid;
    }
    
    /* height being auto will keep the aspect ratio */
    /* horizontal photo take full width */
    .photo_horizontal {
        max-width: min(80vw, 3 / 2 * 80vh);
    }
    
    
    /* horizontal photo take some portion of width */
    .photo_vertical {
        max-width: min(80vw, 2 / 3 * 80vh);
    }
    
    header {
      display: flex;
      width: 100vw;
      max-width: min(80vw, 3 / 2 * 80vh);
    }
    
    #logo {
      width: 15em;
    }
    
    header>div {
      margin: auto 0 0 auto;
    }
        
    <div id="main">
          <header>
          <img id="logo" src="https://via.placeholder.com/500x100/ff7f7f/333333?text=some%20website"/>
          <div>
            <a href="">menu1</a>
            <a href="">menu2</a>
          </div>
        </header> 
    
        <img class="photo_horizontal" src="https://picsum.photos/3000/2000"/>
    
        <img class="photo_vertical" src="https://picsum.photos/2000/3000" />
        
        <img class="photo_vertical" src="https://picsum.photos/2000/3000" />
        
        <img class="photo_horizontal" src="https://picsum.photos/3000/2000" />
    </div>

    Alternatively, see the same code in a pen here.