How can I create a “Show All” button after the first image in the gallery on mobile - 600px<, and have a scrollable fixed-width block (div) everywhere else?
It seems, that the only way to do it without js is to have either one or the other - either "Show more" button, or a fixed-width scrollable section.
.container {
display: flex;
flex-direction: column;
align-items: center;
margin: 0 auto;
max-width: 1200px;
padding: 0 1rem;
}
.book {
max-width: 100%;
}
.cell img {
display: block;
}
#media screen and (min-width: 600px) {
.container{
overflow: auto;
height: calc(70vh);
}
.grid {
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
.cell {
width: calc(50% - 2rem);
}
}
#media screen and (min-width: 1000px) {
.container{
overflow: auto;
max-height: 80vh;
}
.cell {
width: calc(33.3333% - 2rem);
}
}
.cell {
margin: 1rem;
}
<div class="container" id="books">
<div class="container">
<div class="grid">
<div class="cell">
<img src="http://lorempixel.com/200/300" class="book">
</div>
<div class="cell">
<img src="http://lorempixel.com/200/300" class="book">
</div>
<div class="cell">
<img src="http://lorempixel.com/200/300" class="book">
</div>
<div class="cell">
<img src="http://lorempixel.com/200/300" class="book">
</div>
<div class="cell">
<img src="http://lorempixel.com/200/300" class="book">
</div>
<div class="cell">
<img src="http://lorempixel.com/200/300" class="book">
</div>
<div class="cell">
<img src="http://lorempixel.com/200/300" class="book">
</div>
<div class="cell">
<img src="http://lorempixel.com/200/300" class="book">
</div>
<div class="cell">
<img src="http://lorempixel.com/200/300" class="book">
</div>
</div>
</div>
</div>
Related
I'm trying to implement horizontal scrolling of fixed width images which are wrapped in divs. The entire layout is wrapped in flex with a left right layout.
However, I'm not able to keep the parent width of the boxes from overflowing. I need the children boxes to scroll horizontally and its parent contained in a flex.
Link to fiddle: https://jsfiddle.net/wn8zd2t6/43/
.dash {
display:flex;
width:100%;
}
.left {
width: 380px;
height: 100vh;
}
.right {
flex: 1 1 0%;
display:flex;
flex-direction: column;
}
.b {
border:1px solid black;
}
.ig {
display:inline-block;
height:100px;
width:180px;
object-fit: cover;
}
.scrollable {
white-space: nowrap;
overflow-x:scroll;
}
.box {
display: inline-block;
}
<div class="dash">
<div class="left b">
left
</div>
<div class="right b">
<div>
top section
</div>
<div class="container">
<!-- necessary -->
<div>
scrollable section title
</div>
<!-- need this to be scroll -->
<div class="scrollable">
<div class="box">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" class="ig" />
<div>
img caption
</div>
</div>
<div class="box">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" class="ig" />
<div>
img caption
</div>
</div>
<div class="box">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" class="ig" />
<div>
img caption
</div>
</div>
<div class="box">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" class="ig" />
<div>
img caption
</div>
</div>
<div class="box">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" class="ig" />
<div>
img caption
</div>
</div>
<div class="box">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" class="ig" />
<div>
img caption
</div>
</div>
</div>
</div>
</div>
</div>
The flex-basis: 0% isn't enough to define a fixed width on the images container, therefore the overflow function doesn't have a break point.
Instead of flex: 1 1 0% use width: calc(100% - 380px) (the 380px being the fixed width of the other column).
This is all you need:
.right {
/* flex: 1 1 0%; */
width: calc(100% - 380px); /* new */
}
revised jsfiddle
.dash {
display: flex;
width: 100%;
}
.left {
width: 380px;
height: 100vh;
}
.right {
/* flex: 1 1 0%; */
width: calc(100% - 380px); /* new */
display: flex;
flex-direction: column;
}
.b {
border: 1px solid black;
}
.ig {
display: inline-block;
height: 100px;
width: 180px;
object-fit: cover;
}
.scrollable {
white-space: nowrap;
overflow-x: scroll;
}
.box {
display: inline-block;
}
<div class="dash">
<div class="left b">
left
</div>
<div class="right b">
<div>
top section
</div>
<div class="container">
<!-- necessary -->
<div>
scrollable section title
</div>
<!-- need this to be scroll -->
<div class="scrollable">
<div class="box">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" class="ig" />
<div>
img caption
</div>
</div>
<div class="box">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" class="ig" />
<div>
img caption
</div>
</div>
<div class="box">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" class="ig" />
<div>
img caption
</div>
</div>
<div class="box">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" class="ig" />
<div>
img caption
</div>
</div>
<div class="box">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" class="ig" />
<div>
img caption
</div>
</div>
<div class="box">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" class="ig" />
<div>
img caption
</div>
</div>
</div>
</div>
</div>
</div>
I simplified your flex code into the following. I added border styling to the image divs for visual clarity of what's going on.
It's important to remember that to constrain a child element's width to a parent with flex view, the parent flex container must have a constraint on it's width, even if it's width: 100%;
You can see this within the .right class and that controls how the rest of that column's children behave with their flex-grow.
/* Utility */
.border-settings {
border: 1px solid black;
}
.scrollable {
display: flex;
flex-direction: row;
overflow-x: scroll;
padding: 10px;
}
/* Container Settings */
.dashboard {
display: flex;
flex-direction: row;
width: 100%;
height: 100vh;
}
.left {
display: flex;
flex-direction: column;
flex-grow: 1;
}
.right {
display: flex;
flex-direction: column;
flex-grow: 1;
height: 100%;
max-width: 50%;
}
.container {
display: flex;
flex-direction: column;
flex-grow: 1;
}
.card {
margin: 10px;
padding: 10px;
border-style: solid;
border-color: black;
border-width: 1px;
border-radius: 10px;
}
/* Element Settings */
img {
height: 100px;
width: 180px;
}
<div class="dashboard">
<div class="left border-settings">
left Section
</div>
<div class="right border-settings">
<div class="top">
top section
</div>
<div class="container">
<!-- necessary -->
<div>
scrollable section title
</div>
<!-- need this to be scroll -->
<div class="scrollable">
<div class="card">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" />
<p>img caption</p>
</div>
<div class="card">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" />
<p>img caption</p>
</div>
<div class="card">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" />
<p>img caption</p>
</div>
<div class="card">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" />
<p>img caption</p>
</div>
<div class="card">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" />
<p>img caption</p>
</div>
<div class="card">
<img src="https://via.placeholder.com/150/FF0000/FFFFFF" />
<p>img caption</p>
</div>
</div>
</div>
</div>
</div>
I recently got help on an issue I got and the final code is in the code section. Now I have just recognized that for smartphone view it does not look the way I want it. The current format is as follows:
Image | Text
Text | Image
Image | Text
Text | Image
For mobile view it should be:
Image
Text
Image
Text
Image
Text
Image
Text
The format for the second and fourth row have to be changed for the mobile view, in order to have the order image - text - image - text etc. For mobile view I have this section: #media only screen and (max-width: 768px){}. Also, does it make sense to have a separate class for each row? Can you please help?
.h1 {
display: flex;
align-items: center;
justify-content: center;
font-size: 50px;
padding-bottom: 50px;
}
.text {
font-size: 24px;
flex-direction: column;
}
.desc {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.image,
.text {
display: flex;
flex: 1 1 50%;
align-items: center;
justify-content: center;
padding: 10px 10px 20px 10px;
box-sizing: border-box;
flex-direction: column;
border: 2px solid;
}
.image img {
max-width: 80%;
}
.left {
justify-content: flex-start;
}
.right {
justify-content: flex-end;
}
<div class="h1">Headline</div>
<div class="desc">
<div class="image left">
<img src="https://homepages.cae.wisc.edu/~ece533/images/mountain.png">
</div>
<div class="text">
<b>Text</b>
<p>Text</p>
</div>
<div class="text">
<b>Text</b>
<p>Text</p>
</div>
<div class="image right">
<img src="https://homepages.cae.wisc.edu/~ece533/images/mountain.png">
</div>
<div class="image left">
<img src="https://homepages.cae.wisc.edu/~ece533/images/mountain.png">
</div>
<div class="text">
<b>Text</b>
<p>Text</p>
</div>
<div class="text">
<b>Text</b>
<p>Text</p>
</div>
<div class="image right">
<img src="https://homepages.cae.wisc.edu/~ece533/images/mountain.png">
</div>
</div>
You can achieve this by updating your CSS
#media only screen and (max-width: 768px){
.desc {
flex-direction: column;
}
.desc > div:first-of-type{
order: 1;
}
.desc > div:nth-last-of-type(2){
order: 2;
}
.desc > div:nth-last-of-type(3){
order: 4;
}
.desc > div:nth-last-of-type(4){
order: 3;
}
.desc > div:nth-last-of-type(5){
order: 5;
}
.desc > div:nth-last-of-type(6){
order: 6;
}
.desc > div:nth-last-of-type(7){
order: 8;
}
.desc > div:nth-last-of-type(8){
order: 7;
}
}
and don't forget to add a viewport in your HTML head if you want the media query to work on mobile devices :
<meta name="viewport" content="width=device-width, initial-scale=1">
Think mobile first and update your html code:
.desc {
display: grid;
}
#media (min-width:768px) {
.desc {
grid-template-columns:1fr 1fr; /* 2 columns only on big screen */
grid-auto-flow:dense; /* fill all the area */
}
.image:nth-child(4n + 3) {
grid-column:2; /* move the each second image to the second column */
}
}
.image,
.text {
display: flex;
align-items: center;
justify-content: center;
padding: 10px 10px 20px 10px;
box-sizing: border-box;
flex-direction: column;
border: 2px solid;
}
.image img {
max-width: 80%;
}
<div class="desc">
<div class="image">
<img src="https://picsum.photos/id/237/200/300">
</div>
<div class="text">
<b>Text</b>
<p>Text</p>
</div>
<div class="image ">
<img src="https://picsum.photos/id/237/200/300">
</div>
<div class="text">
<b>Text</b>
<p>Text</p>
</div>
<div class="image">
<img src="https://picsum.photos/id/237/200/300">
</div>
<div class="text">
<b>Text</b>
<p>Text</p>
</div>
<div class="image">
<img src="https://picsum.photos/id/237/200/300">
</div>
<div class="text">
<b>Text</b>
<p>Text</p>
</div>
</div>
If you are able to restructure your code into groupings as follows:
<div class="content-block">
<div class="image">
<img src="https://homepages.cae.wisc.edu/~ece533/images/mountain.png">
</div>
<div class="text">
<b>Text</b>
<p>Text</p>
</div>
</div>
then you could rewrite the css for your markup in a more compact way that would prevent the need for adding more :nth-of-type statements to your css every time you added a new piece of text or an image.
This css could be written as follows and would account for both mobile and larger breakpoints:
.content-block {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-bottom: 16px;
}
.image,
.text {
display: flex;
flex: 1 1 50%;
align-items: center;
justify-content: center;
padding: 10px 10px 20px 10px;
box-sizing: border-box;
flex-direction: column;
border: 2px solid;
}
.image img {
max-width: 80%;
}
.content-block:nth-of-type(even) .image {
order: 2;
}
#media only screen and (max-width: 768px) {
.content-block {
flex-direction: column;
}
.content-block .image {
order: 1;
}
.content-block .text {
order: 2;
}
}
/* Styles from here and downward can be ignored - they are just for clarity of the example using colours/spacings */
.content-block {
background: aliceblue;
color: black;
}
<div class="desc">
<div class="content-block">
<div class="image left">
Image here
</div>
<div class="text">
<b>Text</b>
<p>Text</p>
</div>
</div>
<div class="content-block">
<div class="image left">
Image here
</div>
<div class="text">
<b>Text</b>
<p>Text</p>
</div>
</div>
<div class="content-block">
<div class="image left">
Image here
</div>
<div class="text">
<b>Text</b>
<p>Text</p>
</div>
</div>
</div>
I am exercising my web development skills by building a simple gallery app. Unfortunately CSS turned out to be biggest problem.
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
.main-container {
height: 100%;
width: 100%;
margin: 0 10%;
display: flex;
flex-direction: column;
}
.searchbox {
margin-bottom: 20px;
}
.gallery {
height: 100%;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(5, 20%);
gap: 20px;
justify-items: center;
}
.image-container {
display: flex;
flex-direction: column;
height: 100%;
}
img {
display: block;
flex: 9;
min-height: 0;
}
.title {
flex: 1;
}
.pagination {
margin-top: 20px;
}
<div class="main-container">
<div class="searchbox">SEARCHBOX</div>
<div class="gallery">
<div class="image-container">
<img src="https://placekitten.com/200/300"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/300/200"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/200/200"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/400/300"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/200/300"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/100/300"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/100/100"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/200/300"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/200/200"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/300/100"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/200/300"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/200/300"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/200/300"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/200/300"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/200/300"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/200/300"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/200/300"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/200/300"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/200/300"/>
<div class="title">TITLE</div>
</div>
<div class="image-container">
<img src="https://placekitten.com/200/300"/>
<div class="title">TITLE</div>
</div>
</div>
<div class="pagination">PAGINATION</div>
</div>
My gallery will have 20 images per page (4x5). The images might be of different sizes - some might be horizontal, some vertical, some square.
The problems that I have:
The images are scaled in a way that does not keep their original ratio
The "app" does not take only 100% of the height - it takes more, and I need to scroll. Ideally, 100% should be taken always
The "pagination" DIV landed somewhere inside of the grid. It should be placed below the grid.
I have to admit that I tried many different ways to fix it, however I was either getting into even weirder results, or not fixing the problem at all.
What is wrong with my CSS?
First take the height and width out of your html, body - it's directly affecting your image sizes
html, body {margin:0; padding:0;}
Then drop the margin from your main container, it's causing an overflow. Maybe you meant to use padding?
.main-container {
height: 100%;
width: 100%;
/*margin: 0 10%;*/ <--- Remove
display: flex;
flex-direction: column;
}
After that you can use the object-fit property to align your image positions :) It's important that your height and width are set though!
img {
display: block;
flex: 9;
min-height: 0;
width:300px;
max-height:300px;
object-fit:cover;
}
I hope this helps! https://jsfiddle.net/1txLvoh6/
I'd prefer this variant:
html,
body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
.main-container {
width: 80%;
margin: 0 10%;
display: grid;
grid-gap: 20px;
grid-template-rows: 1em max-content 1em;
grid-template-columns: 1fr;
}
.searchbox {
/* your styles for searchbox */
}
.gallery {
display: grid;
/* columns can be equal too, using calc and without justification on center */
grid-template-columns: repeat(4, 1fr);
/* 4 gaps between rows + 2 gaps above and below of gallery + search and pager heights */
grid-template-rows: repeat(5, calc(20vh - 2em));
grid-gap: 20px;
justify-items: center;
}
.image-container {
display: flex;
flex-direction: column;
height: 100%;
}
img {
display: block;
flex: 9;
min-height: 0;
object-fit: cover;
}
.title {
flex: 1;
}
.pagination {
/* your styles for pagination */
}
https://jsfiddle.net/joel081112/6yud4bvo/3/
I have this fiddle which shows my current situation. I cant get my text to always be aligned in the middle of the div next to the image. At the minute the text stays level with the top of the div.
I have tried vertical-aligned and top: 50% but I must be missing something easy
.homeInfo2 {
padding: 20px;
height: auto;
text-align: center;
float: left;
}
.homeIm1 {
height: auto;
float: right;
}
.item {
display: flex;
width: 100%;
}
.item:nth-child(odd) {
flex-direction: row-reverse;
}
.item > div {
width: 50%;
}
<article class="item">
<div class="homeInfo2">
some text 1
</div>
<div class="homeIm2">
<img src="https://cdn1.imggmi.com/uploads/2019/10/11/13fad36a93db836e4eaa1906b8f16433-full.jpg">
</div>
</article>
That code is the crux of what I'm using
Since your .item element is a flexbox set align-items: center on the item:
.item {
display: flex;
width: 100%;
align-items: center;
}
.item:nth-child(odd) {
flex-direction: row-reverse;
}
.item>div {
width: 50%;
}
.homeIm1 {
height: auto;
}
.homeInfo2 {
padding: 20px;
text-align: center;
}
img {
max-width: 100%;
height: auto;
}
#media (max-width: 500px) {
.item,
.item:nth-child(odd) {
flex-direction: column;
}
.item>div {
width: 100%;
}
}
<div class="container">
<article class="item">
<div class="homeInfo2">
some text 1
</div>
<div class="homeIm2">
<img src="https://cdn1.imggmi.com/uploads/2019/10/11/13fad36a93db836e4eaa1906b8f16433-full.jpg">
</div>
</article>
<hr>
<article class="item">
<div class="text">
some text
</div>
<div class="image">
some image
</div>
</article>
<hr>
<article class="item">
<div class="text">
some text 2
</div>
<div class="image">
some image 2
</div>
</article>
<hr>
<article class="item">
<div class="homeInfo2">
some 1 text blah
</div>
<div class="homeIm2">
<img src="https://cdn1.imggmi.com/uploads/2019/10/11/13fad36a93db836e4eaa1906b8f16433-full.jpg">
</div>
</article>
<hr>
<article class="item">
<div class="text">
some text
</div>
<div class="image">
some image
</div>
</article>
<hr>
<article class="item">
<div class="text">
some text
</div>
<div class="image">
some image
</div>
</article>
</div>
Try using flex.
You have to create a div next to the image and then justify-content-center and align-items-center. For more information use google :) Especially css-tricks would be helpful! CSS-Tricks
Just add align-items: center; in your item class.
.item {
display: flex;
width: 100%;
align-items: center;
}
.item:nth-child(odd) {
flex-direction: row-reverse;
}
.item>div {
width: 50%;
}
.homeIm1 {
height: auto;
float: right;
}
.homeInfo2 {
padding: 20px;
height: auto;
text-align: center;
float: left;
}
img {
max-width: 100%;
height: auto;
}
#media (max-width: 500px) {
.item,
.item:nth-child(odd) {
flex-direction: column;
}
.item>div {
width: 100%;
}
}
<div class="container">
<article class="item">
<div class="homeInfo2">
some text 1
</div>
<div class="homeIm2">
<img src="https://cdn1.imggmi.com/uploads/2019/10/11/13fad36a93db836e4eaa1906b8f16433-full.jpg">
</div>
</article>
<hr>
<article class="item">
<div class="text">
some text
</div>
<div class="image">
some image
</div>
</article>
<hr>
<article class="item">
<div class="text">
some text 2
</div>
<div class="image">
some image 2
</div>
</article>
<hr>
<article class="item">
<div class="homeInfo2">
some 1 text blah
</div>
<div class="homeIm2">
<img src="https://cdn1.imggmi.com/uploads/2019/10/11/13fad36a93db836e4eaa1906b8f16433-full.jpg">
</div>
</article>
<hr>
<article class="item">
<div class="text">
some text
</div>
<div class="image">
some image
</div>
</article>
<hr>
<article class="item">
<div class="text">
some text
</div>
<div class="image">
some image
</div>
</article>
</div>
I am trying to create an image gallery using HTML and CSS but I have some trouble making the gallery appear in the middle of the page. As of now the images (grey boxes in picture) are to far to the left. I would like the whole gallery to be centered on the page.
Any help with this would be much appreciated!
Screenshot
#content {
overflow: auto;
margin-top: 30px;
margin-bottom: 30px;
background-color: #6b88f2;
}
.gallery {
min-height: calc(100vh - 200px);
margin: 0 auto;
max-width: 1200px;
padding: 0 1rem;
background-color: #ec6e52;
}
.cell {
margin: 0.5rem;
}
.cell img {
display: block;
}
.responsive-image {
max-width: 100%;
}
#media screen and (min-width: 600px) {
.grid {
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
.cell {
width: calc(50% - 5rem);
}
}
#media screen and (min-width: 1000px) {
.cell {
width: calc(33.3333% - 5rem);
}
}
<div id="content">
<div class="gallery">
<div class="grid">
<div class="cell">
<img src="bilder/test.png" alt="OS" class="responsive-image">
</div>
<!--End cell -->
<div class="cell">
<img src="bilder/test.png" alt="OS" class="responsive-image">
</div>
<!--End cell -->
<div class="cell">
<img src="bilder/test.png" alt="OS" class="responsive-image">
</div>
<!--End cell -->
<div class="cell">
<img src="bilder/test.png" alt="OS" class="responsive-image">
</div>
<!--End cell -->
<div class="cell">
<img src="bilder/test.png" alt="OS" class="responsive-image">
</div>
<!--End cell -->
<div class="cell">
<img src="bilder/test.png" alt="OS" class="responsive-image">
</div>
<!--End cell -->
</div>
<!--End grid -->
</div>
<!--End gallery -->
</div>
<!--End content -->
I would just put text-align: center on .grid, knowing that it will trickle down
Or you can use flexbox which will give you an easier time overall:
.grid {
display: flex;
flex-wrap: wrap;
justify-content: center;
}