Stretching an image inside a flex item to full width - css

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

Related

Whats the reason for flex-wrap not to work?

I've looked at other questions on this website and none of them were similar to my problem, applying flex-direction:row; didnt help, applying all kinds of width's (min-width, max-width) didn't help as well.
Am I using wrong units for styling the items in container?
My goal is for the content to wrap in a new row.
HTML and CSS:
body {
margin: 0;
padding: 0;
background-color: #eeeeee;
}
h1, h5 {
padding: 10px;
margin: 0;
}
.pre-header {
text-align: center;
}
#header-content1-1 {
font-size: 1.15em;
margin: 0;
padding: 0;
}
hr {
margin-top: 20px;
margin-bottom: 3px;
}
.container {
display: flex;
background-color: cornflowerblue;
justify-content:space-between;
max-width: 80%;
margin: auto;
align-items: center;
height: 40vh;
flex-wrap: wrap;
}
.flex-item {
background-color: red;
line-height: 9vh;
width: 13%;
text-align:center;
flex-shrink: 3;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Find out who was Avicii!">
<link rel="stylesheet" href="style.css">
<title>David</title>
</head>
<body>
<header>
<div class="pre-header">
<h1 id="header-content1">Avicii - Tim Bergling</h1>
<h5 id="header-content1-1">Swedish DJ, remixer, record producer, musician, and songwriter</h5>
</div>
</header>
<main>
<hr>
<div class="container">
<div class="flex-item">E</div>
<div class="flex-item">R</div>
<div class="flex-item">I</div>
<div class="flex-item">N</div>
<div class="flex-item">N</div>
<div class="flex-item">N</div>
<div class="flex-item">N</div>
</div>
</main>
<footer>
</footer>
</body>
</html>
One suggested way as mentioned in comments is having an appropriate width (in your case 22%) so it sums up to 100% some items show up in the next row. One can add margin (like margin: 0% 5%) too to add to the width.
There is one way to do that manually, but you will have to add something similar to breaks in your HTML code. Here is a solution inspired by this.
<div class="container">
<div class="flex-item">E</div>
<div class="flex-item">R</div>
<div class="flex-item">I</div>
<div class="flex-item">N</div>
<div class="flex-item">N</div>
<div class="flex-item break"></div>
<div class="flex-item f2">N</div>
<div class="flex-item f2">N</div>
</div>
.break {
flex-basis: 100%;
height: 0;
}
This uses flex-basis.
Have a look at this codepen for demo.
There is also the option to have add one more level of divs inside your container divs as parents to your flex-item. But overall I would suggest to use the dynamic width and not use these methods as they will only add complexity when your number of boxes are dynamic and will probably require some Js too.

Creating responsive 3 x 3 gallery box

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">

An arbibrary hight on header + rest of the height on container [duplicate]

This question already has answers here:
Make a div fill the height of the remaining screen space
(41 answers)
Fill remaining vertical space with CSS using display:flex
(6 answers)
Closed 4 years ago.
I want to achieve the following behavior like in the image
So, I have a header with an arbitrary height and I want the container to fill the rest of the space. I have the following code:
<body>
<div class="header">
My header<br> Arbitrary height (ex: 123px)
</div>
<div class="container">
Container <br> Height = rest of the viewport
</div>
</body>
Note: I don't want to use .container{ height: calc(100% - 123px) } because the in the future 123px may change, so I don't want to modify in two places.
You can use flexbox for this:
html {
height: 100%;
}
body {
min-height: 100%;
margin: 0;
display: flex;
flex-direction: column;
}
.header {
height: 123px; /* whatever height you want */
background:green;
}
.container {
flex-grow: 1;
background:beige;
}
<div class="header"></div>
<div class="container"></div>
See following example:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
html,
body {
height: 100%;
}
body {
min-height: 100%;
display: flex;
flex-direction: column;
padding:0;
margin:0;
}
.container {
flex: 1;
overflow:auto;
padding:10px;
}
.header {
background-color:green;
}
</style>
</head>
<body>
<div class="header">
<p>My header<br> Arbitrary height (ex: 123px)</p>
<p>My header<br> Arbitrary height (ex: 123px)</p>
</div>
<div class="container">
Container <br> Height = rest of the viewport
</div>
</body>
</html>

Photowall with double sized highlight pictures

We are working on a picture gallery site and can't find a solution for following problem.
The picture wall contains several images. Some image (n Percent) should by highlighted and get displayed double sized on the wall.
The issue is, that I have no idea to fill the empty space left of the large picture, because its a new line.
Any ideas.
I created a fiddle for this sample here: Fiddle
<body>
<div class="size1">
</div>
<div class="size1">
</div>
<div class="size2">
</div>
<div class="size1">
</div>
<div class="size1">
</div>
<div class="size1">
</div>
<div class="size1">
</div>
<div class="size1">
</div>
<div class="size1">
</div>
<div class="size1">
</div>
<div class="size1">
</div>
<div class="size1">
</div>
<div class="size1">
</div>
<div class="size1">
</div>
</body>
div {
background-color: #f00;
float: left;
}
.size1{
width: 100px;
height: 100px;
margin: 5px;
}
.size2{
width: 210px;
height: 210px;
margin: 5px;
}
Update:
The following browsers now natively support CSS Grid Layout.
Firefox v52
Chrome v57 for Linux, macOS, Windows, iOS, and Android
Safari v10.1
iOS Safari v10.3
Opera v44
This kind of layout requirement is what the CSS Grid Layout spec aims to address. The introduction to the spec reads:
Grid Layout is a new layout model for CSS that has powerful abilities to control the sizing and positioning of boxes and their contents. Unlike Flexible Box Layout, which is single-axis–oriented, Grid Layout is optimized for 2-dimensional layouts: those in which alignment of content is desired in both dimensions.
Native browser support for CSS Grid Layout is likely to start landing in major browsers soon (as shown here) and is currently featured behind a flag in some. For non-supporting browsers this JavaScript polyfill will be necessary.
As an example, CSS Grid Layout syntax is shown in the following CSS:
HTML
<div class="wrapper">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box box--double">5</div>
<div class="box">7</div>
<div class="box">8</div>
...
</div>
</div>
CSS using the Grid layout model
.wrapper {
width: 600px;
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(7, 100px);
grid-template-rows: 100px 100px 100px;
grid-auto-flow: row;
}
.box {
background-color: #444;
color: #fff;
padding: 20px;
font-size: 150%;
margin: 5px;
}
.box--double {
background-color: red;
grid-column: 3 / span 2;
grid-row: 2 / span 2;
}
DEMO
Here is a fiddle which utilizes CSS Grid Layout syntax (inc. the polyfill) to provide a general gist.
Alternatively, Masonry may be able to achieve this, however long term this will always be dependent on JavaScript.
Responsive Web Design (RWD)
The CSS Grid Layout module includes several features to simplify the creation of responsive designs. Two pertinent features which address the issues raised in the comments are:
1 Flexible Lengths
The fr unit should be used instead of specifying the relative column width as a percentage. The main benefit of the fr unit is that it avoids having to manually recalculate the percentage when the number of columns change via a media query - (You simply change the value for the number of columns only):
/* Avoid using percentages like this */
.wrapper {
grid-template-columns: repeat(7, 14.286%);
...
}
/* Use the 'fr' unit instead */
.wrapper {
grid-template-columns: repeat(7, 1fr);
...
}
2 grid-auto-flow-dense
Three values that can be assigned to the grid-auto-flow property, namely row, column, and dense.
.wrapper {
grid-auto-flow: dense;
...
}
In some situations when row, or column values are used it can produce unwanted holes/gaps in the layout. When specifying dense an algorithm attempts to fill those holes/gaps in, however this can sometimes change the the order of the items. This feature is very similar to the way Masonry places items in a different position based on available vertical space.
DEMO FOR RWD
Here is a responsive fiddle that uses both the fr unit and the dense value to avoid any gaps/holes in the layout.
EDIT(5): Updated list of browsers supporting CSS Grid Layout.
EDIT(4): Added note regarding Chrome 57 implementing CSS Grid Layout spec.
EDIT(3): Added note regarding Firefox 52 implementing CSS Grid Layout spec.
EDIT(2): Add useful CSS Grid Layout features for achieving RWD
EDIT(1): Changed sample code to terse version and updated link to external fiddle
Here's a CSS only solution, fully responsive, based on CSS columns
.columns >div {
background-color: #f00;
float: left;
-webkit-column-break-inside: avoid;
page-break-inside: avoid;
break-inside: avoid;
}
.size1{
width: 100px;
height: 100px;
margin: 5px;
}
.size2{
width: 210px;
height: 210px;
margin: 5px;
}
.columns {
width: 660px;
margin: 0 auto;
-webkit-columns: 200px 3;
-moz-columns: 200px 3;
columns: 200px 3;
-webkit-column-gap: 0;
-moz-column-gap: 0;
column-gap: 0;
}
#media (max-width: 689px) {
.columns {
width: 440px;
margin: 0 auto;
-webkit-columns: 200px 2;
-moz-columns: 200px 2;
columns: 200px 2;
}
}
#media (max-width: 459px) {
.columns {
display: flex;
flex-wrap: wrap;
max-width: 220px;
}
.columns div {
flex: 1 0 auto;
}
.columns .size1 {
flex-basis: calc(50% - 10px)
}
.columns .size2 {
flex-basis: calc(100% - 10px)
}
}
body {
padding: 0;
text-align: center;
}
#media (min-width: 920px) { /* 4 columns */
.columns {
width: 880px;
-webkit-columns: 200px 4;
-moz-columns: 200px 4;
columns: 200px 4;
}
}
#media (min-width: 1140px) { /* 5 columns */
.columns {
width: 1100px;
-webkit-columns: 200px 5;
-moz-columns: 200px 5;
columns: 200px 5;
}
}
#media (min-width: 1360px) { /* 6 columns */
.columns {
width: 1320px;
-webkit-columns: 200px 6;
-moz-columns: 200px 6;
columns: 200px 6;
}
}
#media (min-width: 1580px) {
/* respect the principle above to add as many columns as you like */
}
<div class="columns">
<div class="size2"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size2"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size2"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size2"></div>
<div class="size1"></div>
<div class="size1"></div>
</div>
For mobiles media query interval, I used flexbox, but it's just to show it's possible. You really don't have to, you can stick to box-model.
Note: You can define further media intervals. The basic idea is to have a multiple of 220px and limit it to widths that have sufficient room for all columns.
Here's the fiddle (I added it as, for some reason, SO won't allow me to resize the snippet window under ~480px, while jsFiddle does.)
fiddle here
This solution assumes you will always pair 2 small items together (so they occupy 1 row). If you want a solution where this condition doesn't have to be met by whoever adds content, and automatically tries to pair small items when they are single, you need javascript.
Timeline solution (based on comments info)
I'm guessing this is what you need? (If you decide to change classnames, you'll need to adjust both js and CSS).
$('.timeline .size2').each(function(){
//moving required number of small'uns so they fill the column
var prevIndex = $(this).prevAll('.size2,.wrap').eq(0).index(),
diff = $(this).index() - (prevIndex + 1),
toMove = (3 - (diff % 3)) %3;
if (toMove) {
for (var i = 1; i < toMove + 1; i++) {
$(this).nextAll('.size1').eq(0).addClass('moved').insertBefore($(this))
}
}
var wrap = $('<div />', {
class:'wrap'
})
//wrap 2 small'uns to make a row under a big'un
for (var i = 0; i < 2; i++) {
wrap.append($(this).nextAll('.size1').eq(0));
}
wrap.insertAfter($(this));
})
.timeline [class^="size"] {
background-color: red;
}
.size1{
width: 100px;
height: 100px;
margin: 5px;
}
.size2{
width: 210px;
height: 210px;
margin: 5px;
}
.timeline {
display: flex;
flex-direction: column;
align-content: flex-start;
height: 330px;
flex-wrap: wrap;
}
.timeline .wrap {
display: inline-flex;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="timeline">
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size2"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size2"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size2"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size1"></div>
<div class="size2"></div>
<div class="size1"></div>
<div class="size1"></div>
</div>
I tried to shorten the fiddle from RobC and replaced the fixed width in pixels with relative width in percent. So it is a little more responsive. But still have some gaps which you may prevent with some rules, like "no 2 big boxes side by side" and so on.
The Html
<div class="wrapper">
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/600x400/f33/fff" class="box--double" />
<img src="https://dummyimage.com/600x400/f33/fff" class="box--double" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/600x400/f33/fff" class="box--double" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/600x400/f33/fff" class="box--double" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/600x400/f33/fff" class="box--double" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
<img src="https://dummyimage.com/300x200/333/fff" class="" />
</div>
The CSS
.wrapper {
width: 100%;
display: grid;
grid-template-columns: repeat(6, 16.666%);
grid-auto-flow: row;
}
#media screen and (max-width: 940px) {
.wrapper {
grid-template-columns: repeat(5, 20%);
}
}
#media screen and (max-width: 540px) {
.wrapper {
grid-template-columns: repeat(3, 33.333%);
}
}
.wrapper > img {
background-color: #444;
color: #fff;
border: solid 1px white;
}
.box::before {
content: ' ';
display: block;
padding-top: 100%;
}
.box--double {
background-color: red;
grid-column: auto / span 2;
grid-row: auto / span 2;
}
The fiddle

AngularJS: Two-column odd/even layout

Having a problem trying to get a repeating two-column layout in AngularJS. My dataset is a JSON object of image information. I want to show a two column layout of images. No matter what I tweak, something is wrong in my odd/even logic, but I can't seem to figure it out. What am I doing wrong?
.left {
float: left !important;
width: 50% !important;
}
.right {
float: right !important;
width: 50% !important;
}
.group:after {
content:"";
display: table;
clear: both;
}
img {
max-width: 100%;
height: auto;
}
#media screen and (max-width: 480px) {
.left,
.right {
float: none;
width: auto;
}
}
<div ng-repeat="issue in issues">
<div ng-if="$even" class="group">
<div class="left" ng-if="$even">
<img src="{{ issue.image }}" ng-src="{{ issue.image }}">
</div>
<div class="right" ng-if="$odd">
<img src="{{ issue.image }}" ng-src="{{ issue.image }}">
</div>
</div>
</div>
The issue with code is you had wrap your logic inside
<div ng-if="$even" class="group">
Div which is restricting to show odd logic div.
instead of having two different div, I'd say use ngClassEven & ngClassOdd directive. Also remove the wrapper div which has ng-if="$even" condition.
<div ng-repeat="issue in issues">
<div ng-class-even="'left'" ng-class-odd="'right'">
<img ng-src="{{ issue.image }}">
</div>
</div>
I guess you already got your answer, but still here are some alternatives which may prove useful:
Simply ng-class - it's a little more flexible, so you may find it useful in other cases too. In this case:
<div ng-repeat="issue in issues" ng-class="{left: $even, right: $odd}">
<img ng-src="{{ issue.image }}">
</div>
or
<div ng-repeat="issue in issues" ng-class="$even ? 'left' : 'right'">
<img ng-src="{{ issue.image }}">
</div>
Note that unlike some other properties ng-class can coexist with class in harmony so you could also add class="item" or something similar.
Since it's a styling issue you may want to try to solve it in css. As long as you think IE 6-8 should die you can use the nth-child selector:
:nth-child(odd) { ... }
:nth-child(event) { ... }
Also since both my and Pankaj's answers removed your group class here is some simpler css which you could use instead:
.item {
float: left;
width: 50%;
}
.left {
clear: left;
}
#media screen and (max-width: 480px) {
.item {
float: none;
width: auto;
}
}
Or again if you're not all about IE you could use flexbox (which removes the need for any JS):
.parent {
display: flex;
flex-wrap: wrap;
}
.item {
flex: 0 0 50%;
}
#media screen and (max-width: 480px) {
.item {
flex-basis: 100%;
}
}

Resources