multiple nested selectors with variables in Less

2020-02-13 05:15发布

I want to build some CSS along these lines:

h1,h2,h3,h4,h5,h6 {some rule}
h1 a,h2 a,h3 a,h4 a,h5 a,h6 a {color: inherit;}
h1 span,h2 span,h3 span,h4 span,h5 span,h6 span {another rule;}

It would be useful if I could create a variable like this:

@headings: h1,h2,h3,h4,h5,h6;

and then maybe do something like this:

@{headings} {
  & a {color: inherit;}
}

Unfortunately this gives me:

h1, h2, h3, h4, h5, h6 a {
  color: inherit;
}

Is what I want possible? This is a simple version of what I want to do but I would also find useful for working with HTML input types and other instances of multiple selectors that often appear together.

3条回答
兄弟一词,经得起流年.
2楼-- · 2020-02-13 05:55

#1 Just yet one more solution in addition to @helderdarocha's answer and those given in https://stackoverflow.com/a/23954580/2712740. Maybe be this one could look a bit more clear:

// define header list as usual just
// put a mixin call with some predefined name there
h1, h2, h3, h4, h5, h6 {.headings}

// now to add styles/childs to the header list just add the mixin definitions:

.headings() {
    some: rule;
}

.headings() {
  a {color: inherit}
}

.headings() {
  span {another: rule}
}

// etc.

The limitation of this solution is that h1, h2, h3 ... {} and .headings should be defined at the same level. Additionally, it's important to keep in mind that all these styles will output to CSS at the point of h1, h2, h3 ... {} definition not at the point of .headings definitions, so it may break your cascading overrides if you have some).


#2 The alt. solution I'm copy-pasting from https://stackoverflow.com/a/23954580/2712740 #3, basicaly it's the same as #1 but w/o its limitations (just having more special scary symbols):

// the "variable":
.headings(@-) {
    h1, h2, h3, h4, h5, h6
        {@-();}}


// usage:

.headings({
    some: rule;
});

.headings({
    a {color: inherit}
});

.headings({
    span {another: rule}
});

//etc.
查看更多
ゆ 、 Hurt°
3楼-- · 2020-02-13 06:04

Use a Ruleset

If you define your heading group as a ruleset with a mixin call to set properties with, then you can do this:

@headings: {h1,h2,h3,h4,h5,h6 {.setProps()}};


& {
    .setProps() {
        & {
            some: rule;
        }
        a {
            color: inherit;
        }
        span {
            another: rule;
        }
    }
    @headings();
}

I've isolated the whole thing inside & just so the .setProps() can be localized (it would work without it, but it would be setting the .setProps() globally. Also, the nested & {} bracketing is not necessary, but I find that it helps show what the "default" for the @headings is going to be.

This can be used sequentially, if desired, like so:

& {
    .setProps() {  some: rule; }
    @headings();
}
& {
    .setProps() { a {color: inherit;}}
    @headings();
}
& {
    .setProps() { span {another: rule;}}
    @headings();
}

Both will output like so:

h1,
h2,
h3,
h4,
h5,
h6 {
  some: rule;
}
h1 a,
h2 a,
h3 a,
h4 a,
h5 a,
h6 a {
  color: inherit;
}
h1 span,
h2 span,
h3 span,
h4 span,
h5 span,
h6 span {
  another: rule;
}
查看更多
狗以群分
4楼-- · 2020-02-13 06:21

If you have these variables and selectors:

@headings: h1,h2,h3,h4,h5,h6;

@{headings} {
    some-rule: rule;    
}
.headings { // this is a placeholder
    color: inherit;
}
h1 span {
    other-rule: rule;
}

You can use this mixin to generate the code you want:

.mixin(@headings; @count) when (@count > 0) {
    .mixin(@headings; @count - 1);
    @heading: extract(@headings, @count);
    @{heading}{
        & a:extend(.headings) {}
        & a:extend(h1 span) when not (@heading = h1) {}
    }
}

Calling:

.mixin(@headings, length(@headings));

will generate:

h1, h2, h3, h4, h5, h6 {
  some-rule: rule;
}
.headings,
h1 a,
h2 a,
h3 a,
h4 a,
h5 a,
h6 a {
  color: inherit;
}
h1 span,
h2 a,
h3 a,
h4 a,
h5 a,
h6 a {
  other-rule: rule;
}
查看更多
登录 后发表回答