This is, in effect, the Pinterest layout. However, the solutions found online are wrapped in columns, which means the container inadvertently grows horizontally. That is not the Pinterest layout, and it does not work well with dynamically-loaded content.
What I want to do is have a bunch of images of fixed width and asymmetrical height, laid out horizontally but wrapping in a new row when the limits of the fixed-width container are met:
Can flexbox do this, or do I have to resort to a JS solution like Masonry?
Flexbox is a "1-dimensional" layout system: It can align items along horizontal OR vertical lines.
A true grid system is "2-dimensional": It can align items along horizontal AND vertical lines. In other words, cells can span across columns and rows, which flexbox cannot do.
This is why flexbox has a limited capacity for building grids. It's also a reason why the W3C has developed another CSS3 technology, Grid Layout (see below).
In a flex container with flex-flow: row wrap, flex items must wrap to new rows.
This means that a flex item cannot wrap under another item in the same row.
Notice above how div #3 wraps below div #1, creating a new row. It cannot wrap beneath div #2.
As a result, when items aren't the tallest in the row, white space remains, creating unsightly gaps.
image credit: Jefree Sujit
column wrap Solution
If you switch to flex-flow: column wrap, flex items will stack vertically and a grid-like layout is more attainable. However, a column-direction container has three potential problems right off the bat:
It expands the container horizontally, not vertically (like the Pinterest layout).
It requires the container to have a fixed height, so the items know where to wrap.
As of this writing, it has a deficiency in all major browsers where the container doesn't expand to accommodate additional columns.
As a result, a column-direction container may not be feasible in many cases.
Other Solutions
Add containers
In the first two images above, consider wrapping items 2 and 3 in a separate container. This new container can be a sibling to item 1. Done.
Here's a detailed example: Calculator keypad layout with flexbox
One downside worth highlighting: If you're wanting to use the order property to re-arrange your layout (such as in media queries), this method may eliminate that option.
Desandro Masonry
Masonry is a JavaScript grid layout library. It
works by placing elements in optimal position based on available
vertical space, sort of like a mason fitting stones in a wall.
source: http://masonry.desandro.com/
How to Build a Site that Works Like Pinterest
[Pinterest] really is a cool site, but what I find interesting is how these pinboards are laid out... So the purpose of this tutorial is to re-create this responsive block effect ourselves...
source: https://benholland.me/javascript/2012/02/20/how-to-build-a-site-that-works-like-pinterest.html
CSS Grid Layout Module Level 1
This CSS module defines a two-dimensional grid-based layout system, optimized for user interface design. In the grid layout model, the children of a grid container can be positioned into arbitrary slots in a predefined flexible or fixed-size layout grid.
source: https://drafts.csswg.org/css-grid/
Grid Layout example: CSS-only masonry layout but with elements ordered horizontally
What you want can be achieved in 3 2 ways, CSS wise:
flexbox:
=
.parent {
display: flex;
flex-direction: column;
flex-wrap: wrap;
max-width: {max-width-of-container} /* normally 100%, in a relative container */
min-height: {min-height-of-container}; /* i'd use vh here */
}
.child {
width: {column-width};
display: block;
}
CSS columns
=
(this solution has the very neat advantage of built-in column-span - pretty handy for titles). The disadvantage is ordering items in columns (first column contains first third of the items and so on...). I made a jsFiddle for this.
.parent {
-webkit-columns: {column width} {number of columns}; /* Chrome, Safari, Opera */
-moz-columns: {column width} {number of columns}; /* Firefox */
columns: {column width} {number of columns};
}
.child {
width: {column width};
}
/* where {column width} is usually fixed size
* and {number of columns} is the maximum number of columns.
* Additionally, to avoid breaks inside your elements, you want to add:
*/
.child {
display: inline-block;
-webkit-column-break-inside: avoid;
page-break-inside: avoid;
break-inside: avoid-column;
}
Masonry plugin
absolute positioning after calculating rendered item sizes, via JavaScript (masonry plugin).
You can achieve the masonry effect as per your screenshot, but you've set the height of the outer div dynamically
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
.item-list {
max-width: 400px;
border: 1px solid red;
display: -ms-flexbox;
-ms-flex-direction: column;
-ms-flex-wrap: wrap;
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 100vw;
}
.item-list__item {
border: 1px solid green;
width: 50%;
}
<div class="item-list" >
<div class="item-list__item">
Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do. Therefore by applauded acuteness supported affection it. Except had sex limits
county enough the figure former add. Do sang my he next mr soon. It merely waited do unable.
</div>
<div class="item-list__item">
Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do.
</div>
<div class="item-list__item">
Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do. Therefore by applauded acuteness supported affection it. Except had sex limits
</div>
<div class="item-list__item">
Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do.
</div>
<div class="item-list__item">
Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do. Therefore by applauded acuteness supported affection it. Except had sex limits
</div>
</div>
Instead of flexbox, I recommend to use columns for grids like this. As you can see, the spacing on the bottom images can be better, but for a native CSS solution I think it's pretty neat. No more JS:
.container {
max-width: 900px;
width: 100%;
margin: 0 auto;
}
ul {
margin: 0;
padding: 0;
}
ul li {
list-style: none;
font-size: 0;
}
.portfolio ul {
-moz-column-count: 4;
-webkit-column-count: 4;
column-count: 4;
-moz-column-gap: 3px;
-webkit-column-gap: 3px;
column-gap: 3px;
}
.portfolio ul:hover img {
opacity: 0.3;
}
.portfolio ul:hover img:hover {
opacity: 1;
}
.portfolio ul li {
margin-bottom: 3px;
}
.portfolio ul li img {
max-width: 100%;
transition: 0.8s opacity;
}
<section class="container portfolio">
<ul>
<li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_2959-1400px.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-010.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_6188-dng-k.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/20151220-csaladi-peregi-046-k.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/20151230-csalad-szalai-0194-k.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-001(1).jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528171819-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528171829-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528171938-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528171953-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528194754-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528184948-portfolio.jpg" alt="" /></li>
</ul>
</section>
the column approach seems a good compromise if you set column-width via vmin or vmax units and drop column-count (first snippet) , display:grid and vmin is also an option for the futur (second snippet).
snippet inspired from #Lanti answer.
test demo with vmin
.container {
}
ul {
margin: 0;
padding: 0;
}
ul li {
list-style: none;
font-size: 0;
}
.portfolio ul {
-webkit-column-width:50vmin;
-moz-column-width:50vmin;
column-width:50vmin;
-webkit-column-fill:balance;
-moz-column-fill:balance;
column-fill:balance;
-webkit-column-gap: 3px;
-moz-column-gap: 3px;
column-gap: 3px;
}
.portfolio ul:hover img {
opacity: 0.3;
}
.portfolio ul:hover img:hover {
opacity: 1;
}
.portfolio ul li {
margin-bottom: 3px;
}
.portfolio ul li img {
max-width: 100%;
transition: 0.8s opacity;
}
<section class="container portfolio">
<ul>
<li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_2959-1400px.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-010.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_6188-dng-k.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/20151220-csaladi-peregi-046-k.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/20151230-csalad-szalai-0194-k.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-001(1).jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528171819-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528171829-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528171938-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528171953-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528194754-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528184948-portfolio.jpg" alt="" /></li>
</ul>
</section>
a link among others https://web-design-weekly.com/2014/11/18/viewport-units-vw-vh-vmin-vmax/
display:grid coud make it also easy with auto-fill but will require to set a span value to tallest image so rows and columns can inbricate
.container {}
ul {
margin: 0;
padding: 0;
}
ul li {
list-style: none;
font-size: 0;
}
.portfolio ul {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(50vmin, 1fr));
grid-gap: 5px;
grid-auto-rows: minmax(10px, 1fr);
grid-auto-flow: dense;
}
.portfolio ul:hover img {
opacity: 0.3;
}
.portfolio ul:hover img:hover {
opacity: 1;
}
.portfolio ul li {
margin-bottom: 3px;
}
.portfolio ul li img {
max-width: 100%;
transition: 0.8s opacity;
}
li {
border: solid blue;
grid-row-end: span 1;
display: flex;
align-items: center;
background: lightgray;
}
li:nth-child(1),
li:nth-child(3),
li:nth-child(6),
li:nth-child(7),
li:nth-child(8),
li:nth-child(9),
li:nth-child(10),
li:nth-child(11) {
border: solid red;
grid-row-end: span 2
}
<section class="container portfolio">
<ul>
<li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_2959-1400px.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-010.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_6188-dng-k.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/20151220-csaladi-peregi-046-k.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/20151230-csalad-szalai-0194-k.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-001(1).jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528171819-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528171829-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528171938-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528171953-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528194754-portfolio.jpg" alt="" /></li>
<li><img src="http://lantosistvan.com/temp/freecodecamp/160528184948-portfolio.jpg" alt="" /></li>
</ul>
</section>
you can see https://css-tricks.com/snippets/css/complete-guide-grid/
I've just made my first responsive drop-down menu with a hamburger icon but can't seem to get the logo and the menu (both as a nav and as a icon) on the same line.
<nav>
<div class="container-fluid">
<a class="navbar-brand" href="<?php bloginfo('url');?>">
<img src="<?php bloginfo('template_directory');?>/images/logo.png" class="img-fluid logo"> </a>
<div class="toggle">
<i class="fa fa-bars menu" aria-hidden="true"></i>
</div>
<ul>
<?php wp_nav_menu(
array(
'theme_location' => 'top-menu',
'menu_class' => 'top-menu'
)
);?>
</ul>
</div>
</nav>
<script src="http://code.jquery.com/jquery-3.4.1.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('.menu').click(function(){
$('ul').toggleClass('active');
})
})
</script>
CSS
nav{
width:100;
background:white;
}
ul{
width:80%;
margin:0 auto;
padding:0;
}
ul li{
list-style:none;
display:inline-block;
padding:20px;
}
ul li a {
color:black;
text-decoration:none;
}
.toggle {
width:100%;
padding:10px 20px;
background:white;
text-align:right;
box-sizing: border-box;
color:black;
font-size:30px;
display:none;
}
#media (max-width:959px)
{
.toggle{
display:block;
}
ul{
width:100%;
display:none;
}
ul li{
display:block;
text-align: center;
}
.active{
display:block;
}
}
I keep getting the logo and the nav on separate lines and or a repeat logo on both the main nav and the dropdown for the hamburger option. Please help!
please have a look on the following code segment. Inside the header there is a logo and a navbar(which is floated right). When I resize the browser horizontally, after a certain width, the navbar is coming down and I don't want it to happen. How to prevent the navbar from comming down? Please help
#header
{
height:150px;
width:100%;
background-color:#ff0000;
}
#header #logo
{
position:relative;
margin:0;
top: 50%;
transform: translateY(-50%);
margin-left:5%;
}
#header #navbar
{
list-style:none;
position:relative;
display:inline-block;
float:right;
top: 50%;
transform: translateY(-50%);
margin-right:5%;
}
#header #navbar li
{
display:table-cell;
padding-left:20px;
}
#header form
{
display:inline;
margin-right:0px;
}
#navbar a
{
text-decoration:none;
font-size:20px;
color:white;
}
#searchbox
{
height:18px;
margin-bottom:1.5px;
width:200px;
}
#submit_button
{
height:25px;
}
<div id="header">
<a href="index.html">
<img id="logo" src=logo.png alt="logo"/>
</a>
<ul id="navbar">
<li>Home</li>
<li>About</li>
<li>Contents</li>
<li>Contact Us</li>
<li id="form">
<form action="">
<input id="searchbox" type="text" name="Serching" placeholder="Search"/>
<input id="submit_button" type="submit" value="Go"/>
</form>
</li>
</ul>
</div>
it has been some time since I made my last webpage and it seems that I have forgot much. I cant resolve why the last item from the #menu ul goes to the next line while the #menu div is wide enough to contain all the list elements plus the logo div, it has margin and padding set to 0.
I used to do menus in such way before but have probably forgot something.
I searched for the solution however I cant make the things working right.
The question is..why arent the li items in one line? Whats causing the 850 px overlap when they all together should be 802px wide?
html, body {margin:0; padding:0}
body {background-image: url("./gfx/background.png"); background-position: 50%; background-repeat: no-repeat;text-align:center; background-color:#fff; font-family:Arial, Helvetica;width:100%}
.main-wrap {width:1000px; margin:0 auto}
#header {height:150px;width:1000px}
#logo {
display: block;
width: 150px;
height: 150px;
overflow: hidden;
color: #424242;
float:left;
margin: 0;
padding:0;
}
#logo span {
background: url("./gfx/logo-small.png");
z-index: 5;
display: block;
width: 150px;
height: 150px;
}
.wrap::before {
content: " ";
display: table;
}
.wrap::after{
clear: both;
content: " ";
display: table;
}
/*menu*/
#menu {width:849px;margin:0 0 0 0; padding:0px 150px 0 0}
#menu ul li {list-style: none;}
#menu ul li a {
z-index: 5;
position: relative;
float:left;
display: inline;
height: 31px;
overflow: hidden;
text-decoration: none;
color:#336699;
font-size: 20px;
margin: 0;
padding:0
}
#menu li a:hover,
#menu li a:focus {
height: 31px;
margin-top: 0;
color:#fff;
}
#menu li a span {
position: absolute;
top: 0;
left: 0;
display: block;
z-index: -1;
height: 31px;
cursor: pointer;
}
#menu li a:hover span,
#menu li a:focus span {
background: url("./gfx/menu-a.png");
background-repeat: no-repeat;
color:#fff;
}
#menu-1,
#menu-1 span {
background-position: 0 0;
width:119px;
}
#menu-1:hover span,
#menu-1:focus span {
background-position: 0px 0px;
}
#menu-2,
#menu-2 span {
width: 112px;
}
#menu li a#menu-2:hover span,
#menu li a#menu-2:focus span {
background-position: -119px 0px;
}
#menu-3,
#menu-3 span {
width: 128px;
}
#menu li a#menu-3:hover span,
#menu li a#menu-3:focus span {
background-position: -231px 0px;
}
#menu-4,
#menu-4 span {
width: 184px;
}
#menu li a#menu-4:hover span,
#menu li a#menu-4:focus span {
background-position: -359px 0px;
}
#menu-5,
#menu-5 span {
width: 149px;
}
#menu li a#menu-5:hover span,
#menu li a#menu-5:focus span {
background-position: -543px 0px;
}
#menu-6,
#menu-6 span {
width: 110px;
}
#menu li a#menu-6:hover span,
#menu li a#menu-6:focus span {
background-position: -692px 0px;
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>New web</title>
<link rel="stylesheet" href="main.css" type="text/css" />
</head>
<body>
<div class="main-wrap"> <!-- hlavni -->
<div class="wrap">
<div id="header">
<div id = "logo"><a href = "new_web/">
<span> </span>
</a></div>
<div id="menu">
<ul>
<li><a id="menu-1" href="new_web/about-us.html">About Us<span></span></a></li>
<li><a id="menu-2" href="new_web/services.html">Services<span></span></a></li>
<li><a id="menu-3" href="new_web/insurance.html">Insurance<span></span></a></li>
<li><a id="menu-4" href="new_web/meet-our-team.html">Meet Our Team<span></span></a></li>
<li><a id="menu-5" href="new_web/latest-news.html">Latest News<span></span></a></li>
<li><a id="menu-6" href="new_web/contact.html">Contact<span></span></a></li>
</ul>
</div>
</div>
</div>
<div id = "slider">
</div>
<div id = "main">
<!-- first page only -->
<div class="wrapper">
<div id="smart-boxes">
<div id="smart-box-1">
<p>"Change your thoughts and you chagne your world." <span>Norman Vincent Peale</span>
</p>
</div>
<div id="smart-box-2">
<p>High quality psychological services <a>read more...</a>
</p>
</div>
<div id="smart-box-3">
<p>We are a multidisciplinary treatment center <a>read more...</a>
</p>
</div>
</div>
</div>
</div>
<div id="footer">
<div class="wrapper">
<div id="footer-address">
<p>
</p>
</div>
<div id = "footer-links-1">
<p>
Contact Us<br />
FAQ <br />
</p>
</div>
<div id = "footer-links-2">
<p>
Terms of use<br />
Insurance<br />
Our Team<br />
</p>
<p class="ext-links">
</p>
</div>
</div>
</div>
</div>
</body>
</html>
Thank you for your advices.
Allright, basic mistake: when positioning two elements using float property just beside each other one must have float:left (#logo) and the other muset go to right simple adding float:right to #menu did the thing (also removed the 150px padding-right).
I am having some issues with z-index that I can't seem to be able to iron out. I've made sure that the relavant position atributes are set to relative, but my elements just won't play nicely.
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
</head>
<body>
<div class="container" id="top">
<h1>Top</h1>
<div class="slideshow">
<ul class="nav">
<li class="prev">Previous</li>
<li class="next">Next</li>
</ul>
<ul class="slides" id="slides">
<li><img src="images/top_blue.gif" alt="Harley Davidson Sportster" /></li>
<li><img src="images/top_brown.gif" alt="Harley Davidson Sportster" /></li>
<li><img src="images/top_vanilla.gif" alt="Harley Davidson Sportster" /></li>
</ul>
</div>
</div>
</body>
</html>
And here my CSS:
body, h1, ul, li {
margin: 0; padding: 0; border: 0;
}
.container {
width: 800px; margin: auto;
position: relative;
}
.slideshow {
width: 800px; height: 50px;
position: relative;
}
.slideshow ul.nav {
list-style: none;
position: relative;
z-index: 100;
}
.slideshow ul.nav li.prev {
float: left;
}
.slideshow ul.nav li.next {
float: right;
}
.slideshow ul.nav li a {
display: block; width: 32px; height: 48px; text-indent: -9999px;
}
.slideshow ul.nav li.prev a {
background: url(images/arrow_prev.gif);
}
.slideshow ul.nav li.next a {
background: url(images/arrow_next.gif);
}
.slideshow ul.slides {
list-style: none;
position: relative;
top:0px;
height:50px;
}
Here my JSFiddle: http://jsfiddle.net/XPsn7/1/
Basically, the main images under have z-index of 5, and the arrow image should position in front of the slides, with z-index of 15. However, the navigation arrows cause the slides images to move right to make room for them.
What's going on?
The problem is your relative positioning. If you create a relative container with child elements that are absolutely positioned, you should be able to float the images as intended.