{"id":3385,"date":"2013-05-09T09:26:52","date_gmt":"2013-05-09T09:26:52","guid":{"rendered":"http:\/\/blog.cloudfour.com\/?p=3385"},"modified":"2016-07-08T22:25:44","modified_gmt":"2016-07-08T22:25:44","slug":"behavioral-breakpoints","status":"publish","type":"post","link":"https:\/\/cloudfour.com\/thinks\/behavioral-breakpoints\/","title":{"rendered":"Behavioral Breakpoints: Beyond Media Queries"},"content":{"rendered":"<p>Recently, Cloud Four dev Matt Gifford built a slick, responsive <a href=\"http:\/\/www.lukew.com\/ff\/entry.asp?1569\">off-canvas<\/a> navigation enhancement for a project (we&#8217;ll be releasing the core code shortly, so keep an eye out for Matt&#8217;s post about that!).<\/p>\n<p>The project followed the off-canvas menu metaphor for handling navigation on narrow screens. The baseline, mobile-first layout keeps the navigation out of the way\u2014initially as footer nav with a button-ish jump link, then progressively enhanced to convert the link into a trigger element for the off-canvas menu\u2014while a media query for wider screens formats the navigation on-screen.<\/p>\n<p>A sketch of this layout adaptation:<\/p>\n<p class=\"u-textCenter\"><a href=\"https:\/\/cloudfour.com\/wp-content\/uploads\/2013\/05\/offcanvasmenu-states.png\"><img src=\"https:\/\/cloudfour.com\/wp-content\/uploads\/2013\/05\/offcanvasmenu-states.png\" alt=\"offcanvasmenu-states\" width=\"396\" height=\"170\" \/><\/a><\/p>\n<p>In the past we&#8217;ve approached implementation of this as:<\/p>\n<ol>\n<li>Implement a baseline CSS layout that has a menu button.<\/li>\n<li>Use a CSS media query to adapt the layout for wider screens, hide the button, reflow the nav.<\/li>\n<li>Use JavaScript, often bound on window.resize, to check media query applicability and adapt behavior accordingly (sometimes alternately handled by looking at the width of the viewport and comparing it to media-query-defined widths).<\/li>\n<\/ol>\n<h4>Bolting on Behavior<\/h4>\n<p>Often by the time we get to the behavior implementation of our sites and apps, the process involves bolting on JavaScript as a follower of the CSS-based breakpoints that we&#8217;ve generated during the design process. We define the <em>visual<\/em> breakpoints of our stuff and the JavaScript is expected to use those to indicate how it should behave.<\/p>\n<p>So we bump into things. We want the JavaScript to &#8220;know&#8221; about the breakpoints defined in CSS, and which media queries are presently active. This leads to heartache, and also some pretty clever hacks. We use matchMedia (or a polyfill to support same) to determine whether a particular, specific media query is active.<\/p>\n<p>Thus: duplicating media queries in two places (CSS and JavaScript), a situation that makes a whole lot of us twitchy. I have definitely fantasized about future CSS module spec revisions that allow for naming and scoping of media queries, to make stuff like this better.<\/p>\n<p>But hold on a minute. What are we trying to accomplish here? Does CSS really hold a monopoly on breakpoints? Should our behavioral components be entirely beholden to the specific formulae of our visual layouts?<\/p>\n<h4>(Re-)Defining Breakpoints<\/h4>\n<p>But why is the breakpoint for menu\/navigation behavioral adaptation entirely linked to a CSS concern? Could there be better  indications in the browser that the behavior change is appropriate, beyond a CSS media query or screen width? And, in that case, what <em>does<\/em> define the breakpoint?<\/p>\n<p>This sort of thing was already on my mind when I started reading <strong>Stephen Hay&#8217;s<\/strong> excellent new book, <strong><em><a href=\"http:\/\/www.amazon.com\/Responsive-Design-Workflow-Stephen-Hay\/dp\/0321887867\" title=\"Responsive Design Workflow on Amazon\">Responsive Design Workflow<\/a><\/em><\/strong>. And Stephen is thinking about these things, too\u2014except he&#8217;s already a lot further along!<\/p>\n<p class=\"u-textCenter\"><a href=\"http:\/\/www.amazon.com\/gp\/product\/0321887867\/ref=as_li_ss_il?ie=UTF8&#038;camp=1789&#038;creative=390957&#038;creativeASIN=0321887867&#038;linkCode=as2&#038;tag=lyzdangar-20\"><img src=\"http:\/\/ws.assoc-amazon.com\/widgets\/q?_encoding=UTF8&#038;ASIN=0321887867&#038;Format=_SL110_&#038;ID=AsinImage&#038;MarketPlace=US&#038;ServiceVersion=20070822&#038;WS=1&#038;tag=lyzdangar-20\" ><\/a><\/p>\n<p>Stephen&#8217;s way of defining a breakpoint is: &#8220;<strong>the points where certain aspects of a website or web application change depending on specified conditions<\/strong>.&#8221;<\/p>\n<p>No mention of CSS there\u2014because the picture is bigger than that. As Stephen continues on to say, &#8220;[a]nother reason to consider a more full definition of breakpoints is that CSS is not the only method used to implement changes when a breakpoint has been reached.&#8221;<\/p>\n<p>Exactly!<\/p>\n<h4>Breakpoint Graphs<\/h4>\n<p>To express and plan breakpoints, Stephen advocates the use of breakpoint graphs, an adaptation on bullet graphs he&#8217;s invented to communicate both visual and behavioral aspects of breakpoints.<\/p>\n<p>Along the &#8220;qualitative&#8221; axis (horizontal in these examples), one charts a scale. Often, this is a range of screen width resolutions\u2014the way we tend to think about responsive design and breakpoints.<\/p>\n<p>Using the process from above, we might have a breakpoint graph that looks like this:<\/p>\n<p class=\"u-textCenter\"><img src=\"https:\/\/cloudfour.com\/wp-content\/uploads\/2013\/05\/first-graph.png\" alt=\"first-graph\"><\/p>\n<p>Thus, we&#8217;ve expressed that we have a breakpoint at 40em that alters the page layout.<\/p>\n<p>But Stephen&#8217;s graphs go further than this visual design element. Using qualitative &#8220;bands,&#8221; Stephen&#8217;s graphs can communicate behavior or other aspects, like so:<\/p>\n<p class=\"u-textCenter\"><img src=\"https:\/\/cloudfour.com\/wp-content\/uploads\/2013\/05\/graph-2.png\" alt=\"graph-2\"><\/p>\n<p>This is starting to move toward thinking about behavioral changes as well as visual ones, expressing explicitly that we want to adapt navigation behavior, but the breakpoint is still owned and defined in terms of the CSS breakpoint: 40em. So it&#8217;s natural that we&#8217;ve been creating media queries:<\/p>\n<p><code>@screen only and (min-width: 40em) {}<\/code><\/p>\n<p>and the JavaScript corollary<\/p>\n<p><code>if (window.matchMedia( \"screen and (min-width:40em)\" )) { }<\/code><\/p>\n<h4>Behavioral Breakpoints<\/h4>\n<p>Looking at breakpoints in such a clear way inspired me. I&#8217;d seen the screen-width-resolution-style graphs before, but the qualitative dimension was new and exciting. In fact, it frees us from tying our breakpoints to a visual or CSS source at all.<\/p>\n<p>What is the breakpoint, in the case of the navigation menu example here?<\/p>\n<p>When implementing the navigation behavior, Matt chose to use the state of the triggering button as the indicator for which kind of menu behavior to apply. Button extant and visible? Convert the navigation behavior to the corresponding off-canvas menu. Button gone? Deactivate the off-canvas menu and use on-page navigation. Matt does this by observing the state of that button and reacting accordingly, not by duplicating or checking on the status of the CSS media query that put it there in the first place.<\/p>\n<h4>Building Behavior into the Process<\/h4>\n<p>A behavior-centric breakpoint graph for this could look something like this:<\/p>\n<p class=\"u-textCenter\"><img src=\"https:\/\/cloudfour.com\/wp-content\/uploads\/2013\/05\/graph-3.png\" alt=\"graph-3\"><\/p>\n<p>where <strong>the breakpoint is the state of the trigger button<\/strong>. Yes, the state changes at 40em as a result of a CSS media query, but <strong>it&#8217;s the state we care about, not the media query<\/strong> (or window width) that did it.<\/p>\n<p>Stephen&#8217;s book does an excellent job of pushing the notion that behavior needs to be a part of our responsive design processes, integrated and partnered with visual design, not just adjunct to or beholden to it. Breakpoints span various aspects of the overall experience, and I&#8217;m glad Stephen helped me really understand this.<\/p>\n<p>Thanks!: <em>my gratitude to <a href=\"https:\/\/twitter.com\/stephenhay\" title=\"Stephen Hay on Twitter\">Stephen Hay<\/a> for his personalized help in making breakpoint graphs, <a href=\"https:\/\/twitter.com\/mattg\" title=\"Matt Gifford on Twitter\">Matt Gifford<\/a> for the off-canvas menu idea that got me thinking and <a href=\"https:\/\/www.twitter.com\/tylersticka\">Tyler Sticka<\/a> for a bit of sketching help and proofreading.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently, Cloud Four dev Matt Gifford built a slick, responsive off-canvas navigation enhancement for a project (we&#8217;ll be releasing the core code shortly, so keep an eye out for Matt&#8217;s post about that!). The project followed the off-canvas menu metaphor for handling navigation on narrow screens. The baseline, mobile-first layout keeps the navigation out of [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[233,240,3,241],"tags":[],"class_list":["post-3385","post","type-post","status-publish","format-standard","hentry","category-css","category-javascript","category-mobile-web","category-rwd"],"acf":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/cloudfour.com\/wp-json\/wp\/v2\/posts\/3385","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudfour.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudfour.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudfour.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudfour.com\/wp-json\/wp\/v2\/comments?post=3385"}],"version-history":[{"count":0,"href":"https:\/\/cloudfour.com\/wp-json\/wp\/v2\/posts\/3385\/revisions"}],"wp:attachment":[{"href":"https:\/\/cloudfour.com\/wp-json\/wp\/v2\/media?parent=3385"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudfour.com\/wp-json\/wp\/v2\/categories?post=3385"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudfour.com\/wp-json\/wp\/v2\/tags?post=3385"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}