Working around a lack of element queries

Posted by Scott on 06/21/2013

Topics:

Lately, we've been running into a recurring dilemma when building responsive designs. We want to build responsive layouts comprised of many modular, independent HTML components that fluidly fill any layout container we drop them into, but CSS3 media queries don't currently offer a way to make content respond to its container's dimensions (as opposed to the overall viewport size).

Nearly all of the layouts we're building here at Filament Group these days, even the simplest stuff, would be easier to build using media queries that considered a component's constraining parent element—whether it be a proportional column container within the page or even a container like body or html — and not the browser viewport. If element-based queries were possible, we could build breakpoints articulating how each component should appear when displayed at various widths—regardless of its surrounding containers—and our components' styles would be more self-contained and sustainable across a site.

Unfortunately, we don't yet have element-based CSS3 media queries, and we may not for a long time. As a result, we've needed to find workarounds of our own. So far, we've landed on varying hard-to-maintain overrides and repetitive styles to make components work within different containers each time a new template is needed.

It'd be great to find a better way.

An Example Problem

Let's say we have a responsive weekly schedule component. The component has two major layout breakpoints depending on available space: at narrow widths, schedule is presented as a list, while at wider widths it displays as a calendar grid. The minimum width at which the schedule can break to the wider layout is around 32.5em (or 520px).

Fig. 1a: Narrow breakpoint design. illustration of a weekly schedule component at small breakpoint. Fig. 1b: Wide breakpoint design. illustration of a weekly schedule component at large breakpoint.

The schedule component can appear in two page templates on our hypothetical site: the schedule template and the homepage template. In each of those templates, the schedule component is contained by an element of different dimensions. On the schedule template, the schedule component is contained by a full-width .content element, and in the homepage template, the component sits within an aside element in a narrow-width column.

When placed within these templates, you can see how viewport-based media queries become problematic. Our schedule presents quite well in its primary context, the full-width schedule template (Fig. 2a):

Fig. 2a: Schedule component in its primary context: Wider breakpoint styles work great within the full-width schedule template. illustration of content component example in schedule page template.

But that same markup it is completely unusable when dropped into the homepage template (Fig. 2b), where the viewport-based media queries attempt to style it for the large breakpoint presentation despite a much smaller container size:

Fig. 2b: Schedule component in its secondary homepage context: the larger viewport applies wider breakpoint styles, rendering it unusable. illustration of content component example in homepage template

Ideally, we want our schedule component to adapt to its available containing element width, which has little to do with the viewport width. If element queries were possible, our breakpoints would allow the component to respond to its container and present itself appropriately, as shown in Fig. 3:

Fig. 3: Our Goal: the schedule component displayed in the homepage template but adopting styles appropriate to the container size (if element queries were possible). illustration of content component example in homepage template with ideal styling

Without element queries, it takes a lot of manual work—redundant styles, complex exception cases and workarounds—to pull this off, and the problem compounds itself depending on how dramatically a widget adapts at each of its breakpoints. For example, to make our schedule component appropriately switch from its smaller list-style view to the larger grid-style in the homepage template, its viewport-defined breakpoint would need to be closer to 90em, instead of the 35em that works for the schedule template. Perhaps a tool like SASS could help simplify this problem for us in the meanwhile.

Approach 1

One approach to this could be pretty simple.

We could start by splitting the CSS styles for each of a the component's breakpoints into separate CSS files (or .scss files in this case):

- schedule-sml.scss
- schedule-lrg.scss

We could then create two more CSS files that use SASS to include these 2 breakpoint files inside our respective template-based breakpoints, and reference one file or the other from our HTML templates (schedule.html or homepage.html). Here's how those files would look (note that SASS would pre-include the files into a single compiled static CSS file):

schedule.scss (compiles to schedule.css):

@import component-sml.scss;
@media (min-width: 32.5em){ @import component-lrg.scss; }

homepage.scss (compiles to homepage.css):

@import component-sml.scss;
@media (min-width: 90em){ @import component-lrg.scss; }

In schedule.html:

<link rel="stylesheet" href="schedule.css">

In homepage.html:

<link rel="stylesheet" href="homepage.css">

This approach actually works pretty well for this particular problem. There's a downside, though: these CSS rules cannot coexist in one template because their styles will collide with one another. It would be ideal for us if the styles could coexist in a template (in a single stylesheet), especially because we commonly have situations where a component can exist within two different HTML containers simultaneously in the same template at a single viewport size — for example, we might want to display the same component at its medium size in the body of the page content and also show it at the small size inside a modal dialog that is narrow and centered on the screen.

Approach 2

To address this additional challenge, a second approach could be to create a SASS mixin that creates separate media queries containing the same block of layout styles, each with selectors that are prefixed to make them only apply in one container context or another. The intended output CSS for the two first breakpoints of the component could look something like this:

@media (min-width: 32.5em) {
    .content .schedule-component {
        ...styles here...
    }
}

@media (min-width: 90em) {
    aside .schedule-component {
        ...styles here...
    }
}

Now, I'm no SASS expert, so I'm not sure what sort of input syntax would be needed to produce this output. I think something like this would be pretty nice to work with, though:

@include elementquery( 
    {
        ".content": "(min-width: 32.5em)", 
        "aside":    "(min-width: 90em)"
    } ) {
    /* styles for this common layout breakpoint go here */
    .schedule-component {
        ...styles here...
    }
}

That said, a brief look at the SASS documentation suggests that SASS doesn't accept object syntax for an argument, so this syntax may not be possible.

It's worth noting that a drawback to the compiled output of this approach may be redundancy in our CSS. That said, gzip compression might actually render that overhead null, so the transfer size would be relatively the same as if the duplication wasn't there.

Any ideas?

The lack of element queries can be problematic when trying to write components that are modular and able to adapt to varying layout conditions. For now, Approach 1 above is a workable solution, but it requires that variations live in separate templates, and that doesn't usually meet our needs.

We'd love to see a SASS mixin that allows us to use Approach 2, since it seems like an easier system to maintain across many templates and widgets. Any Savvy SASS experts out there? Also, if you have any other ideas about working around this issue (preferably ideas that do not require JavaScript), please let us know!

Book cover: Designing with Progressive Enhancement

Enjoy our blog? You'll love our book.

For info and ordering: Visit the book site

Comments

I agree that this is a big pain in the butt! We want to create a system where content blocks are styled properly regardless of where they are placed on a page.

Your option #2 made me think about about the power of a basic media query mixin, and how you can pass the contents of the mixin to more than one directive/selector.  I’ve done this in the past where I pass my layout media queries to both min-width media queries and an .ie8 prefixed version of the selector. (Like this https://gist.github.com/micahgodbolt/5406759)

So thinking about the problem, we want the style of your calendar to switch from “full” to “condensed” under 2 different circumstances.

#1 is if the media browser drops under a certain width (say 500px). In that case the calendar should always be “condensed” because there is no room in any parent container for the “full” version.

#2 in it’s simplest terms, is when the calendar is displayed in a parent element that we know will never be large enough for a “full” version. In this case, we can simply change the selector from .calendar to .sidebar .calendar and pass in the same styles without the media query.  http://codepen.io/micahgodbolt/pen/qjFnB

Now this makes the assumption that the sidebar will never be large enough for the full version, and it could probably be improved upon. But this is a way to write “media queries” where we can also pass in the class names of containers where we want the calendar to always display in “condensed”

Comment by Micah Godbolt on 06/21  at  07:55 PM

I’ve been thinking about this for a while, and while it’s plainly obvious from a designer’s perspective that deriving context relative to specified containers makes the most sense, I can see why it’s not likely from a technical implementation standpoint. The problem boils down to: “a container’s width depends on the width of its content, but if the content’s width may depend on the container space available, you can never define either width”. It’s chicken and egg and isn’t something that can be worked around without compromises.

So the best theory I’ve come up with (that I’ve yet to try) is to abandon CSS for layout. Because, frankly, layout has always been the weakest aspect of CSS. Too many assumptions and too many high-level ‘solutions’ when all I want is low level tools to build my own solution. That’s a different (and years old) rant.

So, I’ve been thinking about using some JavaScript for basic layout and also abandoning media queries, because honestly they’re not what we want. They just aren’t. Instead, use JS as a templating engine:

1) Sense the size of the viewport via JS
2) Select from an array the layout template we’ve decided works best at that viewport size
3) Inject the layout template divs into the document
4) Tear the DOM apart and move the modules into those layout divs
5) Use class inheritance to style the modules instead of media queries

No JavaScript? Then you get the same old site as we always did, a nice mobile-first fallback. Or even a ‘responsive’ media query driven one.

Comment by Matt Wilcox on 06/21  at  08:05 PM

You could use JS to figure it out. Each module container would have a class of “.module-container”, then with JS you can loop thru containers and based on container width you can conditionally append “.small”, “.medium”, or “.large” class to immediate child element with class of “.module”.

Here is a very basic example: http://www.kolszewski.com/lab/element-query-workaround/

You will see changes in the browser (text before elements) and in Chrome Dev tools.

Comment by Kris Olszewski on 06/21  at  08:43 PM

Oops, just noticed you weren’t looking for a JS solution. My bad. Altho, I still think JS is a good workaround.

Comment by Kris Olszewski on 06/21  at  08:47 PM

I’m sure I’m missing something but could the ‘Clown car technique’ ( http://coding.smashingmagazine.com/2013/06/02/clown-car-technique-solving-for-adaptive-images-in-responsive-web-design/ ) be of any use here? It seems that media queries can be run from within an element that has an indeterminate width. Directly ported this might require a new html element to contain these EQs, but could some of the implementation techniques there be applied more broadly?

Comment by Jeremie Carlson on 06/21  at  09:21 PM

Not sure if something like this will be the solution…

https://gist.github.com/jpavon/5833682

Comment by Julio Pavon on 06/21  at  09:30 PM

Andy Hume raised similar concerns and thoughts in his article about Responsive Containers back in 2011 in which he proposes the so-called “element media queries”. Andy developed a script that allows developers to apply different class values to an HTML element based on its width which could be quite handy when it comes to this kind of problems. Not sure if it will help resolve your use-case, Scott, but it might be something worth experimenting with!

Comment by Vitaly Friedman on 06/21  at  09:37 PM

The described problem is very interesting. And I guess, it can’t be solved without JavaScript. As we lack object-media-queries we only can test for the whole design for problematic breakpoints.

Nevertheless, even if we had object-media-queries our life wouldn’t be any better, because we cannot wrtite:
@media box (if &#xb;o;x3 has not enough room) { /* rules */}

I made a test-pen in case you want to play with the sketched calendar:
http://codepen.io/jensgro/full/DmLkn

Totally irrelevant which sort of media-query we can use, you always have to look for the necessary room for your module. So where is the problem to react according to the envireonment?

I know that the true believers of OOCSS, SMACSS and BEM wouldn’t like to write CSS with repect to the environment. For most of the time this is totally true.

But if you MUST react on your environment, what argument is stronger than to write according to it?

Comment by Jens Grochtdreis on 06/21  at  09:44 PM

Couldn’t you do this with a nested grid instead of using media queries?

If the component is inside a 5-column element, use the narrow display, if it is inside a 12-column element, use the wide? You could use media queries at a top-level to determine the size of the columns… (Doesn’t the susy ‘magic’ grid do something sort-of like this?)

Comment by Charles Bandes on 06/21  at  10:22 PM

I’ve written the Element Query Sass mixin for you. Take a look:
https://gist.github.com/Snugug/5834818

It utilizes Breakpoint for media query handling (https://github.com/team-sass/breakpoint). If it works for you, I’ll add it to Toolkit (https://github.com/Team-Sass/toolkit)

Comment by Sam Richard on 06/22  at  12:31 AM

Slightly modified version of Sam Richard’s (without Breakpoint, so less powerful but might suit someone’s needs), making it usable like so:

.schedule-component {
@include element-query(’.content’ min-width 32.5em, aside max-width 90em) {
background: pink;
}
}

http://pastie.org/8067983
Codepen example: http://codepen.io/anon/pen/hrLqi

Comment by Rémy on 06/22  at  01:32 AM

+1 for Charles Bandes for mentioning Susy.  This and Compass will give you imho your Figure 3 ideal: abstracting and targeting component layout.  While not perfectly DRY, negligbly so and, as you mentioned, close to zero impact on file size.

Comment by Robin on 06/22  at  01:54 AM

The Sass mixin method is cool but doesn’t sit right with me because the CSS module now needs to have knowledge of its parent elements, so is no longer standalone & independent.

Element queries would be the best way to solve this, but in the meantime I would move the heavy lifting out of CSS and into the HTML templating engine:

https://gist.github.com/bensmithett/5835649

The default `.widget` class has no breakpoint-specific behaviour (i.e. mobile styles, but also how you want it to appear in the sidebar).
`.widget--respond` inherits `.widget`’s default styles as well as adding breakpoint-specific styles for the full page scenario.

The result is a CSS module that needs no knowledge of its parent container, and a standalone HTML component whose CSS behaviour can be configured on a per-scenario basis with arguments.

Comment by Ben Smithett on 06/22  at  05:18 AM

I’ve been working on solutions for this problem for a while. Similar to what Charles mentioned I have had the most success by doing all layout with a grid system and combining grid and media query contexts.  You can then say something like, look like “this” on large screens and look like “that” on small screens or large screens with a six column parent. That’s the basics anyway. You can get quite complex while still keeping the abstractions.

Sure it relies on a grid system, but I’ve found that’s given me the most consistency and tersest code.

Comment by Luke Brooker on 06/22  at  12:41 PM

The idea of container element based queries is an excellent one. In the case of the appointments illustration above however; the two views could easily be handled by just giving the narrow and full width their own CSS classes.

Comment by maxw3st on 06/22  at  02:20 PM

In my opinion, this is kind of dumb. While I can’t argue container-queries could be powerful, they are completely unnecessary even in this example. Here, you have both the full and small styles and you know exactly when and how to style them. Simply target them and give them the appropriate styles in the certain criteria. When you’re styling the containers on the page, and can always be aware of their width. Thus, you can always style your widget correctly.

Comment by rgthree on 06/22  at  06:05 PM

I really don’t think there’s a need for some crazy css workaround. 4 lines of script will do exactly what you need.

if(schedule[removed].offsetWidth > smallBreakpoint)
schedule.classList.add("large");
else
schedule.classList.add("small");

Browsers without javascript? How often do you see that?

Comment by Joshua Beckwith on 06/22  at  08:49 PM

Comment by Dr. Q on 06/22  at  10:25 PM

> Browsers without javascript? How often do you see that? [1](http://filamentgroup.com/lab/element_query_workarounds/#commentNumber17)

The wise words of [Jake Archibald](https://twitter.com/jaffathecake/status/207096228339658752) spring immediately to mind.

Comment by Ethan on 06/23  at  05:38 PM

Would an iFrame work?

Comment by emehrkay on 06/24  at  02:23 AM

You’re asking the wrong question. When you talk about components you should be talking about content, not presentation. That is, a calendar component is talking about something with the content of a calendar. The presentation of the calendar should not be the responsibility of the component. When you look at things this way, the problem changes.

Now it’s a matter of: How do I present a page where I don’t know the content? Your first example is fine, in fact: you just import the appropriate presentation format for the appropriate document.

However, if you have the same component many times, and you want it to be presented differently, how do you present it?

Well, you just have more specific presentation for each content type. For example:


@media (min-width: 32.5em) {
.content {
@import("schedule-component-lrg.scss");
}
.aside {
@import("schedule-component-sml.scss");
}
}

Remember, when presenting, think about presenting the whole page, and when creating components, think of the content component as fitting together separately, and presentation being separate!

Comment by Sunny Kalsi on 06/24  at  06:45 AM

It’s good to see more and more articles like these pop up. Up until 6 months ago there was hardly anything being said about element queries.

As for solutions, you won’t get far without js I’m afraid, even then it’s pretty tough and hardly production-proof. But it’s often decent enough for prototyping purposes. One thing I’ve been thinking about is using scoped css for responsive views, haven’t gotten around to writing the javascript but if you could include the scoped css for a specific component in a specific view, that would be pretty useful (and you would be avoiding conflicts.

Good example btw, but real life is a bit more complex, especially when you have more than 2 views of one component and paddings/margins/borders all impact the effectively available with of your component.

Comment by Niels Matthijs on 06/24  at  02:29 PM

This js lib can add/remove classes based on element width/height. It is configured via data- attributes in the html: https://github.com/ahume/selector-queries

And someone made a fork of the above that allows configuration in CSS: (so you could create a SASS mixin to output them):
https://github.com/ahume/selector-queries/issues/6

Also, this js lib can add classes based on element width/height and looks more versatile but requires configuration in JS: https://github.com/jonathantneal/MediaClass

Comment by Sam Hasler on 06/24  at  03:52 PM

Thanks for the feedback, everyone.

The Sass mixin ideas are particularly appreciated. I’m not sure the examples above are quite going to achieve what we’re looking for, but they’re close. We’ll comment on the Gist to see if there’s more to it that we’re missing (which is likely!).

Ethan’s comment echoes our sentiments on a JS-dependent solution for this problem. The performance drawbacks of a JS-driven layout system are considerable, and best avoided when compared to the optimizations that come naturally with CSS. So while we appreciate the effort, we’re mostly interested in approaches that use CSS alone.

On the simple nature of the problem scenario: The example in the article is purposefully simple, and we certainly run into more complex situations in real work scenarios. Targeting styles at each container may work just fine for this example, but solving this problem generically is what we’re interested in, as it would lead to a broader reusable approach for the real issues we’re hitting.

Comment by Scott (Filament) on 06/24  at  04:30 PM

For any Sass experts following along, I’ve expanded on the problem in the comments of one of the gists posted above. We’d love some help!

https://gist.github.com/jpavon/5833682#comment-851024

Comment by Scott (Filament) on 06/24  at  05:18 PM

I think in SMACSS styling based on context is discouraged. Doing things the SMACSS way you would probably do something like this:

<div class="schedule-component schedule-component-large">
<div class="schedule-component schedule-component-small">

your markup is a bit more verbose now but you save yourself from confusing SASS mixins or JS options. In fact, I don’t think you need media-queries at all with this approach. You just style things that are common under the .schedule-component class and implementation specific details in .schedule-component-large or .schedule-component-small.

It also has the benefit of not being tied to .content or aside in case you need to use the components in a different container.

Comment by Rob Dodson on 06/24  at  07:29 PM

My take on this is more of a workaround than a real solution, but it works for me in my project. Basically I define a default look & feel for the component. Without any extra actions, that is how the component will look. However, in case a specialized look is needed, I simply use per-page styling. The HTML or body tag has the page or template identifier, which can then be used as a hook into switching to the specialized look & feel.

It’s not pretty, but it works. However, after reading the comments here I liked the idea of having it based on parent content better. The styling depends on the markup of the parent, i.e. the distinction between an article and aside tag.

Comment by Ferdy Christant on 06/24  at  08:30 PM

Hi Scott, great post. This is something that I started thinking about a few months ago. I know you said you’d prefer ideas that do not require JavaScript but I have one that is different from the others that have been posted so far. I just pushed it up to https://github.com/jasonadelia/Elementary.

It is basically Respond.JS but for element queries. You write your element queries in your stylesheet using a @element["selector"] syntax and on page load or resize the script runs and checks if the element (defined by the selector) meets the specified size. If it does, the styles within the element query block are added to the page.

Have a look at the README for more detailed information on how it works:
https://github.com/jasonadelia/Elementary#elementary

And check out the demos:
https://github.com/jasonadelia/Elementary#demos

Would really appreciate any feedback anyone has.

Please note:
I have not used this anywhere other than these demos and haven’t done extensive performance or browser testing. But, once I saw this post, I wanted to get it out in the community to see if it was something worth pursuing further.

Comment by Jason Delia on 06/24  at  08:54 PM

Quick update!

So far, this gist by Micah Godbolt and Julio Pavon appears to meet our needs. We’ll give it a test soon to see. https://gist.github.com/micahgodbolt/5851228#comment-851142

Comment by Scott (Filament) on 06/24  at  11:49 PM

Hi Scott,
I am a little bit puzzled. Your preferred solution does nothing more I sketched before on codepen. The solution reacts on certain window-widths, adjusted with media-queries.

The module doesn’t adjust automagically with the environment. How should it do it? The solution is “only” a clever Sass-mixin. That is worth to be saved but I understood you searched a better solution.

And that better solution does actually only work with JavaScript. But what should be wrong with JS? We would have a fallback and the more we develop with HTML5 the more we must use JS, because HTML5 is mainly JS.

Besides the “solution”: do you have an idea how your preferred elemental queries should look ike? If yes: propose it to the W3C. I would be glad to use them in about 15 years or so :-)

Comment by Jens Grochtdreis on 06/25  at  07:43 AM

What about markup? The small version seems more like a list than the larger one, where a table would be more suitable. Forcing a table’s layout to look like a list seems a bit backwards to me. Would be interesting to hear your opinion on that. Maybe a bit off topic, but still an important question.

Comment by Andy on 06/25  at  05:10 PM

Hey Jens,
We appreciate your input. Thanks!

As noted in the original post and comments that follow, in this case we’re interested in a CSS based solution for all of the benefits in performance and flexibility that come from utilizing native layout features that browsers are optimized to perform. The example problem in the article is purposefully simple for explanatory purposes, but in reality, we use many types of media queries that don’t always have to do with viewport or element size (screen density being one), and we often encounter and manage many of these scenarios while working on a single codebase.

We’re certainly not against using JS here at FG – check out our Github page for loads of primarily JS-based techniques we recommend – but we do find that it’s important to avoid JS-driven page layout as much as we can. Layout reflows are costly to rendering performance and can complicate a smooth loading experience for users, so we try to reduce our layout reliance on the delays incurred waiting for JS to load and evaluate when we can.

The mixin linked above, it’s not ideal and indeed far from a self-sustaining module, but it does go a long way towards streamlining the maintenance side of things when styles ned to be repeated for different conditions. It’s just the sort of thing we were looking for while we wait for a more standard approach. We’ll post an update to outline its use soon.

Thanks again!

Comment by Scott (Filament) on 06/25  at  06:06 PM

Hey Andy!

Good question. Actually, we often do use a table element for this sort of problem, but it depends on the content. Regardless, you can find some techniques we’ve created for linearizing tables in the jQuery Mobile project demos: http://view.jquerymobile.com/master/demos/widgets/table-reflow/ and http://view.jquerymobile.com/master/demos/widgets/table-column-toggle/

Comment by Scott (Filament) on 06/25  at  06:10 PM

Settle an argument for me?

In your example with the calendar, are the first and second examples two different HTML documents, or are they in the same HTML but seen in two different viewports?

Comment by Bon Chic Bon Scott on 06/26  at  01:37 AM

Bon Chic Bon Scott: sorry if that was unclear. The example was two separate templates, but in reality, we often deal with this problem for different portions of one template too.

Comment by Scott (Filament) on 06/26  at  01:39 AM

Thank you.

Comment by Bon Chic Bon Scott on 06/26  at  03:47 AM

> “Browsers without javascript? How often do you see that?”
(http://filamentgroup.com/lab/element_query_workarounds/#commentNumber17)

Be careful thinking along such lines. Bandwidth and latency issues (heavy emphasis on latency) wreak all sorts of havoc when there is a Javascript dependency. That’s the reason for trying to solve as much as possible without it.

I love what JS brings to the table for development. But I know I can’t count on it being there when I need it. There are way too many points for failure before the bits and bytes reach the user.

Comment by Bridget Stewart on 06/26  at  03:09 PM

Tying your module styles to its parent container seems to go against the idea of independent HTML components that can be placed anywhere in a template. I prefer to use the solution similar to what Rob Dodson was talkin about, using classes for the different modifications to your module.

It’s common to do this with buttons, you’ll see things like .btn and then .btn--primary, .btn--warning. The concept is similar, its just that the modifier class would be in a media query.

I’ve put together a demo on codepen. http://codepen.io/bjankord/pen/nAGFe The markup I built off of came from David Bushell’s responsive calendar - http://dbushell.com/2012/01/04/responsive-calendar-demo/

In the demo I have the .schedule-component class that always stays in list view and then I have a modifier class named .schedule-component--grid that will switch from list view to grid view at larger viewports.

I’d be interested to hear your thoughts on this.

Comment by Brett Jankord on 06/26  at  03:39 PM

Thanks Brett,

We agree that the mixin is not self-sustaining like an element query would be, but it does dramatically reduce the work required in qualifying the point at which a component’s breakpoints are applied depending on its template (which is a big help).

Classing the component itself as opposed to a parent selector would be a fine solution as well; we used the parent selector in this article for ease of example. That said, your example doesn’t quite do what we’re trying to achieve. While the sample component may not be an ideal example, the problem we constantly run into is more about components that _always_ adapt from one layout to another, not just sometimes - the challenge is merely that the breakpoint at which it makes sense to shift a component’s layout from one display to another depends on the environment the component is placed within.

So, while we could certainly add a class to keep the schedule displayed as a list at all times, that’s not really what we’re looking to achieve - instead, we’re looking to qualify the conditions at which the wider layout styles are applied depending on the template in which our component resides (due to our given knowledge of that template’s layout, of course). In the “homepage” template, the component’s breakpoint comes at much wider breakpoints, but it still happens. The point is that we do always want the component itself to respond when there’s adequate room to do so. 

I hope that makes it a little clearer.

Comment by Scott (Filament) on 06/26  at  04:10 PM

>> Tying your module styles to its parent container seems to go against the idea of independent HTML components

On the contrary, classing your html components goes against making independent HTML components ... because the HTML is different. Instead of using HTML for describing what a component is (and sticking to that HTML), you’re tying it to the style it is supposed to receive.

Comment by Niels Matthijs on 06/26  at  04:22 PM

Thanks for this post. This is a problem that needs solving.

I have used the responsive containers script by Andy Hume successfully in the past to deal with this problem but it’s still a JS dependency as mentioned. You don’t want to keep reflowing your UI through JS calls since that leads to all kinds of redraw/performance problems.

The improved version of the Sass mixin ( https://gist.github.com/micahgodbolt/5851228 ) looks like it will be nice in use but let’s not kid ourselves - this is just a fancy version of scoping your CSS to different parts of the page.

You don’t want a dependency on containers. You want a HTML + CSS combo that can be dropped in anywhere, without depending on it being a child of a certain div.

This discussion is bigger - all of this ties nicely into web components and CSS style encapsulation: (also see https://github.com/Wolfr/css-encapsulation-today)

I believe the goal here is to have components that are transferable from project to project and are not constrained by any external choices. (for example class nesting/grid systems).

The only way to do it properly is by being able to detect the size of an element at any given time in CSS.

Until then, you can make your SCSS extremely hard to read with all sorts of crazy mixins - or maybe just progressively enhance with JS?

Comment by Wolf on 06/28  at  08:50 PM

Not sure if this was answered or not, but here’s an example of what you’re looking for in SCSS: https://gist.github.com/procload/5912563

Does this do the trick?

Comment by Ryan Merrill on 07/02  at  09:56 PM

Hey Ryan,
Thanks. Close but we found this one to meet our needs really well https://github.com/filamentgroup/scoped-media-query

Comment by Scott (Filament) on 07/02  at  10:05 PM

I am currently looking into possibility of using any of these to accomplish the same goal:  https://github.com/jonathantneal/MediaClass https://github.com/bkardell/Hitch/

Comment by Mark Bajkowski on 07/04  at  09:55 PM

Commenting is closed for this post.

Book cover: Designing with Progressive Enhancement

Enjoy our blog? You'll love our book.

For info and ordering: Visit the book site