• Stars
    star
    632
  • Rank 71,124 (Top 2 %)
  • Language
    HTML
  • License
    Other
  • Created almost 9 years ago
  • Updated about 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

pure CSS masonry layouts

img img img img

driveway

pure CSS masonry layout aid

img

driveway is an explorative project for developing pure CSS masonry layouts. It is developed using stylus.

  • easy to use
  • interactive
  • responsive
  • config driven
  • customisable
  • extendable
<div class="dw">
  <div class="dw-panel ">
    <div class="dw-panel__content">
      <p>Some content.</p>
    </div>
  </div>
</div>

"I just want a copy"

You may have come here from the blog post I wrote about pure CSS masonry layouts. If that's the case and you want the exact code I used in that post(with vendor prefixing), you'll be best served looking in the dist folder for driveway.blog.css and driveway.blog.min.css. Alternatively, use bower to pull in the repo.

browser support

Chrome Firefox Safari Opera Edge IE
😄 😄 😄 😄 😄 😓*

* driveway will play nice in IE10+

driveway relies on Flexbox and multi-column layout properties. For further details on browser support for these check out caniuse.com.

usage

In order to start using driveway, drop the driveway{.min}.css file into your page and start building your markup.

driveway simply provides the basic means to layout your content in a masonry style and provides no aesthetic styling. This should ideally be covered by your own theme files. There are some notes about theming below.

If you would like a similar theme to that used in the demo, check out the theme.styl file in the sources.

anatomy

driveway is built up of different blocks;

  • container
  • panels
  • clusters
  • segments
  • flip panels(optional)
  • focus curtain(optional)

Below is an explanation of these blocks. It may be easier to inspect the demo page or source in the repo to get a further understanding of how these piece together.

layout container

We start our layout with a container;

<div class="dw"></div>
class reference
  • dw - layout container

layout panels

Panels are the simplest building blocks of our layout. The content for a panel lives inside the dw-panel__content element.

<div class="dw-panel ">
  <div class="dw-panel__content">
    <p>Panel content.</p>
  </div>
</div>
modifiers
  • Focus {dw-panel--focus} - the focus modifier will focus a panel on hover. Ust it by adding the dw-panel--focus class to the panel. This means that a focus curtain element must exist within the layout container as the very last element.

      <div class="dw__focus-curtain"></div>
  • Pulse {dw-panel--pulse} - the pulse modifier will slightly enlarge a panel on hover. Use it by adding the dw-panel--pulse class to the panel.

class reference
  • dw-panel - panel
  • dw-panel__content - panel content
  • dw-panel--focus - panel focus modifier
  • dw-panel--pulse - panel pulse modifier

clusters and segments

Clusters and segments are most likely the trickiest part of creating a layout with driveway. Clusters are used to breakup the layout flow a little more and enhance the masonry effect that's desired.

A cluster is the top level element.

<div class="dw-panel dw-cluster dw-cluster--vertical">
</div>

It's still a panel so it needs the dw-panel class in addition to the dw-cluster class. The last class is used to declare the direction of the cluster flow. dw-cluster--vertical declares that are cluster should flow vertically using columns whilst dw-cluster--horizontal would declare a horizontal flow for our cluster. This is important. Not adding the modifier class will result in that cluster not collapsing when desired.

A cluster is made up of segments. This can be tricky.

<div class="dw-cluster__segment"></div>

The first children of our cluster need to be either rows or columns depending on the directional flow of our cluster. Our content will then sit within these.

For example;

A vertically flowed cluster with two columns. The row/column modifier is important to define the internal flow of the segment. Here we use dw-cluster__segment--col as we want columns. But we may use dw-cluster__segment--row if we desire a row.

<div class="dw-panel dw-cluster dw-cluster--vertical">
  <div class="dw-cluster__segment dw-cluster__segment--col ">
  </div>
  <div class="dw-cluster__segment dw-cluster__segment--col ">
  </div>
</div>

Once we have created our cluster children containers, we simply need to fill them with content. We fill them with panel blocks. These panel blocks must have the class dw-cluster__segment in addition to their panel class.

<div class="dw-panel dw-cluster__segment">
  <div class="dw-panel__content">
    <p>Panel content.</p>
  </div>
</div>

We may want to enforce that our segments take up a certain amount of real estate inside their clusters. There are two segment modifiers to ensure that a segment takes up at least 25% or 50% of the real estate in the relative direction. These are applied with dw-cluster__segment--quart and dw-cluster__segment--half respectively.

Putting it all together we get something like;

<div class="dw-panel dw-cluster dw-cluster--vertical">
  <div class="dw-cluster__segment dw-cluster__segment--col ">
    <div class="dw-panel dw-cluster__segment ">
      <div class="dw-panel__content">
        <p>I am in the first column.</p>
      </div>
    </div>
  </div>
  <div class="dw-cluster__segment dw-cluster__segment--col ">
    <div class="dw-panel dw-cluster__segment ">
      <div class="dw-panel__content">
        <p>I am in the second column.</p>
      </div>
    </div>
    <div class="dw-panel dw-cluster__segment ">
      <div class="dw-panel__content">
        <p>So am I.</p>
      </div>
    </div>
  </div>
</div>
class reference
  • dw-cluster - cluster
  • dw-cluster--vertical - vertical flow cluster modifier
  • dw-cluster--horizontal - horizontal flow cluster modifier
  • dw-cluster__segment - segment
  • dw-cluster__segment--col - segment column
  • dw-cluster__segment--row - segment row
  • dw-cluster__segment--quart - segment taking up quarter of the real estate available
  • dw-cluster__segment--half - segment taking up half of the real estate available

focus curtain

The focus curtain is an optional element. It is required though if you wish to use the focus modifier on any of your panels. This is because driveway makes use of CSS sibling combinator syntax in order to give off the desired effect. To use, ensure that an element with the class dw__focus-curtain is placed as the very last element of the layout container.

<div class="dw">
  <!-- LAYOUT CONTENT HERE -->
  <div class="dw__focus-curtain"></div>
</div>

flip panels

Flip panels are layout panels that spin round on hover/tap(mobile). Due to the required markup needed for the effect, their structure is a little different to other panels.

<div class="dw-panel dw-flip dw-flip--md">
  <div class="dw-panel__content dw-flip__content">
    <div class="dw-flip__panel dw-flip__panel--front">
      <h1>You can flip me round</h1>
    </div>
    <div class="dw-flip__panel dw-flip__panel--back">
      <h1>Yeah that's right</h1>
    </div>
  </div>
</div>

A flip panel is still a panel so it still uses the dw-panel class. It also uses the dw-flip class and an additional class to define the height of the panel.

That last piece is important. In order for the flip to render and behave correctly, a defined height must be set so that each side of the panel matches up. There are size modifiers for small, medium and large. These are set in the config and are used with dw-flip--sm, dw-flip--md and dw-flip--lg classes respectively.

Our flip panel content(dw-flip__content) has to consist of two panels(dw-flip__panel). One for the front of the panel(dw-flip__panel--front), and one for the back(dw-flip__panel--back).

class reference
  • dw-flip - flip panel
  • dw-flip--sm - small flip panel
  • dw-flip--md - medium flip panel
  • dw-flip--lg - large flip panel
  • dw-flip__content - flip panel content
  • dw-flip__panel - flip panel child panel
  • dw-flip__panel--front - flip panel front
  • dw-flip__panel--back - flip panel back

full class glossary

  • dw - layout container
  • dw-panel - panel
  • dw-panel__content - panel content
  • dw-panel--focus - panel focus modifier
  • dw-panel--pulse - panel pulse modifier
  • dw-cluster - cluster
  • dw-cluster--vertical - vertical flow cluster modifier
  • dw-cluster--horizontal - horizontal flow cluster modifier
  • dw-cluster__segment - segment
  • dw-cluster__segment--col - segment column
  • dw-cluster__segment--row - segment row
  • dw-cluster__segment--quart - segment taking up quarter of the real estate available
  • dw-cluster__segment--half - segment taking up half of the real estate available
  • dw__focus-curtain - focus curtain
  • dw-flip - flip panel
  • dw-flip--sm - small flip panel
  • dw-flip--md - medium flip panel
  • dw-flip--lg - large flip panel
  • dw-flip__content - flip panel content
  • dw-flip__panel - flip panel child panel
  • dw-flip__panel--front - flip panel front
  • dw-flip__panel--back - flip panel back

theming

driveway includes minimal theming. It provides structural styling and minimal aesthetics for things like panel padding. For the demos, utility classes are used to add color to text, panels etc.

Some areas of theming are likely to be common though such as how to display images as panels.

images

Displaying images in a masonry style is quite a common desire. It seems likely that when doing this, there will be no need to define an img element within our panel content as the img is the panel content.

<div class="dw-panel ">
  <img src="img/photo-2.jpg" class="dw-panel__content"/>
</div>

However, dropping this in the page with no img specific theming will break things a little depending on your image sizes. This isn't major, but for my personal theming I added the following rules to my theme.

img {
  max-height: 300px;
}
img.dw-panel__content,
img.dw-flip__panel {
  padding: 0;
}
img.dw-flip__panel {
  max-height: 100%;
}

This stops images going wild!

development

setup

driveway is developed using gulp, stylus and jade.

NOTE: In order to run the source, both [node] and [gulp] are required.

  1. Clone the repo.
  git clone https://github.com/jh3y/driveway.git
  1. Navigate into the repo and install the dependencies.
  cd driveway
  npm install
  1. Run gulp to take care of preprocessing and running a local static server instance.
  gulp

available pages

There are some pages available for developing against that have been used to explore methods when developing driveway;

  • index.html - demo page for driveway which is manually built.
  • sandbox.html - sandbox page for developing new features.
  • dev.html - randomly generated layout in order to test different combinations.
  • timeline.html - page for exploring timeline ordered content layouts.

config driven development

Development of driveway is config driven in the sense that a set of variables defined in a json file are passed to both jade and stylus source are compiled. This makes it easier to change properties for driveway by only having to alter them in one place.

roll your own!

As driveway is config driven, you can make alterations to it's configuration such as classnames, responsive breakpoints and some default aesthetics by making updates to this it's config file and compiling your own versions.

In order to do this;

  • clone and set up the repo.
  • modify driveway-config.json.
  • run gulp compile --dist --stat. This will output new files in the dist folder whilst giving you the new filesize.

timeline ordering issue

Date ordered content is something that deserves it's own mention as this seems to be the hardest issue to tackle with implementing a pure CSS masonry layout.

Without server side rendering or some JavaScript intervention this isn't easy/possible to maintain with just CSS. I have put together a simple implementation that uses JavaScript that can be accessed from this issue.

Date ordered content can be done but it is when we try and make this content responsive that we hit a stumbling block as the order is lost between viewports.

I have experimented with different approaches(even trying to play with flexbox ordering) but I haven't come across a nice way of doing it.

The only straight forward solution seems to be duplicating the markup per viewport size breakpoint.

an example

Let's imagine we have some content that is ordered by date.

At a larger viewport we wish to display this in four columns. This requires dropping an item of content into each column one a time from left to right, newest to oldest(1-10) until we run out of items.

Column 1 Column 2 Column 3 Column 4
1 2 3 4
5 6 7 8
9 10 EMPTY EMPTY

This looks fine but when we drop down to a lower viewport would be greeted with one column and the items in the wrong order;

Column
1
5
9
2
6
etc.

One way to get round this is render two sets of content on the page and wrap them accordingly based on the viewport.

For our mobile version of the markup, we just need one column with our content in the correct order. For this, we can use a container that will be hidden with CSS at larger viewports and then a collection of panel blocks.

<div class="dw--mobile">
  <div class="dw-panel"></div> <!-- 1 -->
  <div class="dw-panel"></div> <!-- 2 -->
  <div class="dw-panel"></div> <!-- 3 -->
  <div class="dw-panel"></div> <!-- 4 -->
  <div class="dw-panel"></div> <!-- 5 -->
  <div class="dw-panel"></div> <!-- 6 -->
</div>

For our desktop version we need a vertically flowed cluster with the amount of columns that are desired. Nested clusters will work fine here.

<div class="dw--desktop">
  <div class="dw-panel dw-cluster">
    <div class="dw-cluster__segment dw-cluster__segment--col ">
      <div class="dw-panel"></div> <!-- 1 -->
      <div class="dw-panel"></div> <!-- 5 -->
    </div>
    <div class="dw-cluster__segment dw-cluster__segment--col ">
      <div class="dw-panel"></div> <!-- 2 -->
      <div class="dw-panel"></div> <!-- 6 -->
    </div>
    <div class="dw-cluster__segment dw-cluster__segment--col ">
      <div class="dw-panel"></div> <!-- 3 -->
    </div>
    <div class="dw-cluster__segment dw-cluster__segment--col ">
      <div class="dw-panel"></div> <!-- 4 -->
    </div>
  </div>
</div>

We can then control what is seen with some simple CSS theming like;

@media (min-width: 768px) {
  .dw--mobile {
    display: none;
  }
}
.dw--desktop {
  display: none;
}
@media (min-width: 768px) {
  .dw--desktop {
    display: block;
  }
}

This isn't ideal but will work. If someone has a better solution please submit a PR! 😄

contributing

Don't hesitate to post and issue, PR or suggestion. Alternatively, get in touch via email or by tweeting me @_jh3y!

license

MIT

@jh3y 2017

More Repositories

1

whirl

CSS loading animations with minimal effort!
SCSS
1,756
star
2

tyto

manage and organise things
JavaScript
675
star
3

ep

enhance your HTML5 progress bars with minimal effort!
JavaScript
647
star
4

vincent-van-git

Use your Github commit history as a canvas!
JavaScript
288
star
5

meanderer

A JavaScript micro-library for responsive CSS motion paths! ✨
JavaScript
223
star
6

sketchbook

The home for all my demo source wherever you may find them! ⚡️
HTML
183
star
7

gulp-boilerplate

a simple gulp boilerplate
JavaScript
146
star
8

kody

.files and environment configuration manager created with node
JavaScript
139
star
9

doormat

Let's take a scroll!
JavaScript
110
star
10

jh3y

73
star
11

pxl

A React app for drawing pixel art
JavaScript
72
star
12

osaka-card

TypeScript
59
star
13

tips

CSS tooltips!
CSS
47
star
14

jhey.dev

Site source for jhey.dev ✨
JavaScript
47
star
15

a-guide-to-css-animation

Demo code for "A Guide to CSS Animation"
CSS
44
star
16

use-caret-position

A custom React hook for grabbing the caret position in a text input.
JavaScript
37
star
17

parcel-boilerplate

a boilerplate for using Parcel JS 😎
HTML
30
star
18

culr

color search engine
JavaScript
27
star
19

node-cli-boilerplate

a simple boilerplate to get up and running with node cli apps
JavaScript
27
star
20

creatives-directory

A list of creatives to follow on Twitter 🐦
JavaScript
23
star
21

view-transition-sandbox

Sandbox to get creative with the View Transition API
Astro
20
star
22

my-script-kit

JavaScript
20
star
23

move-things-with-css

The accompanying source for "Move Things With CSS"
CSS
20
star
24

focussed-twitter

Let's focus on the tweets! 🐦
JavaScript
17
star
25

subscription-calendar-view-transitions

MPA View Transitions Subscription Calendar
Astro
17
star
26

stationery-cabinet

The repository for the majority of my CodePen creations!
Pug
15
star
27

crayon

a repo for styling CodePen profiles
HTML
14
star
28

deck

Astro
14
star
29

pen-case

A local development boilerplate set up for creating new pens 📝
Makefile
12
star
30

sike

a cli app that reminds you to move around every once in a while!
JavaScript
11
star
31

russ

a node scripts runner 🐰
JavaScript
11
star
32

parcel-react-boilerplate

a boilerplate for bundling react applications with Parcel JS
JavaScript
10
star
33

netlify-cms-next-starter

Get up and running with Netlify CMS && Next.js
JavaScript
10
star
34

next-portfolio-starter

A portfolio starting point using Next.js, Netlify CMS, Storybook, and Tailwind
JavaScript
9
star
35

kody_env

My personal settings for kody .files manager
Shell
9
star
36

serverless-og

JavaScript
9
star
37

whac-a-mole-react

JavaScript
9
star
38

dynamic-island

An Astro playground for building a "Dynamic Island" for your site
CSS
9
star
39

round-table

CSS
8
star
40

egghead

a home for my egghead material source 🥚
HTML
7
star
41

campfire

CSS
6
star
42

shooting-stars

HTML5 Canvas play around to create shooting stars effect
JavaScript
6
star
43

houdini-tesla

A CSS Houdini PaintWorklet for Tesla Coils
JavaScript
5
star
44

create-bangle-app

create and develop bangle.js apps from the command line
JavaScript
5
star
45

houdini-noise

CSS Houdini PaintWorklet for background noise
JavaScript
4
star
46

color-image-search-api

JavaScript
4
star
47

astro-mpa-bars

Quick POC for Astro Page Stinger View Transitions
TypeScript
4
star
48

which-key

an app for grabbing JavaScript KeyboardEvent info!
JavaScript
4
star
49

blurbs

Write something about me!
3
star
50

testPlayground

a repo for examples on how to set up mocha
JavaScript
3
star
51

jheymote

Audience remote for Jhey's conference talks
JavaScript
3
star
52

storybook-addon-studybook

Spin your Storybook into a learning aid with trackable progress.
JavaScript
3
star
53

key-book

create frozen enum objects from a string array ❄️
JavaScript
3
star
54

electron-parcel-react-starter

A starter project using Electron, React, and Parcel
JavaScript
3
star
55

border-radius-playground

An interactive visualisation tool for becoming a wizard with border-radius ✨
JavaScript
3
star
56

feedy

an angular app for consuming public photo feeds
JavaScript
3
star
57

inspector-gamut

A POC app for using AI to generate color palettes based on keywords
TypeScript
3
star
58

ng-mega-table

A directive for handling mega data
JavaScript
2
star
59

green-blocks

A Github Activity Visualizer Built with Next.js, React-Three-Fiber, Netlify, Tailwind, and GSAP
JavaScript
2
star
60

react-waves

A React component for making those fancy animated waves!
JavaScript
2
star
61

corvid

interactive command line Github API browser and cloning aid
JavaScript
2
star
62

blokky-road

3D CSS studio built with React on Vite
JavaScript
2
star
63

blink

JavaScript
2
star
64

fusion-hn

Hacker News example app built w/ Fusion JS
JavaScript
2
star
65

html5-boilerplate-jade-less-livereload.docpad

A skeleton for docpad using html5 boilerplate, less and jade.
CoffeeScript
1
star
66

interactive-twitch-overlay

Interactive Twitch Overlays Built with Tailwind && Next.js
JavaScript
1
star
67

sticky

A configurable sticky note component.
JavaScript
1
star
68

nodivember

CSS
1
star
69

blok-party

JavaScript
1
star
70

og-generator

A CLI tool for generating jh3y cover assets.
JavaScript
1
star
71

clinic

Submit your questions and issues for the clinic!
1
star
72

jheytompkins.com

source for
JavaScript
1
star
73

pencil-sharpener

Repo for storing my CodePen profile styling
HTML
1
star
74

next-storyblok-playground

JavaScript
1
star
75

gulp-template-store

a gulp plugin for storing lodash templates in a namespace object
JavaScript
1
star