Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
515 views
in Technique[技术] by (71.8m points)

css - Nesting selectors via loops with SASS

I have this HTML

<ul> // first level
  <li>
    <ul></ul> // second level
  </li>
  <li>
    <ul> // second level
      <li>
        <ul></ul> // third level
      </li>
    </ul>
  </li>
</ul>

Is there any possible to loop nested lists one in another, to get something like this:

ul {
 padding: 10px;
 ul {
  padding: 20px;
  ul {
    padding: 30px;
    ... through 10 * ul
  }
 }
}  

With this i have only list multiplication.

@for $i from 1 through 10 {
    ul {
        padding-left: 100 - (10 * $i) + px;
    }
  }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

For Sass versions prior to 3.4, the function you need to do this is not part of native Sass (and recursive mixins don't work in certain versions). You need Compass function called nest().

$sel: '';
@for $i from 1 through 10 {
    // remove !global flag if you're using Sass < 3.3
    $sel: if($i == 1, "ul", nest($sel, "ul")) !global;

    #{$sel} {
        padding-left: 10px * $i;
    }
}

Sass 3.4 has a native version of this function called selector-nest():

$sel: '';
@for $i from 1 through 10 {
    $sel: if($i == 1, "ul", selector-nest($sel, "ul")) !global;

    #{$sel} {
        padding-left: 10px * $i;
    }
}

Output:

ul {
  padding-left: 10px;
}

ul ul {
  padding-left: 20px;
}

ul ul ul {
  padding-left: 30px;
}

ul ul ul ul {
  padding-left: 40px;
}

ul ul ul ul ul {
  padding-left: 50px;
}

ul ul ul ul ul ul {
  padding-left: 60px;
}

ul ul ul ul ul ul ul {
  padding-left: 70px;
}

ul ul ul ul ul ul ul ul {
  padding-left: 80px;
}

ul ul ul ul ul ul ul ul ul {
  padding-left: 90px;
}

ul ul ul ul ul ul ul ul ul ul {
  padding-left: 100px;
}

If you want to spell out the initial ul, then you would do it like this:

ul {
    // parent styles
    border: 1px solid;

    $sel: '';
    @for $i from 2 through 10 {
        $sel: if($i == 2, 'ul', nest($sel, 'ul')); // note no !global flag

        #{$sel} {
            padding-left: 10px * $i;
        }
    }
}

Note that you could use simple string concatenation instead of either of these functions, but it will only work in cases where you're only nesting a single selector. If you have 2 or more selectors, this is absolutely necessary:

$sel: '';
@for $i from 1 through 3 {
    $sel: if($i == 1, "article, section", selector-nest($sel, "article, section")) !global;

    #{$sel} {
      h1 {
        padding-left: 10px * $i;
      }
    }
}

Output:

article h1, section h1 {
  padding-left: 10px;
}

article article h1, article section h1, section article h1, section section h1 {
  padding-left: 20px;
}

article article article h1, article article section h1, article section article h1, article section section h1, section article article h1, section article section h1, section section article h1, section section section h1 {
  padding-left: 30px;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...