Instantly share code, notes, and snippets.

Embed
What would you like to do?
mymodule {
@at-root {
.#{&}-header { ... }
.#{&}-footer { ... }
.#{&}-body {
a { ... }
span { ... }
p { ... }
}
}
}
.mymodule-header { ... }
.mymodule-footer { ... }
.mymodule-body a { ... }
.mymodule-body span { ... }
.mymodule-body p { ... }
@porada

This comment has been minimized.

Show comment
Hide comment
@porada

porada May 26, 2013

It’s great. I wish it worked slightly different, though. .#{&} isn’t the most elegant piece of code.

.module {
  @at-root {
    &-header { ... }
    &-footer { ... }
    &-body   {
      a      { ... } 
      span   { ... } 
      p      { ... } 
    }
  }
}

porada commented May 26, 2013

It’s great. I wish it worked slightly different, though. .#{&} isn’t the most elegant piece of code.

.module {
  @at-root {
    &-header { ... }
    &-footer { ... }
    &-body   {
      a      { ... } 
      span   { ... } 
      p      { ... } 
    }
  }
}
@jlong

This comment has been minimized.

Show comment
Hide comment
@jlong

jlong May 26, 2013

How does Sass tell the difference between "mymodule" and a regular HTML tag?

jlong commented May 26, 2013

How does Sass tell the difference between "mymodule" and a regular HTML tag?

@CaioBianchi

This comment has been minimized.

Show comment
Hide comment
@CaioBianchi

CaioBianchi May 26, 2013

well, don't use a html tag.

CaioBianchi commented May 26, 2013

well, don't use a html tag.

@MarioRicalde

This comment has been minimized.

Show comment
Hide comment
@MarioRicalde

MarioRicalde May 26, 2013

I have the same question as @jlong

Also, is there any other @rule added besides @at-root related to modules?

MarioRicalde commented May 26, 2013

I have the same question as @jlong

Also, is there any other @rule added besides @at-root related to modules?

@maikeldaloo

This comment has been minimized.

Show comment
Hide comment
@maikeldaloo

maikeldaloo May 26, 2013

This is awesome.

maikeldaloo commented May 26, 2013

This is awesome.

@franzheidl

This comment has been minimized.

Show comment
Hide comment
@franzheidl

franzheidl May 27, 2013

I think Sass schouldn't make any assumptions here and BOTH using a classname .mymodule as well as a rather abstract base name mymodule for scoping/prefixing @at-rootshould work, so it's up to the user to decide how to architecture his (S)CSS.

Also, Sass simply shouldn't care whether a user chose a base name that also happens to be an html-element name. If someone for whatever reason uses an html element name for his base name/prefix – fine. You're perfectly able to use .divas a class name as well (whether that is a very sensible thing to do remains a totally different question :-).

And OH GOD YES for the feature :)

franzheidl commented May 27, 2013

I think Sass schouldn't make any assumptions here and BOTH using a classname .mymodule as well as a rather abstract base name mymodule for scoping/prefixing @at-rootshould work, so it's up to the user to decide how to architecture his (S)CSS.

Also, Sass simply shouldn't care whether a user chose a base name that also happens to be an html-element name. If someone for whatever reason uses an html element name for his base name/prefix – fine. You're perfectly able to use .divas a class name as well (whether that is a very sensible thing to do remains a totally different question :-).

And OH GOD YES for the feature :)

@sheerun

This comment has been minimized.

Show comment
Hide comment
@sheerun

sheerun May 27, 2013

+2 for @porada proposal

sheerun commented May 27, 2013

+2 for @porada proposal

@matthewhall

This comment has been minimized.

Show comment
Hide comment
@matthewhall

matthewhall May 28, 2013

Agree with @porada as well.

matthewhall commented May 28, 2013

Agree with @porada as well.

@ruedap

This comment has been minimized.

Show comment
Hide comment
@ruedap

ruedap commented May 28, 2013

+1 @porada

@chriseppstein

This comment has been minimized.

Show comment
Hide comment
@chriseppstein

chriseppstein May 28, 2013

@MarioRicalde, @jlong Sass doesn't tell the difference between mymodule and an element selector. To Sass, this is just an element selector -- albeit, one that browsers would ignore if it were to become a selector in the css file.

@porada We've decided that a bare & in a selector must always resolve to a valid selector. The only way to accomplish this is to limit & to being used wherever an element selector can be used. We have always allowed more complex selector construction using interpolation (#{}). Interpolation in a selector allows access to SassScript -- the syntax for which is not compatible with selectors as SassScript was designed to be used in a value context. By exposing & to SassScript we now have the capability to manipulate the selector context in interesting and arbitrary ways.

This example is exceedingly simple, there are a number of examples working with modules where you need to do arbitrary manipulation of the selector context. For instance this source that uses some nested selectors would not be able to work like you suggest as Sass doesn't really understand what you're concept of a "module" is. Instead, you can teach it what a module is according to your convention like so:

@function current-module() {
  @return nth(&, 1);
}

mymodule {
  @at-root {
    .#{current-module()}-header { ... }
    .#{current-module()}-footer { ... }
    .#{current-module()}-body   {
      a          { ... } 
      span       { ... } 
      p          { ... }
      form       {
        button.#{current-module()}-button { ... } }
    }
  }
}

And this would generate CSS like:

.mymodule-header { ... }
.mymodule-footer { ... }
.mymodule-body a { ... }
.mymodule-body span { ... }
.mymodule-body p { ... }
.mymodule-body form button.mymodule-button { ... }

Alternatively, if you wanted to support having your module to be a classname you could implement the current-module() function like this:

@function current-module() {
  $module: nth(&, 1);
  @if str-slice($module, 1, 1) == "." {
    $module: str-slice($module, 2)
  }
  @return $module;
}
Owner

chriseppstein commented May 28, 2013

@MarioRicalde, @jlong Sass doesn't tell the difference between mymodule and an element selector. To Sass, this is just an element selector -- albeit, one that browsers would ignore if it were to become a selector in the css file.

@porada We've decided that a bare & in a selector must always resolve to a valid selector. The only way to accomplish this is to limit & to being used wherever an element selector can be used. We have always allowed more complex selector construction using interpolation (#{}). Interpolation in a selector allows access to SassScript -- the syntax for which is not compatible with selectors as SassScript was designed to be used in a value context. By exposing & to SassScript we now have the capability to manipulate the selector context in interesting and arbitrary ways.

This example is exceedingly simple, there are a number of examples working with modules where you need to do arbitrary manipulation of the selector context. For instance this source that uses some nested selectors would not be able to work like you suggest as Sass doesn't really understand what you're concept of a "module" is. Instead, you can teach it what a module is according to your convention like so:

@function current-module() {
  @return nth(&, 1);
}

mymodule {
  @at-root {
    .#{current-module()}-header { ... }
    .#{current-module()}-footer { ... }
    .#{current-module()}-body   {
      a          { ... } 
      span       { ... } 
      p          { ... }
      form       {
        button.#{current-module()}-button { ... } }
    }
  }
}

And this would generate CSS like:

.mymodule-header { ... }
.mymodule-footer { ... }
.mymodule-body a { ... }
.mymodule-body span { ... }
.mymodule-body p { ... }
.mymodule-body form button.mymodule-button { ... }

Alternatively, if you wanted to support having your module to be a classname you could implement the current-module() function like this:

@function current-module() {
  $module: nth(&, 1);
  @if str-slice($module, 1, 1) == "." {
    $module: str-slice($module, 2)
  }
  @return $module;
}
@chriseppstein

This comment has been minimized.

Show comment
Hide comment
@chriseppstein

chriseppstein May 28, 2013

Note: this is a feature that has been long-requested and we think we've found a very simple and consistant way of dealing with myriad use cases. For the long, sordid history please read sass/sass#286 and some of the related issues.

Owner

chriseppstein commented May 28, 2013

Note: this is a feature that has been long-requested and we think we've found a very simple and consistant way of dealing with myriad use cases. For the long, sordid history please read sass/sass#286 and some of the related issues.

@jlong

This comment has been minimized.

Show comment
Hide comment
@jlong

jlong May 28, 2013

@chriseppstein Seems like what you are saying is that you'ved added a new construct (@at-root) for busting out of whatever nesting you are in and you've given SassScript access to the & operator. This allows for a more powerful way of constructing namespaced CSS, but doesn't really add a first class "module" concept. Am I following you?

What is the benefit of this approach over something more like the following?

$module-name: "mymodule";

.#{$module-name}-header { ... }
.#{$module-name}-footer { ... }
.#{$module-name}-body   {
  a          { ... } 
  span       { ... } 
  p          { ... }
  form       { button.#{$module-name}-button { ... } }
}

jlong commented May 28, 2013

@chriseppstein Seems like what you are saying is that you'ved added a new construct (@at-root) for busting out of whatever nesting you are in and you've given SassScript access to the & operator. This allows for a more powerful way of constructing namespaced CSS, but doesn't really add a first class "module" concept. Am I following you?

What is the benefit of this approach over something more like the following?

$module-name: "mymodule";

.#{$module-name}-header { ... }
.#{$module-name}-footer { ... }
.#{$module-name}-body   {
  a          { ... } 
  span       { ... } 
  p          { ... }
  form       { button.#{$module-name}-button { ... } }
}
@damln

This comment has been minimized.

Show comment
Hide comment
@damln

damln May 29, 2013

I like the @jlong approach and I was thinking the exact same thing.

damln commented May 29, 2013

I like the @jlong approach and I was thinking the exact same thing.

@CapMousse

This comment has been minimized.

Show comment
Hide comment
@CapMousse

CapMousse May 29, 2013

Same here, I like the @jlong approach, more easy to use

CapMousse commented May 29, 2013

Same here, I like the @jlong approach, more easy to use

@chriseppstein

This comment has been minimized.

Show comment
Hide comment
@chriseppstein

chriseppstein May 29, 2013

Sass doesn't enforce a particular way of writing CSS and we try to provide approaches that feel natural to develop with. The definition of a "CSS module" doesn't exist in any sort of formal way and neither will it in Sass. When we develop a first class module concept it will be for organizing sass files to ensure namespace collisions can be managed. Feel free to use the approach that @jlong has suggested. It works now. However, many people have wanted a way to use the stylesheet context to define their concept of a module and that is what we are aiming to provide here.

Owner

chriseppstein commented May 29, 2013

Sass doesn't enforce a particular way of writing CSS and we try to provide approaches that feel natural to develop with. The definition of a "CSS module" doesn't exist in any sort of formal way and neither will it in Sass. When we develop a first class module concept it will be for organizing sass files to ensure namespace collisions can be managed. Feel free to use the approach that @jlong has suggested. It works now. However, many people have wanted a way to use the stylesheet context to define their concept of a module and that is what we are aiming to provide here.

@chriseppstein

This comment has been minimized.

Show comment
Hide comment
@chriseppstein

chriseppstein May 29, 2013

Please keep in mind that these feature can be used within mixins that accept content blocks, etc. So an "@include module($name) { ... } " concept could be defined very easily. I think we will quickly find some very nice ways to create useful abstractions with this set of features. And as I have pointed out elsewhere, the @at-root directive and script access for & have benefits beyond just modules.

Owner

chriseppstein commented May 29, 2013

Please keep in mind that these feature can be used within mixins that accept content blocks, etc. So an "@include module($name) { ... } " concept could be defined very easily. I think we will quickly find some very nice ways to create useful abstractions with this set of features. And as I have pointed out elsewhere, the @at-root directive and script access for & have benefits beyond just modules.

@aceofspades

This comment has been minimized.

Show comment
Hide comment
@aceofspades

aceofspades Dec 18, 2013

Has there been any discussion to do something more unobtrusive? For me, the value of namespacing comes in when integrating, where it's not possible or edit and maintain the source. For example, bootstrap and foundation both use .table which to me is too generic.

With styles.css:

.table {
  color: red;
}

Then

namespace mymod {
  @import "styles.css";
}

Would compile to

.mymod-table {
  color: red;
}

aceofspades commented Dec 18, 2013

Has there been any discussion to do something more unobtrusive? For me, the value of namespacing comes in when integrating, where it's not possible or edit and maintain the source. For example, bootstrap and foundation both use .table which to me is too generic.

With styles.css:

.table {
  color: red;
}

Then

namespace mymod {
  @import "styles.css";
}

Would compile to

.mymod-table {
  color: red;
}
@Vegasvikk

This comment has been minimized.

Show comment
Hide comment
@Vegasvikk

Vegasvikk Dec 5, 2014

Can someone please give another example of how namespacing might be used--thanks @aceofspades, I just would like to see it in another context.

Vegasvikk commented Dec 5, 2014

Can someone please give another example of how namespacing might be used--thanks @aceofspades, I just would like to see it in another context.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment