Technically Feasible

Responsive Layout for Wordpress

Likeness of Michael Oldroyd
Michael Oldroyd
⚠️ This content was imported from a previous incarnation of this blog, and may contain formatting errors

WordPress LogoI've been working on a few tweaks to improve accessibility on mobile devices. Since obtaining a shiny new Samsung Galaxy Note 2, I'm finding myself using my mobile device more than ever. The redesign earlier last year allowed me to introduce some initial steps toward a responsive layout, but it was and still is an unfinished product.

I have finally got round to implementing sidebar folding at low resolution. I'm the using adjacent sibling selector (+), the :checked pseudo-selector, and HTML <input> hacks (<label>, radio and check-box <input> elements). This technique also works great for folding the main navigation at low resolution using a check-box.

Implementing the Responsive Layout Elements #

The folding technique is derived from this CSS accordion technique. I find the lack of reliance on JavaScript to be attractive; it remains to be seen whether this improves browser support due to the use of :checked and sibling selectors.

The HTML structure below provides the basis for the sidebar. As is standard with Wordpress' sidebar output, each widget is wrapped within an <li>. A <label> element wraps the heading, which will target the hidden <input> element through the for attribute. The <input> element's id must match the for attribute value to allow the <label> to interact with it. You can implement either check-box or radio type <input>s, which will provide different interactions. Radio buttons allow just one section to be toggled; give them the same name to group them. Check-boxes allow multiple items to display simultaneously.

The input element will be hidden using CSS as we don't want them to be displayed. I only wanted the accordion functionality to apply when in single-column mode, so I wrapped the two selectors in a @media query. I've stripped it down to the bare minimum for sake of clarity;

.sidebar .accordion-selector {
 display: none;
}
@media screen and (max-width: 960px) {
 .sidebar .widget-content {
  display: none;
 }
 .sidebar input.accordion-selector:checked + .widget-content {
  display: block;
 }
}

Implementing the Markup in a Sidebar #

The difficult part is getting the HTML structure in place, within the confines of Wordpress' template and widget system. You have to include a unique ID for the input as mentioned, so the <label> can include this in it's for attribute to activate the hidden <input>. This mark-up needs to be included in the before_title and after_title parameter of the register_sidebar function call. Unfortunately though, the Wordpress API doesn't perform variable substitution on these attributes.

register_sidebar(
  array(
    'name'       => __('Sidebar'),
    'id'      => 'sidebar',
    'description'   => __('Sidebar'),
    'before_title'  => '',
    'after_title'  => '',
    'before_widget' => '',
    'after_widget'  => '',
  )
);

As we need some substitutions performing on the before_title sidebar attribute, allowing us to hook into widget generation to force some values. We need to hook the dynamic_sidebar_params filter to alter this output. My implementation is far from complete but it allows the widget ID to be included in the "title chrome":

function filter_sidebar_params($params) {
  
  $id     = $params[0]['id'];
  $the_id = $params[0]['widget_id'];
  $title  = $params[0]['before_title'];
  $after  = $params[0]['after_title'];
  
  $params[0]['before_title']  = sprintf($title,$the_id,$id);
  $params[0]['after_title']   = sprintf($after,$the_id,$id);
  
  return $params;
}

add_filter('dynamic_sidebar_params','filter_sidebar_params');

Implementing for Navigation #

Implementing a folding navigation bar is a simpler task; we simply need to embed a clickable <label> and hidden check-box input into the template directly before the navigation container.

The functionality is the same here as it is with the sidebar; the <label> will toggle the <input>, in turn toggling the <nav> element's visibility. The only difference is that we need something to toggle. In the sidebar example, we used the title as the content of the label; this can be anything but it ought to be a clear navigation indicator.

It may not be the most semantic implementation, but anything must be little better than navigation by <select> element?

Next Steps #

I'm not sure on the next evolution for the drop-down navigation. I'm not a fan of the horizontal navigation links as they are when in the "low profile" mode. When I figure out what's best I'll follow up if it's noteworthy.

Image of me

Michael Oldroyd

Michael is a Software Engineer working in the North West of England.