Responsive Layout for Wordpress
I'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.