Reputation: 1
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.
Upvotes: 0
Views: 54
Reputation: 1
Thanks to the answers here I figured out a solution. There are three components:
header
can be part of main
even though this is not essential to the solution.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.
Upvotes: 0
Reputation:
Why not include the header within #main
/* 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: 100%;
}
/* horizontal photo take some portion of width */
.photo_vertical {
max-width: 80%;
}
header {
display: flex;
width: 100%;
}
#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>
Upvotes: 0
Reputation: 9273
The main problem is setting .photo_horizontal
's .max-height: 80vh;
causes it to not always honor the width: 80vw;
which means the width of the .photo_horizontal
is not easily calculated. That makes it difficult to make the <header>
the same width.
You can do this:
header {
width: 80vw;
margin: auto;
}
But it only works if you also get rid of the max-height: 80vh
rule for .photo_horizontal
.
https://codepen.io/km0ser/pen/LYpqeYB
Upvotes: 0