Skip to content

Instantly share code, notes, and snippets.

@jensimmons
Created April 3, 2012 21:00
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jensimmons/2295479 to your computer and use it in GitHub Desktop.
Save jensimmons/2295479 to your computer and use it in GitHub Desktop.
Switching Drupal Views Grid to unordered lists
<?php
/**
* @file views-view-grid.tpl.php
* Default simple view template to display a rows in a grid.
*
* - $rows contains a nested array of rows. Each row contains an array of
* columns.
*
* @ingroup views_templates
*/
?>
<?php if (!empty($title)) : ?>
<h3><?php print $title; ?></h3>
<?php endif; ?>
<ul class="<?php print $class; ?>"<?php print $attributes; ?>>
<?php foreach ($rows as $row_number => $columns): ?>
<span class="<?php print $row_classes[$row_number]; ?> clearfix">
<?php foreach ($columns as $column_number => $item): ?>
<li class="<?php print $column_classes[$row_number][$column_number]; ?>">
<?php print $item; ?>
</li>
<?php endforeach; ?>
</span>
<?php endforeach; ?>
</ul>
// Then you need this CSS to go with it:
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
}
// This switched box models. The code below assumes this change has been made.
// http://paulirish.com/2012/box-sizing-border-box-ftw
img {
max-width: 100%;
height: auto;
} // This makes the images fluid
ul.views-view-grid {
padding-left: 0;
list-style: none;
list-style-image: none;
}
ul.views-view-grid li {
float: left;
padding: 0 0.5em;
}
ul.views-view-grid li.col-first {
padding-left: 0;
}
ul.views-view-grid li.col-last {
padding-right: 0;
}
.view ul.cols-2 li {
width: 50%;
}
.view ul.cols-3 li {
width: 33.3333%;
}
.view ul.cols-4 li {
width: 25%;
}
.view ul.cols-5 li {
width: 20%;
}
.view ul.cols-6 li {
width: 16.6666%;
}
.view ul.cols-7 li {
width: 14.2857%;
}
.view ul.cols-8 li {
width: 12.5%;
}
.view ul.cols-9 li {
width: 11.1111%;
}
.view ul.cols-10 li {
width: 10%;
}
@jensimmons
Copy link
Author

Views is a super popular and super awesome way to quickly output all kinds of content with all kinds of settings / filters / options. It's one of the biggest reasons to use Drupal. Really. Awesome. http://drupal.org/project/views

Because it's super powerful and super flexible, the default markup has to be very all-purpose. By default Views has historically provided a lot of markup. Lots o divs. Lots o classes. Developers who like sleek, semantic markup have complained a lot about this. And over time, some new tools have emerged to let developers control and customize the markup more precisely. Yay!

One thing that's remained however, is some very-1997 table-based HTML layout. Yes, tables. For layout. Booooooo!

Where? Well, one of the first things you tell Views is whether you want your content presented in a list, a grid, a table, or "unformatted":
• Sometimes table is the correct option — when you are making a table of data. (This is not the table I'm complaining about. It's a great option for making a real table of content. Sadly it's not the only HTML table…)
• Sometimes people know they want a list — and Views creates a unordered or ordered list of content, that by default looks like a list (with bullets or numbers).
• "Unformatted" looks visually unformatted; Views marks up the content with tons of generic divs.
• And grid — which is one of the most popular options, because it puts the content in a grid-layout. The problem is that grid uses HTML tables to get that layout. And it should semantically be using an unordered list that's styled into a grid (rows of boxes with no bullets).

This gist replaces View's grid table code with unordered list code.

@jensimmons
Copy link
Author

Regarding fixed vs fluid vs responsive:

View's default Grid uses table HTML, which is fixed-width — the width of that table.

My replacement code creates a fluid grid of content — at the set number of columns that you specify in the View itself. It's a good start for responsive web design, but it's not responsive. It's fluid.

For responsive web design, I prefer to create a grid that changes in the number of columns it has based on the screen size. On a narrow screen, maybe you only want 1 column, or 2. On a medium-sized screen 3 or 4 might work great. And then on a giant monitor or TV, maybe you want 5 or 7 columns of content.

Sadly this approach does't take you that far. It's sticking pretty closely to the architecture that Views already has in place — just getting rid of the table HTML and replacing it with a fixed-number-of-columns fluid grid.

@rvilar
Copy link

rvilar commented Apr 4, 2012

I think that inserting a /span between /ul and /li is not correct HTML. Why do you insert this /span? Is it necessary?

@jensimmons
Copy link
Author

Rvilar — yeah, I agree. It's not really correct HTML. I put it there because it mirrors how the current views-view-grid.tpl.php works. The older version has a table row beginning and ending where I put a span. I did that so that each "row" could have a clearfix class on it, and clear the row above no matter how uneven the content is.

I believe better technique is to have it all be simple list markup, with few or no classes, and use CSS & pseudo-classes to style everything. That's what I do when I create custom themes — switch all the grid views to list views and write custom CSS.

I've been debating what to do for my base theme. In the past I've ended up trying to ban developers from using views grid (which doesn't work), having to go in behind them all to redo all their views, and then writing similar custom CSS over and over again from scratch to make the list styled into a grid. I'm looking for a way to prevent hassle and redundancy.

The code that I posted above takes a conservative approach — half fixing the situation and sticking pretty closely to how Views is already built. I'll have to think more about what could be done instead...

@micahw156
Copy link

Thanks, Jen. This is a great drop-in solution!

I saw a trick in this Omega Theme tutorial that might eliminate the span here: simply adding clear:left to the .col-first class should bring the first column over where it belongs for each row.

@klaasvw
Copy link

klaasvw commented Aug 21, 2012

Thanks for the great drop-in replacement.

I've forked your code and did something similar to what micahw156 suggests. The additional spans are removed and the li now gets a child div that takes care of padding. Each li.col-first clears the previous line similar to how the tables rows worked previously.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment