Creating responsive 3 x 3 gallery box - css

Hello I am trying to create a flex grid which has 3 by 3 image gallery which is responsive,
Currently this is going on a wordpress page and this is the code to my image using openseadragon.
So I need this image:
to appear three times next to each other and three on the bottom, I will update the images and add more image boxes once i get the correct layout. I need to add a little bit of padding underneath each row too.
Thank you.
<style>
/* assumes reset with box-sizing:border-box; is in effect */
.gallery ul {
display:flex;
flex-wrap:wrap;
position:relative;
left:-1em;
/*
uncomment these if centering desired
max-width:63em;
margin:0 auto;
*/
}
.gallery li {
flex:1 1 auto;
padding:1em;
margin:0 0 1em 1em;
width:26%;
max-width:20em;
}
.gallery a {
text-decoration:none;
}
.gallery li img {
display:block;
max-width:100%;
height:auto;
margin:0 auto 1em;
}
</style>
<section class="gallery">
<h2>Describe this Gallery</h2>
<ul>
<li>
<div id="materials-01581" class="suarrmaterials-zoomable-image" style="height:400px; width:400px;" data-image="2013/02/DSC_0158-1-scaled.jpg"></div>
<p>
Some text about the image
</p>
</li>
<!-- repeat the above list-item here -->
<li>
<div id="materials-01581" class="suarrmaterials-zoomable-image" style="height:400px; width:400px;" data-image="2013/02/DSC_0158-1-scaled.jpg"></div>
<p>
Some text about the image
</p>
</li>
<li>
<div id="materials-01581" class="suarrmaterials-zoomable-image" style="height:400px; width:400px;" data-image="2013/02/DSC_0158-1-scaled.jpg"></div>
<p>
Some text about the image
</p>
</li>
</ul>
<!-- .gallery --></section>

I've created 2 sets of examples, they both are a responsive layout. I would recommend settings a breakpoint when the layout 'breaks' and set them to 1 or 2 columns.
Images with the same exact aspect ratio.
Pro: texts under images will align with the others on the same row, even while scaling.
Con: images will be cut-off when the original image aspect ratio is to different from the wrapper aspect ratio which contains the image (landscape vs portrait for example).
Images with different aspect ratio's
Pro: images will keep their aspect ratio and won't be cut-off.
Con: texts under the images won't align with the others on the same row.
html,
body {
margin: 0;
padding: 0;
}
.gallery {
/* Negative margin = the padding of the wrapper. This ensures the boxes aligning against the left and right side of the container. Uncomment when this is not wanted. */
/*
margin-left: -1rem;
margin-right: -1rem;
*/
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: flex-start;
}
#media only screen and (max-width: 520px) {
.gallery {
flex-wrap: wrap;
}
}
/* Wrapper is needed to create extra space between gallery boxes in case a background color is needed. */
.gallery_image-wrapper {
padding: 1rem;
min-width: 8rem;
/* Don't Grow, Do Shrink, Base size of 33.33% */
flex: 0 1 33.33%;
#media only screen and (max-width: 520px) {
flex: 1 1 100%;
}
}
#media only screen and (max-width: 520px) {
.gallery_image-wrapper {
flex: 1 1 100%;
}
}
.gallery_image {}
.gallery_image-description {
word-wrap: break-word;
word-break: break-word;
}
.gallery_image-graphic {
margin: 0 0 1rem 0;
/* Add small spacing between image and description */
padding: 0 0 56.25% 0;
/* Ratio trick to make sure the images are the same size. */
background-size: cover;
/* Make sure the image is alway filling/covering the box */
background-repeat: no-repeat;
}
.gallery_image-graphic-inline {
max-width: 100%;
margin: 0 0 1rem 0;
display: block;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Gallery Test</title>
</head>
<body>
<h2>Example 1 - As background images</h2>
<div class="gallery">
<div class="gallery_image-wrapper">
<div class="gallery_image">
<div class="gallery_image-graphic" style="background-image: url('https://via.placeholder.com/750x500.png?text=Image%20Example');"></div>
<div class="gallery_image-description">A random text about the image.</div>
</div>
</div>
<div class="gallery_image-wrapper">
<div class="gallery_image">
<div class="gallery_image-graphic" style="background-image: url('https://via.placeholder.com/750x500.png?text=Image%20Example');"></div>
<div class="gallery_image-description">If the image contains relevant information</div>
</div>
</div>
<div class="gallery_image-wrapper">
<div class="gallery_image">
<div class="gallery_image-graphic" style="background-image: url('https://via.placeholder.com/750x500.png?text=Image%20Example');"></div>
<div class="gallery_image-description">make sure to add it to your description.</div>
</div>
</div>
</div>
<h2>Example 2 - Inline images</h2>
<div class="gallery">
<div class="gallery_image-wrapper">
<div class="gallery_image">
<img class="gallery_image-graphic-inline" src="https://via.placeholder.com/750x500.png?text=Image%20Example" />
<div class="gallery_image-description">Image example 1</div>
</div>
</div>
<div class="gallery_image-wrapper">
<div class="gallery_image">
<img class="gallery_image-graphic-inline" src="https://via.placeholder.com/750x600.png?text=Image%20Example" />
<div class="gallery_image-description">Image example 2</div>
</div>
</div>
<div class="gallery_image-wrapper">
<div class="gallery_image">
<img class="gallery_image-graphic-inline" src="https://via.placeholder.com/750x400.png?text=Image%20Example" />
<div class="gallery_image-description">Image example 3</div>
</div>
</div>
</div>
</body>
</html>
Update
Just in case it is a viewport meta issue, can you check if you have the following in your head?
<meta name="viewport" content="width=device-width, initial-scale=1">

Related

Changing the order of Columns when page loads from desktop to mobile responsive layout

In the below given layout,
When the width of page is lowered than 600px, I want to place Column2 above Column1
I tried using display: flex; flex-direction: column-reverse; but it instead of reversing the order of column it reversed the content order of the column.
Here is snippet.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
box-sizing: border-box;
}
/* Create two equal columns that floats next to each other */
.column {
float: left;
width: 50%;
padding: 10px;
height: 300px; /* Should be removed. Only for demonstration */
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
#media screen and (max-width: 600px) {
.column {
width: 100%;
/**Uncommenting below will lead to content of column reversed and not the order of column reversed**/
/*display: flex;
flex-direction: column-reverse;*/
}
}
</style>
</head>
<body>
<h2>Responsive Two Column Layout</h2>
<p>Resize the browser window to see the responsive effect (the columns will stack on top of each other instead of floating next to each other, when the screen is less than 600px wide).</p>
<div class="row" style="height: 20px; background-color: red;">
</div>
<div class="row" style="height: 20px; background-color: blue;">
</div>
<div class="row">
<div class="column" style="background-color:#aaa;">
<div class="cls1">
<h2>Column 1</h2>
<p>Some text..</p>
</div>
<div class="cls2">
<h2>Column 1.2</h2>
<p>Some text..</p>
</div>
<div class="cls3">
<h2>Column 1.3</h2>
<p>Some text..</p>
</div>
</div>
<div class="column" style="background-color:#bbb;">
<h2>Column 2</h2>
<p>Some text..</p>
</div>
</div>
</body>
</html>
Any help will be appreciative.
You tried adding display:flex to the column - which made the column a flex container and elements inside of it his flex items. That's why you were reversing content inside the columns and not the columns themselves. You want to instead control columns inside the row. To do that, you need to make the row your flex container (apply display:flex to the row instead of the column). Here is a working CSS for your case:
.row {
display: flex; // makes the row a flex container
}
#media screen and (max-width: 600px) {
.row {
flex-direction: column-reverse;
}
}
.column {
flex-grow: 1; // makes all columns fill the width of the row equally
padding: 0 10px;
}
Here is the correct implementation with working example based on Accepted answer of #ajobi:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
box-sizing: border-box;
}
/* Create two equal columns that floats next to each other */
.column {
float: left;
width: 50%;
padding: 10px;
height: 300px; /* Should be removed. Only for demonstration */
}
.row {
display: flex; // makes the row a flex container
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
#media screen and (max-width: 600px) {
.row {
flex-direction: column-reverse;
}
.column {
width: 100%;
/**Uncommenting below will lead to content of column reversed and not the order of column reversed**/
/*display: flex;
flex-direction: column-reverse;*/
}
}
</style>
</head>
<body>
<h2>Responsive Two Column Layout</h2>
<p>Resize the browser window to see the responsive effect (the columns will stack on top of each other instead of floating next to each other, when the screen is less than 600px wide).</p>
<div class="row" style="height: 20px; background-color: red;">
</div>
<div class="row" style="height: 20px; background-color: blue;">
</div>
<div class="row">
<div class="column" style="background-color:#aaa;">
<div class="cls1">
<h2>Column 1</h2>
<p>Some text..</p>
</div>
<div class="cls2">
<h2>Column 1.2</h2>
<p>Some text..</p>
</div>
<div class="cls3">
<h2>Column 1.3</h2>
<p>Some text..</p>
</div>
</div>
<div class="column" style="background-color:#bbb;">
<h2>Column 2</h2>
<p>Some text..</p>
</div>
</div>
</body>
</html>

Centered grid of dynamic cards (divs) with more block elements inside

I want a dynamically generated grid of fixed size cards to be horizontally centered in a container of variable width, basically this: https://foodgawker.com/
My question is similar to Center a grid of Divs (dynamically generated) or How to center a grid of divs? (the example is from there), except they both recomend using display: inline-block instead of float : left, which only works as long as there are no further block elements inside the cards.
Here is the example from the previous question with one block element added inside the card, the whole layout breaks: http://jsbin.com/vozusukigo/1/edit?html,css,output. Also the foodgawker.com uses float : left, not display: inline-block.
Here is a JS Bin for your convenience, I am grateful for any help.
EDIT: The last row should aligned to left as in the example. To my horror the accepted answer to similar question uses JQuery (and none of the flexbox answers have fixed size gaps).
These kinda solutions especially are made easy now thanks to the Flexbox concept in CSS3.
https://jsbin.com/vetanocaxi/1/edit?html,css,output
Having the same HTML, the CSS can be written as below
.ct {
background-color : #ffff00;
display: flex;
justify-content: flex-start; /* center if you want to the center */
align-items: center;
flex-wrap: wrap;
}
.el {
width : 50px;
height : 50px;
background-color : #ff9999;
margin : 5px;
display: flex;
justify-content: center; /* center inside flex items */
align-items: center; /* center inside flex items */
}
No floats required & even better you can easily have complex structure within individual flex items without effecting the outer layout structure.
.ct {
background-color : #ffff00;
display: flex;
justify-content: flex-start; /* center if you want to the center */
align-items: center;
flex-wrap: wrap;
}
.el {
width : 50px;
height : 50px;
background-color : #ff9999;
margin : 5px;
display: flex;
justify-content: center; /* center inside flex items */
align-items: center; /* center inside flex items */
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="ct">
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
<div class="el"><p>flex</p></div>
</div>
</body>
</html>
Flexbox can be used to achieve this effect like this: http://jsbin.com/vunubuqobo/edit?html,css,output
Main assumption is a fixed width for all cards. A small nuisance is a bunch of media queries to set .center_wrapper's width right, but that is easy to overcome with Less/SCSS/etc.
Note: use jsbin link above to check out responsiveness.
.cards_wrapper {
background: red;
}
#media(min-width: 122px) {
.center_wrapper { width: 122px; }
}
#media(min-width: 296px) {
.center_wrapper { width: 244px; }
}
#media(min-width: 416px) {
.center_wrapper { width: 366px; }
}
#media(min-width: 524px) {
.center_wrapper { width: 488px; }
}
#media(min-width: 646px) {
.center_wrapper { width: 610px; }
}
.center_wrapper {
display: flex;
flex-wrap: wrap;
padding: 10px;
margin: 0 auto;
background: yellow;
}
.card {
height: 100px;
width: 100px;
border: 1px solid;
margin: 10px;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<div class="cards_wrapper">
<div class="center_wrapper">
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<p>block element</p>
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
<div class="card">
<img src="./Index - My ASP.NET MVC Application_files/noImageAvailable.png">
</div>
</div>
</div>
</body>
</html>
To be honest I can't see any problem by using display: inline-block and have block elements inside the repeating divs. Also aligning the last row to the left is simple and doesn't require a single line of JavaScript or any complex workarounds.
According to the link you have posted you could achieve the layout with the following HTML structure and CSS code
body {
background: #eee;
}
#wrapper {
font-size: 0;
padding: 10px 0;
}
.item {
width: calc(25% - 4px);
background: white;
overflow: hidden;
border-radius: 3px;
display: inline-block;
font-size: initial;
margin: 2px;
}
p {
padding: 4px 20px;
}
img {
width: 100%;
}
<div id="wrapper">
<div class="item">
<img src="https://photo.foodgawker.com/wp-content/uploads/2016/12/2845923.jpg" alt="" />
<p>All the nutty deliciousness of pecan pies - these no bake Rice Krispie Pecan Pie Cookies are vegan-friendly & dairy-free friendly!</p>
</div>
<div class="item">
<img src="https://photo2.foodgawker.com/wp-content/uploads/2016/12/2845735.jpg" alt="" />
<p>This Barbecue Chicken Cornbread Casserole is an easy dinner that comes together in just 15 minutes!!</p>
</div>
<div class="item">
<img src="https://photo.foodgawker.com/wp-content/uploads/2016/12/2845542.jpg" alt="" />
<p>Vegan Meringue Kisses, made using aquafaba</p>
</div>
<div class="item">
<img src="https://photo2.foodgawker.com/wp-content/uploads/2016/12/2845725.jpg" alt="" />
<p>Healthy spicy creole pulled pork made in the slow cooker! {Gluten Free, Dairy Free, Paleo}</p>
</div>
<div class="item">
<img src="https://photo.foodgawker.com/wp-content/uploads/2016/12/2845855.jpg" alt="" />
<p>Praline chocolates with a crispy dark chocolate coating and a soft caramelized nuts filling. Chocolatey, nutty and insanely delicious!</p>
</div>
</div>

Stretching an image inside a flex item to full width

I am playing around with CSS Flexbox and media queries and I stumbled across this issue. Considering the following code of mine, I can't get the last image in the last div item in the flex container to stretch to full width though I set the div item width to 100%. How can I achieve this? Here is my code:
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Playing with CSS Flexbox</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="layoutstyle.css" rel="stylesheet" type="text/css">
</head>
<body>
<header>
<nav>
<div class="logo">
</div>
<ul>
<li>
</li>
</ul>
</nav>
</header>
<main id="container">
<div class="featured">
</div>
<div class="flexbox col-1">
<img src=images/singapore-small.jpg alt=""
sizes="(min-width: 650px) 70vw, 100w"
srcset="images/singapore-x-small.jpg 400w,
images/singapore-small.jpg 600w,
images/singapore-medium.jpg 800w,
images/singapore-large.jpg 1000w,
images/singapore-x-large.jpg 1500w
"
/>
</div>
<div class="flexbox col-2">
<img src=images/skyscrapers-small.jpg alt=""
sizes="(min-width: 650px) 70vw, 100w"
srcset="images/skyscrapers-x-small.jpg 400w,
images/skyscrapers-small.jpg 600w,
images/skyscrapers-medium.jpg 800w,
images/skyscrapers-large.jpg 1000w,
images/skyscrapers-x-large.jpg 1500w
"
/>
</div>
<div class="flexbox col-3">
<img src=images/sunset-small.jpg alt=""
sizes="(min-width: 650px) 70vw, 100w"
srcset="images/sunset-x-small.jpg 400w,
images/sunset-small.jpg 600w,
images/sunset-medium.jpg 800w,
images/sunset-large.jpg 1000w,
images/sunset-x-large.jpg 1500w
"
/>
</div>
</main>
</body>
</html>
////////CSS//////
* {
box-sizing: border-box;
}
body,html {
width: 100%;
height: 100%;
}
body {
margin: 0;
}
li {
padding: 0;
list-style-type: none;
}
header {
display: flex;
}
main {
display: flex;
flex-flow: row wrap;
justify-content: center;
width: 100%;
}
#media all and (max-width: 650px) {
.flexbox {
width: 100%;
}
}
#media all and (min-width: 651px) {
.col-1, .col-2 {
width: 50%;
}
.col-3 {
width: 100%;
}
}
Add this to your CSS to maximize your images:
.flexbox img {
width: 100%;
height: auto;
}
Demo at CodePen
If older browser compatibility isn't an issue, using just flex-box properties can achieve this. So regardless of the number of flex-items in the container, last odd-item always stretches.
flex-grow: unitless value;
Tells flex item how much space inside the flex container it should take if necessary (in proportion to others.)
If all items have flex-grow set to 1, the remaining space in the container will be distributed equally to all children. If one of the children a value of 2, the remaining space would take up twice as much space as the others (or it will try to, at least). source & more details: css-tricks.com
Following is the basic idea,
#container {
display: -webkit-box; /* OLD - iOS 6-, Safari */
display: flex;
flex-wrap:wrap;
}
.flexbox {
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari */
flex-basis: 50%;
flex-grow: 2;
}
.flexbox img {width: 100%;}
CodePen Example

Stretch div to bottom of screensize, but allow scrolldown

On load I'd like to load the topsection div with a bg image and have it take up the entire screen, but then I have content below it which you can scroll down to. The div should size itself to the window screen only on load and not remain like that on scrolldown. I cannot give the div a position:absolute; either.
I'm banging my head on this one. I've tried a ton of different things
Here is my html:
<div id="topsection" class="row bgimage ">
<div id="logomain" class="mainlogo ">
<div class=" floorplanbuttoncontainer helvetical">
<ul>
<li>Residence A - Duplex</li>
<li>
Residence D - Simplex</li>
</ul>
</div><!-- end floorplanbuttoncontainer -->
</div><!-- end logomain -->
Here is my css for the background image:
.bgimage {
background: url(images/image.jpg) no-repeat center center fixed;
background-size: cover;
.mainlogo {
margin:0 auto;text-align:center;width:100%;height:488px; /*I think this height is messing things up */
background-image:url(images/picture.png);background-repeat:no-repeat;
background-position: center;
}
In order to set a div to take up the entire screen you need to set the height of the body and html element to 100%. You also have to remove the padding and margin from them. Then you create a wrapper class to encase your content and assign it your background-image. Then all ya' gotta do is create the content below your full screen image to scroll into!
Fiddle
Edit
If you run the snippet below and hit full page you can see how it works.
body, html {
height: 100%;
margin: 0;
padding: 0;
}
.wrapper {
min-height: 100%;
background: red;
}
.full {
width: 100%;
}
.footerThing {
width: 100%;
height: 200px;
background: blue;
}
<div class="wrapper">
<div class="full">
asd
</div>
</div>
<div class="footerThing">
</div>
Modern browsers: a simple way is to use vh units to get the Viewport Height
Just to simplify: jsBin demo
<div id="home" class="container full">
<h1>HOME</h1>
</div>
<div id="about" class="container">
<h1>About us</h1>
<p>Content</p>
</div>
CSS:
.container { min-height:400px; }
.full { height:100vh; }
Crossbrowser: use % instead of vh and simply add html, body{height:100%;} jsBin demo

How to get right sidebar up on main content on resize of flexible with page?

I have page with main content and right sidebar. But I want to have sidebar before main content block on page resize. How can I accomplish this?
HTML part:
<div id="header">
<div id="logo"></div>
</div>
<div id="container">
<div id="content">
main content
</div>
<div id="sidebar">
sidebar
</div>
</div>
<div id="footer">
footer
</div>
CSS part:
#container {
clear: both;
overflow: auto;
}
#content {
clear:both;
width: 70%;
float: left;
padding: 2% 0;
margin-right: 2%;
}
#sidebar {
width: 28%;
float: right;
padding: 2% 0;
}
In your media query float your #sidebar left and your #content right.
Because you are trying to do responsive design, what you want to do is media query in your CSS that will allow you to style the changes you want to make. The first decision you have to make is which screen sizes you want to display the responsive design. Tablets usually have a max-width of 760px and phones are around max-width of 480px. So the media query will look something like this:
CSS:
#media screen and (max-width: 480px){
...all your mobile styles are in here...
}
Now to answer the positioning issues you have. Of course there are several ways, the way I would do it is this is to move your sidebar above the content in the HTML, remove the clear from the content CSS, and inside the media query all you have to do is make the width for both divs 100%.
HTML:
<div id="header">
<div id="logo">The logo</div>
</div>
<div id="container">
<div id="sidebar">
sidebar
</div>
<div id="content">
main content
</div>
</div>
<div id="footer">
footer
</div>
CSS:
#container {
clear: both;
overflow: auto;
}
#content {
float:left;
width: 50%;
background:grey;
}
#sidebar {
width: 25%;
float:right;
background:lightgrey;
}
#media screen and (max-width:480px){
#sidebar {
width:100%;
}
#content {
width:100%;
}
}

Resources