I think I heard @JohnAlbin say in the Themeing Haiku with Haml, Sass and Peroxide session at DrupalCon Chicago that he's interested in getting SASS into Zen (through Compass?). I'm very interested in that, and I wondered if I might prompt some discussion by creating an issue for it. I want to be the first to know if something comes of it!

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

JohnAlbin’s picture

Version: 7.x-5.x-dev » 7.x-3.x-dev
JohnAlbin’s picture

OMG. Sass is so awesome. After I've finished converting the STARTERKIT css files to scss, I'll:

  1. commit them to the 7.x-5.x branch
  2. Then I'll investigate compass a bit so that I don't look like a sass newb. Which, actually, I am. ;-) But I want to ensure I understand compass and sass enough first before putting them in an official Zen release.
  3. Then I'll migrate the scss files over to the 7.x-3.x branch and they'll go out as part of Zen 7.x-3.2 or whatever.
JohnAlbin’s picture

Version: 7.x-3.x-dev » 7.x-5.x-dev
Status: Active » Needs work

Ok. I've added the first draft of the .scss files to 7.x-5.x-dev.

http://drupalcode.org/project/zen.git/commitdiff/e768cb3?hp=6549e6ef122f...

I still need to add something for the layout CSS files.

KrisBulman’s picture

Issue tags: +Sass

John, What are the plans with implementing Sass into Zen going forward? Will it always be a separate release, or will Sass be there and optional?

After the first Sass release, should developers submitting patches now use Sass in their primary development environment to keep all files in sync going forward? Or make changes in both sass and css files seperately?

The reason I ask is because after updating the navigation.scss sass file, running the commands specified to watch the folder/write to the folder.. the output looks like the following.. i note that we'll lose commenting in the original css files.. but it will be retained in the sass files.

/* line 9, sass/navigation.scss */
li a.active {
  color: #000; }

/* line 21, sass/navigation.scss */
#navigation ul.links,
#navigation .content ul {
  margin: 0;
  padding: 0;
  text-align: left; }
  /* line 26, sass/navigation.scss */
  #navigation ul.links li,
  #navigation .content ul li {
    float: left;
    padding: 0 10px 0 0;
    list-style-type: none;
    list-style-image: none; }
/* line 33, sass/navigation.scss */
#navigation h2.block-title {
  display: none; }
/* line 36, sass/navigation.scss */
#navigation .block-menu {
  margin-bottom: 0em; }

/* line 51, sass/navigation.scss */
#secondary-menu {
  float: right; }

After installing the drupal compass plugin which runs with cron (awesome), here are the output options in development mode (production mode removes line comments):

nested

exact same as default sass output above

Expanded

much like the current css (sans comments)

compact

all selectors use one line each

compressed

continuous output, much like a minified js file
KrisBulman’s picture

Issue tags: +compass
FileSize
580 bytes

added optional drupal compass module support to starterkit (exposes sub-theme to the compass module) - http://drupal.org/project/compass

This may not be preferred, and probably should be something added to a subtheme after installing the module anyway.

barraponto looks like he's taking a good approach with the compass-drupal-plugin

barraponto’s picture

@JohnAlbin I guess you can take a look what I have done in https://github.com/barraponto/compass-drupal-plugin

Edit: Just noticed it is mentioned in the first comment :)

barraponto’s picture

@KrisBulman: thanks for the heads up. I don't use cron, I usually compile on my local machine (compass compile) and push the CSS files to the server, as running ruby on the live server might slow things down.

Contributions might come both in CSS and SASS, it will be the mantainer's work to bring stuff into SASS/Compass. This is because many developers might not jump in the SASS/Compass bandwagon. So they will get the Zen theme as they always did, sub-theme it and work on top of the CSS files. And it will still work.

barraponto’s picture

I have released a readme file, I hope it makes things easier. There is no Zen example there since it doesn't generate a sub theme, yet. So in order to use Drupal Compass Plugin with Zen you need to create a sub theme first then run compass create themename from sites/all/themes (you are effectively overwriting stuff in your theme). You will need to change the subtheme info file as well.

See https://github.com/barraponto/compass-drupal-plugin for the readme file and http://groups.drupal.org/node/97989 for instructions on Zen subthemeing. I know it is frustrating right now and will probably have to wait for 2.0 if I follow the roadmap (but I guess I won't).

franz’s picture

sub

geekgirlweb’s picture

Wow, I recently started working with SASS/Compass and I'm definitely interested in testing this out. Thanks!

Anonymous’s picture

KrisBulman’s picture

There's also some great stuff going on in barraponto's compass drupal plugin that makes liquid/fixed ltr/rtl very easy.. definitely worth a look.

https://github.com/barraponto/compass-drupal-plugin/blob/master/styleshe...

JohnAlbin’s picture

There's great things in both Benjamin's and Capi’s files for the Zen layout.

But there are a couple of limitations that were built-in to the Zen's layout-fixed/liquid.css that I want to remove now that I've got the tools to do so.

  1. Remove the hard-coded column classes/ids. The layout method should be easy to apply to any divs no matter their identifiers. (Benjamin's code did this. !#++)
  2. Remove the funky "with-navigation" class. That's just a hack because the Zen theme doesn't know if you'll have a navbar or not. But the theme builder does know if there is going to be a navbar.
  3. Remove the wrapper divs. Here's the the thing. All those padding: 0; /* DO NOT CHANGE. */ comments are simply to make the math much easier to handle. The reality is that we can add the left and right padding into our calculations; its just much harder to do. Let's have sass to the heavy lifting.

    This is the only HTML we need:

    <div class="wrapper">
      <div class="col1"></div>
      <div class="col2"></div>
      <div class="col3"></div>
    </div>
    
  4. The number of columns is unlimited, but we've only ever used 3. A mixin should support any number of columns: 1, 2, 3, 4, 5, 20, whatever.
  5. Calculating the distance from the column to the left or right edge of the container is annoying. It would be much easier to just specify the distance between the columns. Why not give the "leading gutter" for each column and have the mixin add up all the previous column's widths and gutters?
  6. Its trivial to build a grid system on top of the zen columns layout method. I've just never done it.

I just committed this zen-columns mixin. I want to thoroughly debug it before I build a zen-columns-liquid or a zen-grids mixin.

//
// This mixin should be applied to a container so that the children elements
// become columns arranged with the Zen Columns layout method.
//
// The mixin has the following required parameters:
// - $selectors: A list of selectors for all the columns inside the container.
//   Order the columns as they appear from left-to-right (or right-to-left when
//   the $leading-direction is "right".)
// - $widths: A list of widths. Each one corresponds to a column specified in
//   $selectors. e.g. The first width is for the first column. The second width
//   is for the second column. etc.
//
// The mixin has the following optional parameters:
// - $leading-direction: The direction the columns should float. Can be set to
//   "left" or "right". An extremely advanced option allows you to specify a
//   a list of directions, one direction for each column.
// - $leading-gutters: A list of leading gutters; one per column. The leading
//   gutter specifies the distance between the current column and the column
//   floated just before it.
// - $padding: A list of padding measurements; one per column. In order to
//   specify a complex padding value like "0 4px 2px", you can use nested lists,
//   e.g. $padding: ((0 4px 2px), (3px 0), (10px 5px 5px 10px))
//   In order to use the same padding measurements for all columns, you can
//   simply list one measurement total instead of one per column,
//   e.g. $padding: ((5px 10px))
//
// In addition to standard columns, the mixin supports one horizontal navbar
// that will appear (with a fixed height) above all the other columns. The
// parameters for this optional navbar are:
// - $navbar-selector: The selector for the navbar. It should be a child element
//   of the container just as a normal column is.
// - $navbar-height: The fixed height of the navbar. Required if the
//   $navbar-selector is used.
// - $navbar-width: The width of the navbar. Defaults to 100% of the container
//   width.
// - $navbar-leading-gutter: An optional leading space between the navbar and
//   and the container's inner edge. If specified, the $navbar-width must also
//   be specified so that the width plus leading gutter plus padding isn't
//   greater than 100% of the container's width.
// - $navbar-padding: An optional padding for the navbar. If specified, the
//   $navbar-width must also be specified so that the width plus leading gutter
//   plus padding isn't greater than 100% of the container's width.
//
@mixin zen-columns-fixed (
  // Information about the columns.
  $selectors: ('.sidebar1', '.content', '.sidebar2'),
  $widths: (),
  $leading-direction: (),
  $leading-gutters: (),
  $padding: (),

  // Information about the navbar.
  $navbar-selector: false,
  $navbar-height: 0,
  $navbar-width: 100%,
  $navbar-leading-gutter: 0,
  $navbar-padding: 0
) {
…
KrisBulman’s picture

setting the leading direction to "left" or "right" in layout-fixed gives some strange results for me..

Should it be looking for the actual term "right"?

$leading-direction: (right),

Boy, I thought I had a handle on SASS, but it's taking me a while to get my head around the columns scss

JohnAlbin’s picture

The "Prevent overflowing content from breaking the layout" bit of code was broken because Sass doesn't interpolate lists properly when put into a selector. I just committed a fix for that.

@Kris: Yeah, this mixin is the most complex that I've seen. I looked at a bunch of mixins, but realized I needed a single one on the container that also set the CSS for the container's columns. Otherwise it put the burden of the math on the themer again.

With this mixin, the parameters are complex, but once you understand how the parameters relate to each other and what they mean, then you don't have to do any math except figuring out the distance between the columns (the leading gutter). The mixin does all the crazy math.

Do take a look at the layout-fixed.scss file because it shows an example of using the mixin.

Also, the mixin definitely needs stress testing. Theoretically, I believe, the mixin should accept $leading-direction: right, $leading-direction: 'right', $leading-direction: (right), or $leading-direction: ('right'). But I haven't tested all of those. The docs can be expanded to show example usage.

KrisBulman’s picture

Rather than use numbers in layout-fixed.. (for .two-sidebars #main, .sidebar-second #main & .sidebar-first #main), wouldn't it be better to set the sidebar variables at the top of the document and let SASS calculate the content width - gutter & remove the need to type in the same value more than once across the document?

$page-width: 960px;
$first-sidebar-width: 180px;
$second-sidebar-width: 180px;
JohnAlbin’s picture

Rather than use numbers in layout-fixed.. (for .two-sidebars #main, .sidebar-second #main & .sidebar-first #main), wouldn't it be better to set the sidebar variables at the top of the document and let SASS calculate the content width - gutter & remove the need to type in the same value more than once across the document?

You mean set several variables in the layout-fixed.scss file and use those variables as the values passed to the mixins? Absolutely, you could do that.

However, I just tried that I got this result:


// To make Drupal's expandible/collapsible columns work a little easier, we set
// the following variables:
$content-width: 560px;
$sidebar-first-width: 180px;
$sidebar-second-width: 180px;
$sidebar-gutter: 20px;

$zen-navbar-height: 3em;
$zen-navbar-width: 100%;
$zen-navbar-leading-gutter: 0;
$zen-navbar-padding: 0;

.two-sidebars #main {
  @include zen-columns-fixed (
    $selectors: ('.region-sidebar-first', '#content', '.region-sidebar-second'),
    $widths: ($sidebar-first-width, $content-width, $sidebar-second-width),
    $leading-direction: (),
    $leading-gutters: (0, $sidebar-gutter, $sidebar-gutter),
    $padding: (),

    $navbar-selector: '#navigation',
    $navbar-height: $zen-navbar-height,
    $navbar-width: $zen-navbar-width,
    $navbar-leading-gutter: $zen-navbar-leading-gutter,
    $navbar-padding: $zen-navbar-padding
  );
}

If I've never seen this mixin before, I would find that completely indecipherable. :-\

What I would find more interesting is something like this:

$grid-width: 960px / 8;  // Define 8 column grid system
$grid-gutter: 0;
$grid-padding: 10px;

.two-sidebars #main {
  @include zen-columns-fixed (
    $selectors: ('.region-sidebar-first', '#content', '.region-sidebar-second'),
    $widths: ( 2 * $grid-width, 5 * $grid-width, 1 * $grid-width), // Make sure we use all 8 columns
    $leading-direction: (),
    $leading-gutters: $grid-gutter,
    $padding: $grid-padding
  );
}

Maybe some functions like 960 or Blueprint to calculate widths when there is a non-zero gutter?

Owen Barton’s picture

Super excited for this!

barraponto’s picture

@JohnAlbin: since we still have the .section div inside each of the columns, I guess we don't actually need column paddings — margins in the sections will do. However I like the approach of using lists as a way to make it easier for N columns.

Your mixin, however, goes beyond what is reasonable when it comes to setting variables. Making good use of the .section divs to avoid paddings, we don't need to worry about them and we can lower the number of variables. I guess the leading gutter can follow the same path. And let's set the variables once and split the layout mixin into column and layout, since we might not need to print the navbar styles if we aren't going to use it.

KrisBulman’s picture

Just found this little tidbit on preserving comments from Chris Eppstein..

Add an exclamation mark to a comment to make it a loud comment. Loud comments will remain even in compressed mode and they evaluate sass script.

/*! Copyright (c) #{$current-year}. All rights reserved. */

adellefrank’s picture

Subscribing.

sylvain_a’s picture

Suscribing.

JohnAlbin’s picture

FYI, now that #1249790: Convert tabs from old sliding-door CSS technique to CSS3 has landed, Zen's Sass files require Compass. If you don't have Compass installed, the tabs.scss file will fail compilation with errors.

KrisBulman’s picture

beats writing endless vendor specific code! for just that alone it's worth it, let alone everything else it gives us.

JohnAlbin’s picture

JohnAlbin’s picture

What I did on my Winter vacation: https://github.com/JohnAlbin/compass-zen-grids

I haven't done any testing to make sure the new mixins are bug-proof.

The general plan is to:

  1. finish testing the mixins
  2. Publish the zen-grids Ruby gem
  3. Add responsive grid layouts to Zen
  4. Document recipes for several grid layouts
  5. Create layout generator to use general layouts with variable-column grids
KrisBulman’s picture

nice work John, can't wait to try this out!

echoz’s picture

Awesome, I've been looking forward to this, and eager to test.

barraponto’s picture

@JohnAlbin why rolling your own grid system when there are several compatible with SASS and Compass, with a whole community mantaining them?

I'd go for Susy, but there's 960gs and blueprint out there.

echoz’s picture

@barraponto, as best practices are yet to be settled on from many to check out or model from to build our own, I for one have been anticipating what JohnAlbin will create.

KrisBulman’s picture

now we have a whole new theming community maintaining a zen grid system :)

JohnAlbin’s picture

I find Susy a bit overly complicated. (Given Zen 7.x-3.x's layout-fixed.css, I recognize the irony.) And the tutorials don't help much. http://susy.oddbird.net/tutorial/ http://scottdavis.github.com/blog/2011/12/30/introduction-to-building-we...

I knew the underlying method behind Zen's default layout was very powerful and (surprising to me!) worked great for responsive layouts. The only thing it was missing was an abstraction that made applying it super simple.

I'm hoping that's what these mixins provide. Here's the example in the README from https://github.com/JohnAlbin/compass-zen-grids:

@import "zen";

$zen-column-count: 12;    // Set the total number of columns in the grid.
$zen-gutter-width: 30px;  // Set the gutter size. A half-gutter is used on
                          // each side of each column.

.container {
  @include zen-grid-container();
}
.sidebar1 {
  @include zen-grid(1, 3);  // 3 col. wide sidebar starting in the 1st column
}
.content {
  @include zen-grid(4, 6);  // 6 col. wide element starting in the 4th column
}
.sidebar2 {
  @include zen-grid(10, 3); // 3 col. wide sidebar starting in the 10th column
}

This creates a fluid 12-column grid with 30px gutters (15 pixel half-gutters on each . (I hate percentage-based gutters because they force the designer to add lots of breakpoints so the gutters don't wildly fluctuate.)

A more interesting example is in the example.html that comes with the zen-grids gem.

You can build the example yourself:

sudo gem install zen-grids --pre
compass create test-project -r zen-grids --using zen-grids

That will create a directory called "test-project" that includes the example.html, config.rb (so compass watch will work correctly), and all the sass source and generated css files for the example. Here's a snippet from the sass/layout.scss file:

@media all and (min-width: 480px) and (max-width: 639px) {
  $zen-column-count: 2;

  #content {
    @include zen-grid(1, 2);
  }
  #aside1 {
    @include zen-clear(); // Clear left-floated elements (#content)
    @include zen-grid(1, 1);
  }
  #aside2 {
    @include zen-grid(2, 1);
  }
}

@media all and (min-width: 640px) and (max-width: 799px) {
  $zen-column-count: 3;

  #content {
    @include zen-grid(1, 2);
  }
  #aside1 {
    @include zen-grid(1, 1, right); // Position from the right
  }
  #aside2 {
    @include zen-clear(); // Clear left-floated elements (#content)
    @include zen-grid(1, 2);
  }
}

@media all and (min-width: 800px) and (max-width: 959px) {
  $zen-column-count: 3;

  #content {
    @include zen-grid(1, 2);
  }
  #aside1 {
    @include zen-grid(1, 1, right); // Position from the right
  }
  #aside2 {
    @include zen-clear(right); // Clear right-floated elements (#aside1)
    @include zen-grid(1, 1, right);
  }
}

I'm pleased with the results.

KrisBulman’s picture

I haven't given this a shot, but wonder what the css output results are like. any bloat problems?

JohnAlbin’s picture

FileSize
56.85 KB

@KrisBulman Re: bloat problems. Actually I added a new global variable that can be used to reduce the CSS output.

// You can generate more efficient CSS if you manually apply the
// zen-grid-unit-base mixin to all grid elements from within a single ruleset.
$zen-auto-include-unit-base: true !default;

From https://github.com/JohnAlbin/compass-zen-grids/blob/master/stylesheets/z...

I'm working on better docs for this. Here's a sneak peak:

JohnAlbin’s picture

Component: PHP code » layout.css

Zen Grids is up to 1.0.beta.5 now and the parameter order and mixin names have changed slightly. See http://zengrids.com/help/

Zach Harkey’s picture

So with this method, what is the best way to make the main content column expand to fill the empty space left when one of the sidebars doesn't have any content?

echoz’s picture

@Zach Harkey, we can use Zen’s body classes denoting the presence of sidebars (.two-sidebars, .one-sidebar, .sidebar-first, .sidebar-second, .no-sidebars) in combination with #content and region classes (ex: .region-sidebar-first) in our media queries.

barraponto’s picture

I'm pretty sure a mixin can fix it by default.

JohnAlbin’s picture

I had added some sass files to 7.x-3.x branch, but those are really out-of-date now. And the sass files in 7.x-5.x are HTML5 and responsive specific, so I can't just copy over the files.

I've decided to remove the Sass files from 7.x-3.x. I've moved the files to a 7.x-3.x-sass branch in case someone volunteers to update and maintain them.

JohnAlbin’s picture

Component: layout.css » CSS/SASS/HTML markup
Status: Needs work » Fixed

Now that I've completed #1446064: Make CSS files be slightly-modified compiled versions of the Sass files, I think we can mark this issue complete.

That just leaves a handful of Sass/Compass issues left which we can tackle in their own issue.

#1181622: Add responsive layouts to Zen
#1440910: Change font styling technique from "em"s to "rem"s
#1439712: Add default variables for use in sass files

Automatically closed -- issue fixed for 2 weeks with no activity.