Reputation: 195
I'm trying to build a gallery in form of a masonry, but I can't get my head around wrapping of flexboxes?
I got a simple UL list and I've added the style needed, but things are not floating and wrapping as it should.
.masonry {
margin: 48px -2px;
padding-left: 0;
list-style: none;
align-items: flex-start;
flex-direction: row;
flex-wrap: wrap;
display: flex;
}
.masonry li {
height: 300px;
flex-basis: calc(33.33% - 4px);
margin: 2px;
text-align: center;
display: flex;
background-color: #C9F4FF;
}
.masonry li:nth-child(1), .masonry li:nth-child(7) {
height: 604px;
background-color: #FFB4FF;
}
.masonry li:nth-child(4), .masonry li:nth-child(4) {
flex-basis: calc(66.66% - 4px);
background-color: #B9EDA8;
}
<!-- masonry starts -->
<ul class="masonry">
<li> </li>
<li> </li>
<li> </li>
<li> </li>
<li> </li>
<li> </li>
<li> </li>
<li> </li>
</ul>
<!-- masonry ends -->
The result looks like this, which is kinda funny :)
Maybe someone knows how to write the correct CSS to make things wrap correctly?
Upvotes: 4
Views: 9271
Reputation: 195
I've created a quick image gallery from the help I got and have to say it was as simple and neat as I wanted it.
body {
padding: 48px;
font-family: Helvetica, Arial, sans-serif;
}
.masonry {
margin: -2px;
padding-left: 0;
list-style: none;
align-items: flex-start;
flex-direction: row;
flex-wrap: wrap;
display: flex
}
.masonry li {
flex-basis: calc(100% / 3);
position: relative;
height: 300px;
display: flex
}
@media (max-width: 1199.98px) {
.masonry li {
height: 250px
}
}
@media (max-width: 991.98px) {
.masonry li {
height: 200px
}
}
@media (max-width: 767.98px) {
.masonry li {
flex-basis: calc(100% / 2) !important;
height: 160px !important
}
}
.masonry li:nth-child(1) a, .masonry li:nth-child(7) a {
width: calc(100% - 2px);
height: calc(200% - 2px);
position: absolute;
left: 0;
top: 0
}
.masonry li:nth-child(4), .masonry li:nth-child(8) {
flex-basis: 100%
}
.masonry li:nth-child(4) a {
margin-left: calc((100% / 3) + 1px)
}
.masonry li:nth-child(8) a {
margin-right: calc((100% / 3) + 1px)
}
.masonry a {
margin: 1px;
text-align: center;
text-decoration: none;
position: relative;
color: #fff;
display: flex;
flex: 1
}
@media (max-width: 767.98px) {
.masonry a {
width: auto !important;
height: auto !important;
margin: 1px !important;
position: relative !important
}
}
.masonry a:hover {
text-decoration: none
}
.masonry a:hover img {
transform: scale(1.04);
opacity: 1
}
.masonry img {
transition: opacity .2s, transform .3s;
opacity: .5
}
.masonry-image {
width: 100%;
height: 100%;
overflow: hidden;
background-color: #000;
position: absolute;
z-index: 1;
left: 0;
right: 0;
top: 0;
bottom: 0
}
.masonry-caption {
width: 100%;
min-width: 0;
padding: 24px;
align-items: center;
justify-content: center;
position: relative;
flex-direction: column;
flex-wrap: nowrap;
overflow: hidden;
display: flex;
z-index: 2
}
@media (max-width: 575.98px) {
.masonry-caption {
padding: 0
}
}
.masonry-caption:hover strong, .masonry-caption:hover span {
transition: background-color .4s ease-in-out;
background-color: #000
}
.masonry-caption strong, .masonry-caption span {
padding: 4px 8px;
transition: background-color .15s ease-in-out
}
.masonry-caption strong {
margin-bottom: 8px;
font-family: "opensans-semibold";
font-size: 1.625rem
}
@media (max-width: 991.98px) {
.masonry-caption strong {
font-size: 1.4rem
}
}
@media (max-width: 767.98px) {
.masonry-caption strong {
margin: 0;
font-size: 1.1rem;
background-color: transparent !important
}
}
@media (max-width: 991.98px) {
.masonry-caption span {
font-size: .938rem
}
}
@media (max-width: 767.98px) {
.masonry-caption span {
font-size: .875rem;
background-color: transparent !important
}
}
.cover {
width: 100%;
max-width: 100%;
height: inherit;
object-position: 50% 50%;
object-fit: cover;
}
<!-- masonry starts -->
<ul class="masonry">
<li>
<a href="" class="masonry-holder" title="">
<div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
<div class="masonry-image"><img src="https://farm6.staticflickr.com/5594/15041847508_8e9ef380f9_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
</a>
</li>
<li>
<a href="" class="masonry-holder" title="">
<div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
<div class="masonry-image"><img src="https://farm6.staticflickr.com/5559/15225339791_f01c6697b6_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
</a>
</li>
<li>
<a href="" class="masonry-holder" title="">
<div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
<div class="masonry-image"><img src="https://farm4.staticflickr.com/3914/15041657969_ac472610cb_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
</a>
</li>
<li>
<a href="" class="masonry-holder" title="">
<div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
<div class="masonry-image"><img src="https://farm6.staticflickr.com/5564/15041850517_00f9b6667f_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
</a>
</li>
<li>
<a href="" class="masonry-holder" title="">
<div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
<div class="masonry-image"><img src="https://farm6.staticflickr.com/5591/15041649519_f9862e81c9_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
</a>
</li>
<li>
<a href="" class="masonry-holder" title="">
<div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
<div class="masonry-image"><img src="https://farm6.staticflickr.com/5596/15228427075_a56b625397_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
</a>
</li>
<li>
<a href="" class="masonry-holder" title="">
<div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
<div class="masonry-image"><img src="https://farm4.staticflickr.com/3917/15228055382_58c02657b8_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
</a>
</li>
<li>
<a href="" class="masonry-holder" title="">
<div class="masonry-caption"><strong>Image title</strong><span>label</span></div>
<div class="masonry-image"><img src="https://farm6.staticflickr.com/5553/15228056972_9b780d2891_z.jpg" rel="noindex" class="cover" width="360" height="240" alt=""></div>
</a>
</li>
</ul>
<!-- masonry ends -->
Here's a responsive masonry grid made with flexbox, if someone else need a bit inspiration for their work.
Upvotes: 5
Reputation: 87303
Flexbox can't do that with its own layout capabilities, it needs some help, so here is a CSS solution that assume the size of the items is given.
The main trick here is to add an extra element inside the li
and make that the "styled" one, and use the li
for the main layout.
The "light green" items gets a left/right margin, to push them accordingly, and with that make space for the "light purple".
Since a flex item (here the li
) can't dynamically grow both vertical and horizontal, we instead use its inner div
to take twice the height, and with that enable the requested layout.
This setup, combined with Flexbox's order
property, will now make it very simply to adjust its layout using e.g. media query for a portrait layout (vertically stacked) etc.
Note, to make this all dynamically sized by its content, either a script or CSS Grid will be needed.
Here is a great post shedding some light (and more solutions) on Masonry:
Stack snippet
.masonry {
margin: 48px -2px;
padding-left: 0;
list-style: none;
align-items: flex-start;
flex-wrap: wrap;
display: flex;
}
.masonry li {
flex-basis: calc(100% / 3);
height: 200px;
display: flex;
}
.masonry li div {
display: relative;
flex: 1;
margin: 2px;
text-align: center;
display: flex;
background-color: #C9F4FF;
}
.masonry li:nth-child(1) div,
.masonry li:nth-child(7) div {
display: absolute;
left: 0;
top: 0;
width: 100%;
height: calc(200% - 4px); /* twice the height */
background-color: #FFB4FF;
}
.masonry li:nth-child(4),
.masonry li:nth-child(8) {
flex-basis: 100%; /* 100% width to force wrap */
}
.masonry li:nth-child(4) div,
.masonry li:nth-child(8) div {
background-color: #B9EDA8;
}
.masonry li:nth-child(4) div {
margin-left: calc((100% / 3) + 2px); /* pushed to left */
}
.masonry li:nth-child(8) div {
margin-right: calc((100% / 3) + 2px); /* pushed to right */
}
<!-- masonry starts -->
<ul class="masonry">
<li><div> </div></li>
<li><div> </div></li>
<li><div> </div></li>
<li><div> </div></li>
<li><div> </div></li>
<li><div> </div></li>
<li><div> </div></li>
<li><div> </div></li>
</ul>
<!-- masonry ends -->
Upvotes: 4
Reputation: 378
Use bootstrap Grid System
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="col-md-4 col-sm-12 col-xs-12">
<div class="pink">
</div>
</div>
<div class="col-md-8 col-sm-12 col-xs-12">
<div class="col-md-6 col-sm-6 col-xs-6">
<div class="lightblue">
</div>
</div>
<div class="col-md-6 col-sm-6 col-xs-6">
<div class="lightblue">
</div>
</div>
<div class="clearfix">
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="gray">
</div>
</div>
</div>
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="col-md-8 col-sm-12 col-xs-12">
<div class="col-md-6 col-sm-6 col-xs-6">
<div class="lightblue">
</div>
</div>
<div class="col-md-6 col-sm-6 col-xs-6">
<div class="lightblue">
</div>
</div>
<div class="clearfix">
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="gray">
</div>
</div>
</div>
<div class="col-md-4 col-sm-12 col-xs-12">
<div class="pink">
</div>
</div>
</div>
</body>
</html>
In CSS
.pink
{
background-color:#FFB5FB;
height:230px;
}
.lightblue
{
background-color:#C6F4FE;
height:100px;
}
.gray
{
background-color:#B3EDAD;
height:100px;
margin:30px 0px;
}
.col, .col-1, .col-10, .col-11, .col-12, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-auto, .col-lg, .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-auto, .col-md, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-auto, .col-sm, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-auto, .col-xl, .col-xl-1, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-auto
{
padding-right: 3px;
padding-left: 3px;
}
Here is the demo on Jsfiddle https://jsfiddle.net/d3aht26z/11/
Upvotes: 0