3

I have a question. So in a mixing I am making a reference to the parent selector "&". This works as long as the mixin is not nested. Is there a way to to detect if the mixing is being used in a non nested scenario, or to check if "&" is null?

This works when the mixin call is not nested

=myresponsiveMixin($media)
  @if $media == small {
    @media only screen and (max-width: $break-small)
       @content
  @else if $media == medium
    @media only screen and (min-width: $break-small + 1) and (max-width: $break-large - 1)
       @content

This works great when the mixin call is nested, but will not resolve '&' when not nested

 =myresponsiveMixin($media)
      @if $media == small {
        @media only screen and (max-width: $break-small)
           .classInHTMLToAllowMediaQueries &
               @content
      @else if $media == medium
        @media only screen and (min-width: $break-small + 1) and (max-width: $break-large - 1)
           .classInHTMLToAllowMediaQueries &
               @content

So the question is, if there is a way to be able to check the value of parent selector "&", so I can cover all bases in a single mixin?

Andres Gallo
  • 671
  • 6
  • 13
  • 2
    Can you give a concrete example? You may have an [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – bookcasey Mar 27 '13 at 20:57
  • I want to be able to use a mixin with a parent class.For example =responsiveMixin .responsive & Do responsive stuff a mixin like the above will work as long as the mixing is called while nested. But I want it to be usable even when not nested. For example. – Andres Gallo Mar 27 '13 at 21:01
  • 1
    Please edit your initial question and provide the code. – Andrey Mikhaylov - lolmaus Mar 28 '13 at 16:34

2 Answers2

5
@mixin does-parent-exist {
  @if & {
    .exists & {
      color: red;
    }
  } @else {
    .doesnt-exist {
      color: red;
    }
  }
}

http://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-script

Valentin E
  • 1,363
  • 11
  • 11
0

You're trying a wrong solution to solve your issue.

Have a look at how this problem is addressed in powerful SASS frameworks. Let's take Susy by Eric Meyer as a great example.

Let's imagine you've got the following HTML:

<div class="container">
  <div class="parent">
    <div class="child">
      Bla bla
    </div>
  </div>
</div>

When you call a mixin for the first time, you're doing it simply (the code is in the indented .sass syntax):

$total-columns: 8 // Declaring a varible that will be used by the mixin

.parent
  +span-columns(4) // Span four of eight columns

But when you call that for a child element, the proportions would be crooked, because the parent is already proportioned:

.child
  +span-columns(2) // This will fail. You want 2 of 8 columns,
                   // but due to nesting the math is crooked.
                   // It will be "2 of (4 of 8)".

To address the issue, you provide an optional argument: a context that is used to do the math:

.child
  +span-columns(2, 4) // Now the mixin will take 2 parts of 4
                      // instead of 2 parts of four

The source code for this mixin is available on GitHub.

In short, it creates an optional argument like this (the code is in the CSS-like .scss syntax):

@mixin span-columns(
  $columns,
  $context: $total-columns
  //...
) {
  //...
  width: columns($cols, $context /*...*/);
  //...
}

See how $context has a default value? Thanks to the default value this argument can be omitted. In other words, $context is an optional argument.

When calling this mixin, if $context is not provided (e. g. span-columns(2)), then it is set equal to $total-columns. The $total-columns variable should be set prior to calling the mixin for the first time (see my example above).

Then the two arguments are used to calculate the width.

UPD 2013-03-30

I am not trying to figure out things in regards to columns... I have modifier my question to make it clearer.

First of all, my recommendation concerns not only grid columns. It's a universal technique you can adopt.

Secondly, now i see that you're trying to nest media queries.

Well, some media queries of different type can be combined in CSS3: e. g. print and width. But you can't put a min-width: 601px inside max-width: 600px, this just won't work!

There's an extensive answer here on StackOverflow describing why you should not nest media queries of the same type: https://stackoverflow.com/a/11747166/901944

Thirdly, you're trying to invent the wheel. There's already a fantastic mixin for crunching media queries: Respond To by Snugug. It's super easy to use and very effective.

Fourthly, the XY thing. Instead of asking about your crooked mixin, please describe the problem that you're trying to solve with it! Show us the actual HTML and explain what behavior you would like to achieve.

We will show you that it can be solved with a simple, elegant, semantic solution that does not require SASS hacking.

Community
  • 1
  • 1
Andrey Mikhaylov - lolmaus
  • 23,107
  • 6
  • 84
  • 133
  • I am not trying to figure out things in regards to columns... I have modifier my question to make it clearer. – Andres Gallo Mar 30 '13 at 01:27
  • The media mixin I have above is exactly the same as respond to. Its just in scss format. But that being the case neither of the two solve the issue i have. If you read the media query above the output is the same, and there is no nesting of media queries. The output is exactly the same as that of respond to, as its the same thing in SASS syntax. Now the second media query allows me to ignore the media queries when the class `. classInHTMLToAllowMediaQueries` is not available to boot. Allows me to disable responsive in some sections. The problem is it uses parent selector. – Andres Gallo Mar 30 '13 at 13:35
  • Oh, now i understand you. Please tell me why are you using a class to enable media queries? – Andrey Mikhaylov - lolmaus Mar 30 '13 at 15:04
  • Gonna weigh in here, because I'm encountering a similar problem: I believe that `.classInHTMLToAllowMediaQueries` is actually a class that gets added on (via JavaScript, UA sniffing (evil), or IE conditional comments) when media queries aren't supported. So IE8 might get the desktop version. – Paul d'Aoust Sep 11 '13 at 17:55
  • Then it would be a class to enable a mediaquery-less design. – Andrey Mikhaylov - lolmaus Sep 11 '13 at 21:49