I'm trying to make a page with a horizontal scrolled image gallery using flex grid.
The gallery should be centered on the page with bars on the sides. To accomplish this, I have created a css grid with areas 'mainleft maincenter mainright'. It shuld look something like this:
The problem is the page is not responsive. So, if I do not set max-width of the gallery the site looks like this:
The gallery overflows the entire page. Setting max-width to 100% do not work. Setting max-widt to something like 700px works but then the page is not responsive anymore.
Code for the page:
<!DOCTYPE html>
<html lang="en">
<head>
<title>HScroll gallery test</title>
<style>
main {
background-color:aqua;
display: grid;
grid-template-columns: 100px auto 100px;
grid-template-rows: auto;
grid-template-areas: 'mainleft maincenter mainright';
}
.left {
grid-area: mainleft;
background-color:coral;
}
.right {
grid-area: mainright;
background-color:coral;
}
.gallery {
grid-area: maincenter;
position: relative;
max-width: 100%; /* Not working */
padding: 0 10;
}
.gallery_scroller {
/* snap mandatory on horizontal axis */
scroll-snap-type: x mandatory;
overflow-x: scroll;
overflow-y: hidden;
display: flex;
align-items: center;
height: 300px;
/* Enable Safari touch scrolling physics which is needed for scroll snap */
-webkit-overflow-scrolling: touch;
}
.gallery_scroller img {
/* snap align center */
scroll-snap-align: center;
scroll-snap-stop: always;
margin:22px;
}
</style>
</head>
<body>
<main class="main">
<div class="left">
</div>
<div class="gallery">
<div class="gallery_scroller">
<img src="https://placeimg.com/300/300/animals/grayscale"/>
<img src="https://placeimg.com/360/480/animals/grayscale"/>
<img src="https://placeimg.com/640/480/animals/grayscale"/>
<img src="https://placeimg.com/360/360/animals/grayscale"/>
<img src="https://placeimg.com/2560/960/animals/grayscale"/>
<img src="https://placeimg.com/360/360/animals/grayscale"/>
</div>
</div>
<div class="right">
</div>
</main>
</body>
</html>
main {
background-color:aqua;
display: grid;
grid-template-columns: 100px auto 100px;
grid-template-rows: auto;
grid-template-areas: 'mainleft maincenter mainright';
}
.left {
grid-area: mainleft;
background-color:coral;
}
.right {
grid-area: mainright;
background-color:coral;
}
.gallery {
grid-area: maincenter;
position: relative;
width: 100%; /* Not working */
padding: 0 10;
}
.gallery_scroller {
/* snap mandatory on horizontal axis */
scroll-snap-type: x mandatory;
overflow-x: scroll;
overflow-y: hidden;
display: flex;
align-items: center;
height: 300px;
/* Enable Safari touch scrolling physics which is needed for scroll snap */
-webkit-overflow-scrolling: touch;
}
.gallery_scroller img {
/* snap align center */
scroll-snap-align: center;
scroll-snap-stop: always;
margin:22px;
}
<main class="main">
<div class="left">
</div>
<div class="gallery">
<div class="gallery_scroller">
<img src="https://placeimg.com/300/300/animals/grayscale"/>
<img src="https://placeimg.com/360/480/animals/grayscale"/>
<img src="https://placeimg.com/640/480/animals/grayscale"/>
<img src="https://placeimg.com/360/360/animals/grayscale"/>
<img src="https://placeimg.com/2560/960/animals/grayscale"/>
<img src="https://placeimg.com/360/360/animals/grayscale"/>
</div>
</div>
<div class="right">
</div>
</main>
Here is a possible solution with minimum modifications to the original code.
The main change here is in the grid-template-columns property: Instead of
grid-template-columns: 100px auto 100px;
it's
grid-template-columns: 100px minmax(0, 1fr) 100px;
If I'm not wrong, a value of auto takes the inner content in account as well as the availalable width so that breaks the desired width limitation. On the other hand, minmax(0, 1fr) means that 1fr would be the maximun width for this column. 1fr is one fraction of what remained after the other fixed-width columns took their own space, and since there is only one column remained it takes the entire remaining width.
Another minor change to the code is fixing the broken padding by changing 10 to 10px.
main {
background-color: aqua;
display: grid;
grid-template-columns: 100px minmax(0, 1fr) 100px;
grid-template-rows: auto;
grid-template-areas: 'mainleft maincenter mainright';
}
.left {
grid-area: mainleft;
background-color: coral;
}
.right {
grid-area: mainright;
background-color: coral;
}
.gallery {
grid-area: maincenter;
position: relative;
width: 100%;
padding: 0 10px;
}
.gallery_scroller {
/* snap mandatory on horizontal axis */
scroll-snap-type: x mandatory;
overflow-x: scroll;
overflow-y: hidden;
display: flex;
align-items: center;
height: 300px;
/* Enable Safari touch scrolling physics which is needed for scroll snap */
-webkit-overflow-scrolling: touch;
}
.gallery_scroller img {
/* snap align center */
scroll-snap-align: center;
scroll-snap-stop: always;
margin: 22px;
}
<main class="main">
<div class="left">
</div>
<div class="gallery">
<div class="gallery_scroller">
<img src="https://placeimg.com/300/300/animals/grayscale" />
<img src="https://placeimg.com/360/480/animals/grayscale" />
<img src="https://placeimg.com/640/480/animals/grayscale" />
<img src="https://placeimg.com/360/360/animals/grayscale" />
<img src="https://placeimg.com/2560/960/animals/grayscale" />
<img src="https://placeimg.com/360/360/animals/grayscale" />
</div>
</div>
<div class="right">
</div>
</main>
I know isn't the best solution but it works for you because images are causing overflow
.gallery {
grid-area: maincenter;
position: relative;
width: calc(100vw - 200px);
/*width: 100%; Not working */
padding: 0 10;
}
btw
your padding isn't working because doesn't have units, maybe u wanted px
Related
When creating my dashboard with flexbox css html, I have a scroll problem for example:
In the middle red container if I make it vertical the horizontal one does not work well for me opteniendo results like it expands the container descuadrando the design.
If I work the horizontal scroll does not work the vertical scroll expanding this.
I want it to work like this in the following image:
Desired result
I have tried many things with the flexbox like setting the height or width to 100% and even forcing the scroll, but I can't get the expected effect.
Your question is a bit broad, you should post your current solution next time to see which part is not working. For example, I couldn't really tell if the vertical scrollbar in the middle region is supposed to scroll the top or the middle part. Anyways, if you're set on using flexboxes, here's a way to do it:
body {
margin: 0;
}
main {
display: flex;
width: 100vw;
height: 100vh;
}
.left {
width: 20%;
background-color: cornflowerblue;
}
.left__header {
background-color: lightblue;
}
.middle {
display: flex;
flex-direction: column;
width: 40%;
background-color: salmon;
}
.middle__header {
flex-shrink: 0;
overflow-y: auto;
background-color: lightpink;
}
.middle__body {
overflow-x: auto;
}
.middle__footer {
margin-top: auto;
background-color: white;
}
.right {
width: 40%;
background-color: lightgreen;
}
<main>
<div class="left">
<div class="left__header">1</div>
<div class="left__body"></div>
</div>
<div class="middle">
<div class="middle__header">
<!-- Fixed width to simulate overflowing content -->
<div style="min-width: 2000px">1 2 3 4 5</div>
</div>
<div class="middle__body">
<!-- Fixed height to simulate overflowing content -->
<div style="min-height: 2000px">Content</div>
</div>
<div class="middle__footer">
Pia de Pagina
</div>
</div>
<div class="right">
SideBar Right
</div>
</main>
But if you don't plan on dynamically adding/removing elements or moving stuff around in the base layout (i.e. these regions stay the same during the use of the application) I'd recommend using CSS grid instead:
body {
margin: 0;
}
main {
display: grid;
grid-template:
"left-header middle-header right" min-content
"left-body middle-body right"
"left-body middle-footer right" min-content / 2fr 4fr 4fr;
width: 100vw;
height: 100vh;
}
.left__header {
grid-area: left-header;
background-color: lightblue;
}
.left__body {
grid-area: left-body;
background-color: cornflowerblue;
}
.middle__header {
grid-area: middle-header;
overflow-x: auto;
background-color: lightpink;
}
.middle__body {
grid-area: middle-body;
overflow-y: auto;
background-color: salmon;
}
.middle__footer {
grid-area: middle-footer;
background-color: white;
}
.right {
grid-area: right;
background-color: lightgreen;
}
<main>
<div class="left__header">1</div>
<div class="left__body"></div>
<div class="middle__header">
<!-- Fixed width to simulate overflowing content -->
<div style="min-width: 2000px">1 2 3 4 5</div>
</div>
<div class="middle__body">
<!-- Fixed height to simulate overflowing content -->
<div style="min-height: 2000px">Content</div>
</div>
<div class="middle__footer">
Pia de Pagina
</div>
<div class="right">
SideBar right
</div>
</main>
This results in the same output, but the HTML/CSS is much more readable IMO. It uses the grid-template property, which is fairly new, but should be available in most browsers.
Considering this HMTL:
/* Desired styiling: */
.container {
display: grid;
grid-template-columns: 250px 250px 250px /* this is the part to automate */
grid-template-rows: 50px;
}
.child {
width: 100%;
height: 100%;
background: red;
}
<div class="container">
<div class="child">x</div>
<div class="child">y</div>
<div class="child">z</div>
</div>
And the fact that the number of .child element can change.
How can I make .container have display grid and a column of size 250px for every .child el?
I know this can be done in JS but I was looking for a css solution.
Update your code like below:
.container {
display: grid;
grid-auto-columns: 250px; /* size of each column */
grid-auto-flow: column; /* column flow */
grid-template-rows: 50px;
}
.child {
background: red;
}
<div class="container">
<div class="child">x</div>
<div class="child">y</div>
<div class="child">z</div>
</div>
I have a CSS grid, but I'm finding that the grid rows are not all fitting onto the page - instead, they're causing an overflow. How can I resize the grid rows so that they don't overflow the page? I thought the 1fr value was supposed to do this, but it doesn't seem to be working in my code.
I've had a look at Prevent content from expanding grid items and tried the suggested answers there (such as changing grid-template-rows: repeat(5, 1fr) to grid-template-rows: repeat(5, minmax(0, 1fr)); but to no avail.
I've tried adding height: 100% to the grid and it's container, but it is still overflowing.
JsFiddle https://jsfiddle.net/4g9b2qkL/
body,
html {
margin: 0;
height: 100%;
}
#container {
display: grid;
grid-template-columns: 1fr 5fr;
height: 100%;
}
#left {
grid-column: 1 / 2;
background: lightblue;
height: 100%;
}
#right {
grid-column: 2 / 3;
height: 100%;
}
#results {
display: grid;
grid-template-rows: repeat(5, 1fr);
height: 100%;
}
img {
max-height: 100%;
max-width: 100%;
}
<div id="container">
<div id="left">
<p>
Some stuff on the left....
</p>
</div>
<div id="right">
<h1>
Title
</h1>
<div id="results">
<div class="result">
<img src="https://upload.wikimedia.org/wikipedia/commons/6/62/Paracas_National_Reserve%2C_Ica%2C_Peru-3April2011.jpg" />
</div>
<div class="result">
Result 2
</div>
<div class="result">
Result 3
</div>
</div>
</div>
</div>
A few things to consider:
missing height reference
Using a percentage value to set the height of the img is problematic because there is no defined height on the container. Generally speaking, percentage heights should have a height reference on the parent for reliable rendering. Your declarations may or may not be ignored / misinterpreted.
See: Working with the CSS height property and percentage values
height: 100%
Setting the #results element to height: 100% is problematic, if you want to prevent a vertical overflow, because it doesn't factor in the height of the sibling (the h1).
height: 100% + height of h1 title > height of container (resulting in an overflow)
use a flexible height instead
Instead of using a percentage height, set a more flexible height, such as flex-grow. This tells the container to simply consume remaining space.
override the minimum height default
Grid and flex items are set by default to stop shrinking at the size of their content. Override that setting with min-height: 0.
See: Why don't flex items shrink past content size?
cross browser compatibility
Chrome can do the layout with less code (than posted below). It makes more assumptions about an author's intentions. Firefox, Edge and Safari assume less, so require more rules.
#container {
display: grid;
grid-template-columns: 1fr 5fr;
height: 100vh;
}
#left {
background: lightblue;
}
#right {
display: flex;
flex-direction: column;
height: 100vh;
}
#results {
flex-grow: 1;
min-height: 0;
display: grid;
grid-template-rows: repeat(5, 1fr);
}
.result {
min-height: 0;
}
img {
max-width: 100%;
max-height: 100%;
}
body {
margin: 0;
}
<div id="container">
<div id="left">
<p>Some stuff on the left....</p>
</div>
<div id="right">
<h1>Title</h1>
<div id="results">
<div class="result">
<img src="https://upload.wikimedia.org/wikipedia/commons/6/62/Paracas_National_Reserve%2C_Ica%2C_Peru-3April2011.jpg" />
</div>
<div class="result">Result 2</div>
<div class="result">Result 3</div>
</div>
</div>
</div>
You need to consider min-height:0 in different places and make some adjustment like below:
body,
html {
margin: 0;
height: 100%;
}
#container {
display: grid;
grid-template-columns: 1fr 5fr;
height: 100%;
}
#left {
grid-column: 1 / 2;
background: lightblue;
/*height: 100%; removed */
}
#right {
grid-column: 2 / 3;
/*height: 100%; removed */
min-height:0; /* here */
/* added */
display:flex;
flex-direction:column;
/**/
}
#results {
display: grid;
grid-template-rows: repeat(5, 1fr);
/*height: 100%; removed */
flex-grow:1; /* added */
min-height:0 /* here */
}
.result {
min-height:0 /* here */
}
img {
max-height: 100%;
max-width: 100%;
}
<div id="container">
<div id="left">
<p>
Some stuff on the left....
</p>
</div>
<div id="right">
<h1>
Title
</h1>
<div id="results">
<div class="result">
<img src="https://upload.wikimedia.org/wikipedia/commons/6/62/Paracas_National_Reserve%2C_Ica%2C_Peru-3April2011.jpg" />
</div>
<div class="result">
Result 2
</div>
<div class="result">
Result 3
</div>
</div>
</div>
</div>
In Chrome, my site is breaking on desktop and mobile.
Issues:
The second section isn't displaying the hero image correctly. The image should have two halves that when hovered, join together.
Hero images jump to the top of the page with only half of the image in view.
When I went to inspect the page, I saw the following in the console
[Deprecation] Percentages row tracks and gutters for indefinite height grid containers will be resolved against the intrinsic height instead of being treated as auto and zero respectively
I looked into it and came to find the fix for the said issue was to change percentages in grid-template-rows or grid-auto-rows to auto.
I applied the given fix and the issue still persisted. It only breaks in Google Chrome. The site looks fine in Firefox.
Here's the code.
HTML:
<section class="page">
<div class="details">
<h1>Skyline KPGC110</h1>
<h2>1973</h2>
</div>
<div class="hero">
<a href="./kenmeri.html">
<img class="model-left" src="./images/front-1.png" alt="model">
<img class="model-right" src="./images/front-2.png" alt="model">
</a>
</div>
</section>
<!-- ------------------------------ Seciton 2 ------------------------------ -->
<section class="page about">
<div class="details">
<h1>Skyline PGC10</h1>
<h2>1969</h2>
</div>
<div class="hero">
<a href="./pgc10.html">
<img class="model-left" src="./images/gtr-left.png" alt="chef">
<img class="model-right" src="./images/gtr-right.png" alt="chef">
</a>
</div>
</section>
<!-- ------------------------------ Section 3 ------------------------------ -->
<section class="page reel">
<div class="details">
<h1>Fairlady 240z</h1>
<h2>1973</h2>
</div>
<div class="hero">
<a href="./fairladyz.html">
<img class="model-left" src="./images/240z-left.jpg" alt="model">
<img class="model-right" src="./images/240z-right.jpg" alt="model">
</a>
</div>
</section>
Desktop view:
.page {
display: grid;
grid-template-columns: 5% 1fr 1fr 1fr 5%;
min-height: 90vh;
}
.about,
.reel {
position: absolute;
bottom: 0%;
left: 0%;
width: 100%;
opacity: 0;
pointer-events: none;
}
.hero {
display: flex; /* gets rid of gap between imgs */
align-self: center;
justify-self: center;
height: 500px;
overflow: hidden;
}
.hero a {
display: flex; /* removes seperation created by a tag */
}
.hero img {
height: 500px;
transition: transform 0.3s ease-out;
cursor: pointer;
}
Breakpoint 1(Laptop):
#media screen and (max-width: 1024px) {
.page {
grid-template-columns: 5% 1fr 5%;
grid-template-rows: 2fr 1fr;
align-items: center;
}
.hero {
height: auto;
grid-column: 2;
}
.hero img {
height: 425px;
}
}
Breakpoint 2(Mobile):
#media screen and (max-width: 768px) {
.page {
grid-template-rows: 1fr;
}
.page-1 h3 {
font-size: 1.125rem;
padding-right: 20px;
}
.hero img {
width: auto;
}
.details h2 {
font-size: 28px;
}
}
The link to the repo is here if you want to get a full look at the code.
In your code,
img {
display: block;
width: 100%;
height: 100%;
}
just remove the width: 100% and it will work fine.
I'm trying to setup a grid system with one side a form and the other one an image. Now the problem is that I want everything to go to the bottom of the viewport, but for some reason the image doesn't go to the bottom of the screen.
I've already tried putting a height: 100vh on body, * and the image itself but it didn't change.
.login-section {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-areas: "form form form form form form form form map map map map";
align-items: center;
justify-items: center;
}
.login-section .login-form {
grid-area: form;
}
.login-section .login-map {
grid-area: map;
width: 100%;
overflow-x: hidden;
}
<div class="login-section">
<div class="login-map">
<img src="../img/map.png" alt="photo map">
</div>
<div class="login-form">
<div class="login-form-back">
Bla bla login
</div>
</div>
</div>
Give height: 100vh for login-section and use align-items: flex-end - see demo below:
body {
margin: 0; /* Reset body-margin */
}
img {
display: block; /* Remove whitespace below image*/
height: 100%; /* Image extending the full height of the grid item */
}
.login-section {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-areas: "form form form form form form form form map map map map";
/*align-items: center;*/
align-items: flex-end; /* ADDED */
height: 100vh; /* ADDED */
justify-items: center;
}
.login-section .login-form {
grid-area: form;
}
.login-section .login-map {
grid-area: map;
width: 100%;
overflow-x: hidden;
height: 100vh; /* image over full viewport*/
}
<div class="login-section">
<div class="login-map">
<img src="https://via.placeholder.com/100" alt="photo map">
</div>
<div class="login-form">
<div class="login-form-back">
Bla bla login
</div>
</div>
</div>