Reopen a Mixin?

19 views
Skip to first unread message

Karl

unread,
Dec 17, 2009, 1:21:31 PM12/17/09
to Compass
This has come up every time I use compass, and I have a perfectly
acceptable way to work through it, but I have longed for a better way.
At least 95% of compass/blueprint works well for me. But I need to
make small, minor adjustments (typically for spacing). So I just add
those adjustments to my screen.sass and because it places those tags
at the end, it overrides blueprint formatting. There are other ways
too.

But I would rather reopen the mixin I need to change, add/remove/
change what I need, and thus not have to depend on descendant tags to
apply the styling changes I need.

For example, in blueprint/_form.sass:

=blueprint-form-layout
label
:font-weight bold

I would rather have the label style italic. It would be so nice to
reopen the blueprint-form-layout mixin as if it was a ruby class, and
modify that label tag. This way I don't have to have my own label tag
to remove the bold and add italic.

Or

Maybe sass could recognize that a latter tag of the same definition
override a previous tag and thus not generate the style for previous
tags.

Maybe it's because I've become so accustomed to ruby and the ability
to reopen a class and replace or add a method. I naturally want to do
that with my sass too.

Does this make sense to anyone else? or am I just being overly
fastidious about my css?

Andrew Vit

unread,
Dec 17, 2009, 2:10:35 PM12/17/09
to compas...@googlegroups.com
I think it’s a very good point, but there are some ways around it.

If your Sass is well structured so you can decompose it into smaller mixins, then it’s pretty straightforward to mix-and-match what you need into your own mixin and leave out the rest.

In the specific case you showed, I’m actually not sure why that font-weight is in the blueprint-form-layout mixin at all. Shouldn’t that be in a separate blueprint-form-typography or something?

Andrew Vit

> --
>
> You received this message because you are subscribed to the Google Groups "Compass" group.
> To post to this group, send email to compas...@googlegroups.com.
> To unsubscribe from this group, send email to compass-user...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/compass-users?hl=en.
>
>

Nathan Weizenbaum

unread,
Dec 17, 2009, 2:11:17 PM12/17/09
to compas...@googlegroups.com
We're planning to add an optimization stage to Sass that will do things like get rid of multiple definitions of the same property. That should help with this. As with re-opening mixins, you can already redefine existing mixins; I'm not sure how one would go about doing more, though, like including the old properties.

Karl

unread,
Dec 17, 2009, 2:33:50 PM12/17/09
to Compass
On Dec 17, 12:10 pm, Andrew Vit <and...@avit.ca> wrote:
> I think it’s a very good point, but there are some ways around it.
>
> If your Sass is well structured so you can decompose it into smaller mixins, then it’s pretty straightforward to mix-and-match what you need into your own mixin and leave out the rest.

Yes. But in almost all of my projects, blueprint is fine for 95%. So
my screen.sass is relatively small. I just need to do a little tweak
here and there.

The real problem is, for example, a label is getting styling from
blueprint, formtastic, my base.sass and screen.sass (add ie.sass too).
Trying to track down which stylesheet and tags is contributing to the
final computed style get a little hairy sometimes (though CSSEdit is a
big help). But you have to track down the offending tag and style and
then create an override many times with several lines of styling, just
to nudge a checkbox a couple of pixels this way or that.

And I have done the mix-and-match thing. And the override thing (ala
Nathan's suggestion). And yes they work. No complaints there.

Just attempting to up the elegance a notch.

> In the specific case you showed, I’m actually not sure why that font-weight is in the blueprint-form-layout mixin at all. Shouldn’t that be in a separate blueprint-form-typography or something?

I didn't include the full path to that... frameworks/blueprint/
stylesheets/blueprint/modules/_form.sass

I think it's there because it's only form formatting elements.

Karl

Karl

unread,
Dec 17, 2009, 2:58:37 PM12/17/09
to Compass
On Dec 17, 12:11 pm, Nathan Weizenbaum <nex...@gmail.com> wrote:
> We're planning to add an optimization stage to Sass that will do things like
> get rid of multiple definitions of the same property. That should help with
> this.

That would be terrific. Will it consider tags across multiple sass
files?

> As with re-opening mixins, you can already redefine existing mixins;
> I'm not sure how one would go about doing more, though, like including the
> old properties.

Yes, and I've done that. But some are quite lengthy and if you monkey-
patch a large style definition, you miss on upgrade and bug fixes in
compass. That one just bit me yesterday.

I guess my brain looks at css and sees an xml dom tree of elements and
attributes. If I can identify an element, I should be able to add/
delete/change it's attributes.

=blueprint-form-layout
label
style_remove :all # or style_remove :font-weight
style_add :font-style => 'italic' # or just- font_style: italic

Considering that I only add styling changes to screen.sass, something
like above lets me know explicitly that I'm removing all the styling
from the label tag, then adding just one style. But it will *not*
override the other tags in blueprint-form-layout. Focused and explicit
changes.

But hey, maybe no one else runs into this situation or has a better
idea.


Just thinking out loud.
Karl

Chris Eppstein

unread,
Dec 17, 2009, 3:47:12 PM12/17/09
to compas...@googlegroups.com
I guess my brain looks at css and sees an xml dom tree of elements and attributes. If I can identify an element, I should be able to add/delete/change it's attributes.

Maybe LessCSS is more your style then. This is exactly what it does. 

Of course, my opinion is that your mental model is flawed. CSS is absolutely not a DOM tree or any kind of tree. It is a cascade of rules down a DOM tree. CSS operates by overriding and the order of overriding is based on selector specificity of the rules that match a DOM element. The nesting in Sass makes it easier to build rules, but it is not terribly hard to construct an example that exemplifies how the reopening of selectors to amend their contents quickly leads to unexpected behavior when those styles are applied to a document. I understand that you're request applies specifically to selectors in mixins, and it might be ok in that case, but I think there are better ways to address the mixin case.

The reason I like mixins is that they are very simple to understand. CSS selectors still work like they used to, it's just that you have easier ways to build their contents.

When you need to create your own abstractions on top of others, even if it's just to fix a bug, you should do so by defining your own mixins.

=form-layout
  +blueprint-form-layout
  label
    font:
      weight: normal
      style: italic

The only downside to this approach is that it generates duplicative style properties in the CSS. But duplication in CSS is the norm if you want semantic markup, so this is really a rounding error in that world.

As far as changing a mixin goes (say to fix a bug before the maintainer can issue a new release), I'm wondering whether our intended change to allow nested imports would enable this:

=blueprint-form-layout
  @import blueprint/forms.sass
  +blueprint-form-layout
  label
    font:
      weight: normal
      style: italic

In this way, you've effectively monkey patched the mixin thanks to how mixins are shadowed by imports.

If you had this facility, would you find it sufficient or even preferable? I like that it builds on existing Sass syntax.

chris

Nathan Weizenbaum

unread,
Dec 17, 2009, 5:10:57 PM12/17/09
to compass-users
On Thu, Dec 17, 2009 at 12:47 PM, Chris Eppstein <ch...@eppsteins.net> wrote:
Maybe LessCSS is more your style then. This is exactly what it does. 
 
Really? How?

When you need to create your own abstractions on top of others, even if it's just to fix a bug, you should do so by defining your own mixins.

=form-layout
  +blueprint-form-layout
  label
    font:
      weight: normal
      style: italic

This is the sort of approach I like. The thing is, though, if you don't redefine the original mixin, you lose the ability to affect it when it's used elsewhere - perhaps in code you don't control. It might be useful to have a way to redefine it while referencing the old implementation in a forwards-compatible way. Maybe something as simple as

=blueprint-form-layout

  +blueprint-form-layout
  label
    font:
      weight: normal
      style: italic

The only downside to this approach is that it generates duplicative style properties in the CSS. But duplication in CSS is the norm if you want semantic markup, so this is really a rounding error in that world.

I don't think we should just passively accept duplication in CSS. We should do what we can w.r.t. optimization to get rid of it.

As far as changing a mixin goes (say to fix a bug before the maintainer can issue a new release), I'm wondering whether our intended change to allow nested imports would enable this:

=blueprint-form-layout
  @import blueprint/forms.sass
  +blueprint-form-layout
  label
    font:
      weight: normal
      style: italic

In this way, you've effectively monkey patched the mixin thanks to how mixins are shadowed by imports.

If you had this facility, would you find it sufficient or even preferable? I like that it builds on existing Sass syntax.

This is cool, but I'm not sure it's really clear what's going on at a glance, especially for someone unfamiliar with the intricacies of how the language works. I think maybe my example above is clearer.

On Thu, Dec 17, 2009 at 11:58 AM, Karl <threa...@gmail.com> wrote:
On Dec 17, 12:11 pm, Nathan Weizenbaum <nex...@gmail.com> wrote:
> We're planning to add an optimization stage to Sass that will do things like
> get rid of multiple definitions of the same property. That should help with
> this.

That would be terrific. Will it consider tags across multiple sass
files?

Yes, as long as those properties are under the same selector.

I guess my brain looks at css and sees an xml dom tree of elements and
attributes. If I can identify an element, I should be able to add/
delete/change it's attributes.

=blueprint-form-layout
 label
   style_remove :all   # or style_remove :font-weight
   style_add :font-style => 'italic'  # or just- font_style: italic

Considering that I only add styling changes to screen.sass, something
like above lets me know explicitly that I'm removing all the styling
from the label tag, then adding just one style. But it will *not*
override the other tags in blueprint-form-layout. Focused and explicit
changes.

But hey, maybe no one else runs into this situation or has a better
idea.

This seems awfully programmer-y to me. I think adding styles should be done with the standard property syntax. I'm not sure about removing... unfortunately, there's not really a good CSS syntax for saying "pretend this property" isn't here (as far as I know?). Maybe we should just add something of our own for that, because it does seem useful.

- Nathan

Karl

unread,
Dec 17, 2009, 11:02:06 PM12/17/09
to Compass
On Dec 17, 3:10 pm, Nathan Weizenbaum <nex...@gmail.com> wrote:

> This is the sort of approach I like. The thing is, though, if you don't
> redefine the original mixin, you lose the ability to affect it when it's
> used elsewhere - perhaps in code you don't control. It might be useful to
> have a way to redefine it while referencing the old implementation in a
> forwards-compatible way. Maybe something as simple as
>
> =blueprint-form-layout
>   +blueprint-form-layout
>   label
>     font:
>       weight: normal
>       style: italic

Yes, I like that idea. Nice.

> The only downside to this approach is that it generates duplicative style
>
> > properties in the CSS. But duplication in CSS is the norm if you want
> > semantic markup, so this is really a rounding error in that world.
>
> I don't think we should just passively accept duplication in CSS. We should
> do what we can w.r.t. optimization to get rid of it.

I have to agree. If sass can provide a path to simplification or
clarification, why not.

> > issue a new release), I'm wondering whether our intended change to allow
> > nested imports would enable this:
>
> > =blueprint-form-layout
> >   @import blueprint/forms.sass
> >   +blueprint-form-layout
> >   label
> >     font:
> >       weight: normal
> >       style: italic
>
> > In this way, you've effectively monkey patched the mixin thanks to how
> > mixins are shadowed by imports.
>
> > If you had this facility, would you find it sufficient or even preferable?
> > I like that it builds on existing Sass syntax.
>
> This is cool, but I'm not sure it's really clear what's going on at a
> glance, especially for someone unfamiliar with the intricacies of how the
> language works. I think maybe my example above is clearer.

Again, I agree. I like this a little better than current methods and I
can see the potential. But in this case, it seems like a different way
to skin the same cat.


> > I guess my brain looks at css and sees an xml dom tree of elements and
> > attributes. If I can identify an element, I should be able to add/
> > delete/change it's attributes.
>
> > =blueprint-form-layout
> >  label
> >    style_remove :all   # or style_remove :font-weight
> >    style_add :font-style => 'italic'  # or just- font_style: italic
>
> > Considering that I only add styling changes to screen.sass, something
> > like above lets me know explicitly that I'm removing all the styling
> > from the label tag, then adding just one style. But it will *not*
> > override the other tags in blueprint-form-layout. Focused and explicit
> > changes.
>
> > But hey, maybe no one else runs into this situation or has a better
> > idea.
>
> This seems awfully programmer-y to me. I think adding styles should be done
> with the standard property syntax. I'm not sure about removing...
> unfortunately, there's not really a good CSS syntax for saying "pretend this
> property" isn't here (as far as I know?). Maybe we should just add something
> of our own for that, because it does seem useful.

I see your point... but I am a programmer.

My point was, as I think you see, if there was the ability to reopen a
mixin, it should be concise and clear. While it may be a bit
programmer-y to some, it's just an option. Don't like it, don't use
it. The whole concept of mixins to designers is somewhat foreign
anyway and has no correlation to current css.


Anyone else find this potentially useful?

Nathan Weizenbaum

unread,
Dec 18, 2009, 1:43:18 AM12/18/09
to compass-users
On Thu, Dec 17, 2009 at 8:02 PM, Karl <threa...@gmail.com> wrote:
> This seems awfully programmer-y to me. I think adding styles should be done
> with the standard property syntax. I'm not sure about removing...
> unfortunately, there's not really a good CSS syntax for saying "pretend this
> property" isn't here (as far as I know?). Maybe we should just add something
> of our own for that, because it does seem useful.

I see your point... but I am a programmer.

My point was, as I think you see, if there was the ability to reopen a
mixin, it should be concise and clear. While it may be a bit
programmer-y to some, it's just an option. Don't like it, don't use
it. The whole concept of mixins to designers is somewhat foreign
anyway and has no correlation to current css.

The more features there are of Sass that seem programmer-y, the more programmer-y the language seems in general, which puts a lot of designers off. In any case, I think we can come up with a way to do it that meshes well with what we've already got.

Eric Meyer

unread,
Dec 18, 2009, 8:03:15 PM12/18/09
to Compass
> We're planning to add an optimization stage to Sass that will do things like
> get rid of multiple definitions of the same property.

That sounds risky to me. I'm working with CSS3 all over the place and
end up with code like this:

background-color: #333333
background-color: rgba(0,0,0,.25)
background-image: url(gradient.png)
background-image: -webkit-gradient( etc...
background-image: -moz-linear-gradient etc...

And so on. You start removing my repeated properties and the entire
progressive-enhancement stack falls apart.

-e

> > compass-user...@googlegroups.com<compass-users%2Bunsubscribe@goog legroups.com>

Chris Eppstein

unread,
Dec 18, 2009, 8:32:59 PM12/18/09
to compas...@googlegroups.com, Compass
This point is well understood.

Optimization is an optional step and even when enabled there will be
ways for the code to tell the optimizer to keep it's grubby hands off.

Also there will probably be different levels of optimization that
allow the optimizer to make increasingly aggressive optimizations.

Chris

Hunt & pecked on my iPhone... Sorry if it's brief!

Reply all
Reply to author
Forward
0 new messages