Zero-D
Everybody starts using CSS with a single file that contains all the styles.
1D
Soon it becomes bulky and one decides to group CSS in a number of files by page elements:
html_elements.css
header.css
main-area.css
footer.css
Some may find this not convenient enough and group styles by function:
typography.css
layout.css
sticky-footer.css
(contains declarations for many elements, not footer only)
2D
When a project has a lot of CSS, it might require using both groupings simultaneously. CSS files structure becomes two-dimensional:
layout/
grid-system.css
header.css
sidebars.css
look/
typography/
main.css
headers.css
lists.css
backgrounds/
html_elements.css
header.css
main-area.css
footer.css
Okay, the example is fabricated, but you sure do understand what i mean.
Up to this point everything is fine.
Enter Media Query
This is where my CSS structure gets funked up.
In addition to the 2D structure described above, i have to structure my code by media queries:
- Some of my styles are universal (applied everywhere)
- Some are applied to certain screen size only:
- small;
- medium;
- large;
- extra large.
- Some are applied to certain groups of screen sizes:
- everything except small (non-mobile styles);
- small and medium (where sidebars aren't at the sides)
- large and xlarge (where you do have sidebars)
I tried to overcome the issue by scattering media queried styles among existing CSS files. The breakpoint Compass extension helps a lot, but the stylesheets become too messy. Finding a certain style when it's not portrayed in the files structures a lot of pain.
I tried grouping by media queries, then by elements and function. But files structure is two dimensional, so you can't add a new dimension, you can only add another level of hierarchy. So, it's not graceful. Also, it's very bulky.
So i end up with a 2D structure with media queries on one axis and an ugly mix of elements and functions on the other axis.
I'm absolutely not satisfied with that but i just fail to come up with a graceful solution. Please suggest one.
CSS is already a structured language. For better or worse, the order of your code changes it's meaning. Because of that, it's important that any CSS organization scheme is dictated primarily by the cascade. The other structural aspect of CSS is semantics. Use it to your advantage. The concern of organization is keeping things meaningful and maintainable. The best thing you can do to retain meaning is to show relationships. Relationships are already expressed by semantics.
Put those things together, and you end up with code organized by specificity first and then semantics, but never by external concepts such as type vs. layout or screen-size. Here's my naming scheme:
base/
- Sass imports and settings - no CSS output.
- e.g _grid, _colors, _rhythm, etc.
general/
- Initial CSS baseline with resets, defaults, font imports, and classes to extend.
- e.g. _reset, _root, _fonts, _icons, _defaults, etc.
layout/
- The rough outline of the site structure.
- Not "layout" as a set of properties excluding type, "layout" as the overall site template which might well include typography.
- e.g. _banner, _nav, _main, _contentinfo, etc.
modules/
- All the details. First by effect (classes/general), then by widget (ids/specifics).
- e.g. _users, _admin, _product-lists etc.
Media-queries should stay as close as possible to the code they affect. When possible, they go directly inline (with Sass media bubbling). If that becomes bulky, they move outside the block, but never outside the partial. MQ's are overrides. When you override code, it is especially important that you are able to see exactly what is being overridden.
On some sites, you may take this structure farther. I've occasionally added two folders at the end: plugins/
to manage 3rd-party code, and overrides/
to handle unavoidable (try to avoid them!) location-specific overrides to a widget. I've also gone deeper, adding a fonts/
folder with partials for each font family, or a users/
folder with partials for adding, editing, viewing, etc. The specifics are flexible, but the basic organization remains the same:
- Start general.
- Move towards specifics as slowly as possible.
- Never divide based on any external concepts (type/layout, screen-sizes, etc).
why not try something like this:
/root
/modules
/header
/html
header.html
/css
module_styles.css /*Configure which style sheets are included with @media rule in this file*/
/at-media
small.css
medium.css
large.css
/js
fancy-nav.js
/site
includes.css /*use @import to include each modules stylesheet in a file here and let each module control its own media issues*/
What I wind up doing is your 2D solution (although mine has some more nesting) and using Breakpoint to write my media queries in line when needed. One of the things we need to deal with is our output CSS isn't going to look the same as our hand-written code, it's a reality of using a CSS preprocessor and specifically abstracting things around. Soon, Google Chrome's dev tools are going to come with built in Sass partial support, and there is FireSass
for Firefox to help you figure out where styles come from.
Hope these help!
Ok so this is more a question of personal taste and may be not really answering the question but here is my contribution:
What I do is a "2D" organization like you say, with a lot of less files (let's say we are speaking css with less preprocessor)
I found it easier to use media queries in the same "less" file of the element I am styling.
So for example I have header.less and in the same file, its media queries.
#header {
...
}
//Header media queries
-----------------------
@media screen and (min-width:480px) { ... }
@media screen and (min-width:768px) { ... }
Now, Why I choose to do it that way ?
-> Because (for me) it's a huge pain in the... to have to look in another file (say responsive.less for example) , search in it the media queries for header, do my changes.. etc. Instead, with this method I always know where my media queries are and they are easy to reach / modify for each element and this does not add many more lines to the code.
The only problem with that is that when the css is generated, we end up with media queries for single elements spread all over the css code. Not very beautiful! (at this time less/winless does not group automatically media queries.)
I ended building a small app to group media queries: http://nokturnalapp.com/mqhelper/
I use it to build the css files for production. (it's not finished yet, I need to add the code stripped from the media queries version but have a look at it.)
I hope this helps you in some way.