A Responsive Drupal theme in 50 lines of code or less
Right now everyone wants a good mobile experience for their site and that is sparking discussions about what theme you can and should use to make your site accessible to the mobile world. At Zivtech, we feel that we have outgrown starter themes because we spend more time overriding than using them (especially in D7 since a lot of the great Zen stuff is baked right in). The other day I got to thinking, just what would it take to build a responsive theme for Drupal from scratch. Is it so complicated that we need systems upon systems to handle it?
You probably guessed, my answer is no. It turns out it takes less than fifty lines of code to build a basic working responsive theme complete with media query powered break points. If a completely custom and highly flexible layout can be made in less code than zen’s opening page.tpl.php comment, why use a base theme for responsiveness? Of course, I cheated a little by using an amazing framework that a coworker and zealot turned me onto awhile back called Susy.
Grid systems have been around for quite a few years now but the advent of Sass makes them a whole new ball game. Until CSS preprocessors, working with a grid system (like blueprint or 960.gs) meant you included some boilerplate CSS files that gave you a bunch of nice default grid behaviors. Then you just had to take their selectors and add them to your markup. This works well and it is very cool, the one problem is it is not semantic. You are changing your doc to change your presentation, yeah it’s necessary but really not cool and what that ol’ zen garden was all about avoiding. Enter Sass.
Sass is all about making CSS as terse as humanly possible, so a major feature is having simple functions that you can pass variables to (called mixins) for generating all of your CSS quickly and easily. This means you can leave your markup alone (especially in Drupal where everything and its mother is a div with 10 classes) and you can generate tailored grid CSS to match. No presentation leaking into our DOM (at least until we start hitting edge cases).
Following the Drupal 7 core’s own Stark theme for guidance, I created nothing more than an .info file and a layout.css, giving me an installable theme called Tony (named for my favorite Stark (sorry, that one was for the nerds)). My goal with Tony was to create a bare bones Drupal 7 theme with a fully functional responsive layout built with media query based break points to keep the layout friendly to displays of all sizes (including mobile). Experimenting with Tony requires that you have Compass and Susy installed on your machine.
You can always find Tony in my sandbox if you want to toy around with it, though I really don’t intend to turn it into a real base theme. Remember, we have a lot of choices there and it’s what I’m trying to avoid.
Step by step
Now lets take a tour of the code:
This line just imports compass and Susy.
$total-cols: 8 $col-width: 50px $gutter: 8px $gutter-width: $gutter $side-gutter-width: $gutter-width
Here’s where the magic begins. Here we set the stage by establishing the number of columns in our grid, the width of each one, the space between each element (the gutter) and how much room we should have on the far left and right sides. These global variables will be used by Susy everywhere else to determine what CSS it should generate. Note that we are free to enter our dimensions in pixels but Susy will do all the hard math to convert these into
% ratios so that our layout can respond proportionally to the size of the screen.
@mixin full-width +columns($total-cols) +alpha
If you’re not familiar with Sass’s syntax you’re in for a treat and I highly recommend you read up. You’ll thank me. What this does is define a mixin that can be used throughout my css to reapply a few lines of code. This one sets the width of an element by proscribing it the appropriate number of columns (in this case all of them) and then applies the alpha styles (as opposed to omega) telling Susy we want this to go to the left. The first element in a row should always be an alpha and the last one an omega.
#page-wrapper +container +susy-grid-background() width: auto margin: 6em #header, #navigation @include full-width #sidebar-second +columns(2) +omega #sidebar-first +columns(2) +alpha #content +columns(6)
Here we set the stage. Again, borrowing from Stark, this theme uses Drupal 7’s stock markup without any tweaks. We apply one of Susy’s mixins with
+container to turn the
#page-wrapper div into a container, applying the global Sass variables we created before by calling Susy’s
+container mixin. We then turn on a visible grid to show our grid as a reference (obviously just for the design/development phase). Next, we set the width to auto so that the page will grow to fill any screen size and set all margins to 6em to give it a bit of breathing room and space for a background. We also set widths for the sidebars by calling the Susy mixin (again, like a function for generating CSS) and passing in an argument of the number of columns this div should take up. Note we set whether the sidebars should appear first and last by calling
+omega Susy mixins as well. You can read more about how this works here. Finally we set the main content region’s width at 6 columns (the default appropriate to both left sidebar only and right sidebar only).
body.one-sidebar.sidebar-first #content +omega body.one-sidebar.sidebar-second #content +alpha
These four lines set
#content to float right or left based on which side bar is currently visible.
body.two-sidebars #content +columns(4) #sidebar-first +alpha #sidebar-second +omega
Here we set the content to float in between the sidebars and adjust it’s width to accommodate having an extra sidebar. The grid system makes the math easy, 8 columns - (2x 2 sidebars) = 4 columns. That’s it, now we have a fluid grid based layout that can accommodate all of our side bar variations. A great start, but I did promise to make this responsive, so now the real fun begins:
Media queries allow you style sheets to apply specific styles depending on the current size of the browser. Normally these need to go a the root of your CSS document but thankfully Sass has a media bubbling behavior that will ensure they find their way to where they belong and you are free to define them in a place that makes sense to you, even nesting them inside other selectors.
@media screen and (max-width: 1000px) #page-wrapper margin: 1em top: 0
Here we specify that if the browser width ever dips below 1,000 pixels, we should remove the top margin, drop the rest of the margins from 5em to 1 and stop using up so much real estate for borders. This helps on smaller screens and netbooks, but to be able to work well all the way down to mobile, we probably want to kill our margins completely and pop the sidebars above or below our main content.
@media screen and (max-width: 500px) #page-wrapper margin: 0 body.one-sidebar.sidebar-first, body.one-sidebar.sidebar-second, body.two-sidebars #content, #sidebar-second, #sidebar-first @include full-width
And that’s it! We covered all the big ticket items in less than fifty lines of code (at least, before compiling). So if the responsive grid system and media query break points can be achieved reliably and easily without tedious calculations, tweaking or templating… Why use a base theme at all? A good mobile experience needs to be hand tweaked, that’s easier to do if you have a full control and understanding of what’s going on. We all need to change how we think about presentation and I don't think any theme out of the box will be a good mobile experience for your content.
Now all you have to do is make it look good, but that’s really a whole other post.
Are you an aspiring web developer, fresh out of college and eager to dive into Philly’s exploding tech startup scene? Are you a growing startup or established company in need of talented developers to help take your business to the next level?
Zivtech was thrilled last week when Philadelphia Mayor Michael A. Nutter announced that we were one of five winners of Startup PHL’s second round of Call for Ideas Grants, for a 6-week Web Development Bootcamp. We are hosting and teaching this bootcamp along with another awesome Philly web development firm--Neomind Labs--the goal of which is to allow us to share our expertise with, and help create job opportunities for, the next generation of Philly-based professional web developers.
We at Zivtech have been working with Drupal for a long time, some of us for over 10 years, and in that time we’ve gotten to use (and sometimes build) a lot of really cool modules to develop stellar sites for our clients. We have sifted through thousands of modules on Drupal.org, going far beyond the first couple pages of results and venturing deep into the unknown, unheard of, and ultimately under-appreciated modules. We sent out a question to our staff to ask for their favorite obscure modules, and we've compiled this list to share some of these modules that we have found particularly helpful, and to help ensure that they don't fall through the cracks. All of these modules have fewer than 8,000 active installs, and most have under 5,000.
As a Senior Developer here at Zivtech, part of my job is to develop with an eye towards security. If you follow development and security news, you know that achieving security is pretty hard in complex systems. But, while correctly implementing security across a site is challenging, some aspects of security are actually pretty easy and we've known what to do and what not to do for a long time.
Introducing Bear Skin, a comprehensive skin for Zivtech's Bear base theme.
The quality assurance (QA) phase of a web development project is the last phase before launch. While the development team has a lot of experience with QA phases, oftentimes the client team is new to the process, which can lead to stress. Let's prevent this with a little Q&A on QA.
Nominees for the 17th annual Webby Awards have been announced! And Zivtech-built sites are in the running for four awards!
This weekend 9 members of the Zivtech staff will be participating and competing in Startup Weekend Health Philadelphia 2013, which, according to their site, ”centers on building a web or mobile application that could be the basis for a credible business. After 500+ Startup Weekends world-wide, this will be the first dedicated solely to healthcare’s unique problems.”
We love Responsive Web Design, and we love Drupal. But do they love each other? After working on a number of RWD and Drupal projects this year, I'm happy to report that they get along just fine. Though "Love" might be stretching it a bit.
I've worked on many "Site Rescue" jobs, in which a client comes with a sick, but often brand-new and expensive Drupal site, desperately needing it fixed in a number of ways. Through this work I've seen a lot of patterns of "worst practices" employed. I enjoy the challenge of this cleanup work, while feeling bad for the clients who have been taken by incompetent vendors. I refer to these sites as "lemons" and I've made a study of their characteristics.