Skip to content

Instantly share code, notes, and snippets.

@pixleight
Created May 7, 2012 18:17
Show Gist options
  • Save pixleight/2629423 to your computer and use it in GitHub Desktop.
Save pixleight/2629423 to your computer and use it in GitHub Desktop.
CSS-Only Pinterest-style box columns
/**
* CSS-Only Pinterest-style box columns
*/
@import url(http://fonts.googleapis.com/css?family=Open+Sans:400,300);
html {
background: #DEF;
background: linear-gradient(45deg, #FFE, #FED);
min-height: 100%;
font-family: "Open Sans", Helvetica, sans-serif;
font-weight: 300;
}
.mono {
font-family: monospace;
}
pre {
background: rgba(255, 255, 255, 0.5);
padding: 10px;
border: 1px solid #FFF;
}
#wrapper {
width: 90%;
max-width: 1170px;
min-width: 800px;
margin: 50px auto;
}
#columns {
column-count: 3;
column-gap: 10px;
}
.pin {
display: inline-block;
background: #FEFEFE;
border: 2px solid #FAFAFA;
box-shadow: 0 1px 2px rgba(34, 25, 25, 0.4);
margin: 0 2px 15px;
column-break-inside: avoid;
padding: 15px;
background: linear-gradient(45deg, #FFF, #F9F9F9);
}
.pin img {
width: 100%;
}
.pin p {
margin: 0;
}
@media all and (min-width: 960px) {
#columns {
column-count: 4;
}
}
@media all and (min-width: 1170px) {
#columns {
column-count: 5;
}
}
<div id="wrapper">
<h1>CSS-Only Pinterest-style Columns</h1>
<p>Social sharing website Pinterest has a simple multi-column interface when displaying "pins".</p>
<p>This is simple to achieve with only CSS floats if the boxes are all the same height. However, when the boxes are different heights, some problems will arise. There will be gaps all over the place and nothing will fit snugly together as intended.</p>
<p>Pinterest accomplishes this by using some JavaScript to get each box's height and do some calculations to absolute position it in the grid. This works well with their "infinite scolling, as new items are added to the bottom as you scroll down.</p>
<p>However, my mission is to mimic the style, and not necessarily the functionality, using only CSS. That's where CSS3 columns come in. To see how it's done, <a href="#howitsdone">skip below the demo</a>.</p>
<h2>DEMO:</h2>
<div id="columns">
<div class="pin">
<img src="http://placekitten.com/400/300" alt="PlaceKitten" />
<p>Jean shorts street art flexitarian, put a bird on it small batch squid tofu 3 wolf moon vegan 8-bit.</p>
</div>
<div class="pin">
<img src="http://placekitten.com/g/400/300" alt="PlaceKitten" />
<p>Leggings pour-over banksy, DIY wolf tattooed next level vegan dreamcatcher stumptown gentrify. DIY cred occupy, biodiesel pickled cardigan blog.</p>
</div>
<div class="pin">
<img src="http://placekitten.com/500/450" alt="PlaceKitten" />
<p>Put a bird on it viral wolf, 3 wolf moon brooklyn direct trade cliche kale chips photo booth vegan gluten-free mixtape irony pitchfork.</p>
</div>
<div class="pin">
<img src="http://placekitten.com/g/500/400" alt="PlaceKitten" />
<p>Dreamcatcher post-ironic food truck art party trust fund, salvia locavore selvage portland.</p>
</div>
<div class="pin">
<img src="http://placekitten.com/g/275/300" alt="PlaceKitten" />
<p>Leggings pour-over banksy, DIY wolf tattooed next level vegan dreamcatcher stumptown gentrify. DIY cred occupy, biodiesel pickled cardigan blog.</p>
</div>
<div class="pin">
<img src="http://placekitten.com/400/300" alt="PlaceKitten" />
<p>Jean shorts street art flexitarian, put a bird on it small batch squid tofu 3 wolf moon vegan 8-bit.</p>
</div>
<div class="pin">
<img src="http://placekitten.com/g/500/400" alt="PlaceKitten" />
<p>Dreamcatcher post-ironic food truck art party trust fund, salvia locavore selvage portland.</p>
</div>
<div class="pin">
<img src="http://placekitten.com/280/200" alt="PlaceKitten" />
<p>Put a bird on it viral wolf, 3 wolf moon brooklyn direct trade cliche kale chips photo booth vegan gluten-free mixtape irony pitchfork.</p>
</div>
<div class="pin">
<img src="http://placekitten.com/460/300" alt="PlaceKitten" />
<p>Jean shorts street art flexitarian, put a bird on it small batch squid tofu 3 wolf moon vegan 8-bit.</p>
</div>
<div class="pin">
<img src="http://placekitten.com/300/300" alt="PlaceKitten" />
<p>Jean shorts street art flexitarian, put a bird on it small batch squid tofu 3 wolf moon vegan 8-bit.</p>
</div>
<div class="pin">
<img src="http://placekitten.com/g/500/400" alt="PlaceKitten" />
<p>Dreamcatcher post-ironic food truck art party trust fund, salvia locavore selvage portland.</p>
</div>
<div class="pin">
<img src="http://placekitten.com/500/400" alt="PlaceKitten" />
<p>Jean shorts street art flexitarian, put a bird on it small batch squid tofu 3 wolf moon vegan 8-bit.</p>
</div>
<div class="pin">
<img src="http://placekitten.com/g/500/400" alt="PlaceKitten" />
<p>Dreamcatcher post-ironic food truck art party trust fund, salvia locavore selvage portland.</p>
</div>
<div class="pin">
<img src="http://placekitten.com/g/670/400" alt="PlaceKitten" />
<p>Dreamcatcher post-ironic food truck art party trust fund, salvia locavore selvage portland.</p>
</div>
<div class="pin">
<img src="http://placekitten.com/500/557" alt="PlaceKitten" />
<p>Put a bird on it viral wolf, 3 wolf moon brooklyn direct trade cliche kale chips photo booth vegan gluten-free mixtape irony pitchfork.</p>
</div>
</div>
<h2 id="howitsdone">How It's Done:</h2>
<p>To accomplish this, my HTML will look something like this:</p>
<pre>
&lt;div id="columns"&gt;
&lt;div class="pin"&gt;
&lt;img src="http://placekitten.com/400/300" alt="PlaceKitten" /&gt;
&lt;p&gt;Jean shorts street art flexitarian ... &lt;/p&gt;
&lt;/div&gt;
&lt;div class="pin"&gt;
&lt;img src="http://placekitten.com/g/400/300" alt="PlaceKitten" /&gt;
&lt;p&gt;Leggings pour-over banksy, DIY wolf tattooed ... &lt;/p&gt;
&lt;/div&gt;
&lt;div class="pin"&gt;
&lt;img src="http://placekitten.com/500/450" alt="PlaceKitten" /&gt;
&lt;p&gt;Put a bird on it viral wolf, 3 wolf moon ... &lt;/p&gt;
&lt;/div&gt;
&lt;!-- and so on ... --&gt;
&lt;/div&gt;
</pre>
<p>Now on to the styling:</p>
<pre>
#columns {
-moz-column-count: 3;
-moz-column-gap: 10px;
-moz-column-fill: auto;
-webkit-column-count: 3;
-webkit-column-gap: 10px;
-webkit-column-fill: auto;
column-count: 3;
column-gap: 15px;
column-fill: auto;
}
.pin {
-moz-column-break-inside: avoid;
-webkit-column-break-inside: avoid;
column-break-inside: avoid;
display: inline-block;
margin: 0 2px 15px;
padding: 15px;
border: 2px solid #FAFAFA;
box-shadow: 0 1px 2px rgba(34, 25, 25, 0.4);
background: #FEFEFE;
background-image: linear-gradient(45deg, #FFF, #F9F9F9);
}
</pre>
<p>As you can see, I used <span class="mono">column-count, column-gap</span> on <span class="mono">#columns</span> to achieve the column behavior. Then I added <span class="mono">column-break-inside: avoid;</span> to the "pins" to prevent them from flowing from one column to the next &mdash; force them to be contained in a single column. Make sure to include <span class="mono">-moz-</span> and <span class="mono">-webkit-</span> browser prefixes. Then I just styled the boxes however I wanted.</p>
<p>For good measure, I added some media queries to adjust the number of columns depending on browser width:</p>
<pre>
@media all and (min-width: 960px) {
#columns {
column-count: 4;
}
}
@media all and (min-width: 1170px) {
#columns {
column-count: 5;
}
}
</pre>
<p>All in all, I think it works pretty well. It won't function the same as Pinterest, as adding more boxes to the end will adjust the "flow" of all the columns, but I was going for style here and not function.</p>
<p>The biggest "downside" is that this <a href="http://caniuse.com/#feat=multicolumn" target="_blank">won't work</a> in IE 9 and below. The upside is maybe people will upgrade if they know they get new hawtness with a top-of-the-line browser. One can hope.</p>
</div>
{"view":"split","fontsize":"100","seethrough":"","prefixfree":"1","page":"result"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment