Scoping CSS / Prepend selector with LESS

2019-08-10 10:11发布

问题:

I have a chunk of CSS that I want to "scope" to a specific block of HTML. I'm generating a unique ID and then setting it on the block of HTML and then would like to wrap the chunk of CSS with the same ID so that those selectors can't match sibling or parent elements. I don't know the contents of the chunk of CSS. Given a chunk of CSS:

.container {
    background-color: black;
}

.container .title {
    color: white;
}

.container .description {
    color: grey;
}

I need it to come out like this:

.theme0 .container, .theme0.container {
    background-color: black;
}

.theme0 .container .title, .theme0.container .title {
    color: white;
}

.theme0 .container .description, .theme0.container .description {
    color: grey;
}

Is there any way to do this with LESS? The first selector is easy, just wrap the CSS chunk with '.theme0 {' + cssChunk + '}'. But I haven't been able to figure out a way to prepend '.theme0' to all of the selectors without the space.

EDIT: So I should clarify that our intentions are to build such a system into our build process / dependency system. We're attempting to scope a chunk of css to a react component. We have a couple different approaches we're trying out, this is just one of them. Point is, the CSS and HTML we're trying to scope could be anything, we have no control or knowledge of it. The first pattern can easily be achieved by prepending .uniqueID { and appending }. This gives .uniqueID .someSelector {}. I'm wondering if it's possible to do a similar thing but get .uniqueID.someSelector {}? Ideally without having to write the original chunk of CSS with knowledge of our scoping system.

回答1:

Assuming the component styles are in a separate CSS file, i.e.:

// component.css

.container {
    background-color: black;
}

.container .title {
    color: white;
}

.container .description {
    color: grey;
}

The wrapper code could be:

.theme0 {
    @import (less) "component.css";
    &.container:extend(.theme0 .container all) {}
}


回答2:

in less you can nest selectors for selecting inside that element like:

.theme {
    color: black;
    .container {
        color: blue;
    }
}

This wil generate:

.theme {
    color:black;
}
.theme .container {
    color:blue;
}

Creating elements that are connected is easy enof: .test#badge will select a class test width an id badge

In less this is dont with the & symbol. (this selects the starting property)

.test {
    color: blue;
    &#badge {
        color:black;
    }
}

Compiles to:

.test {
    color: blue;
}
.test#badge {
    color: black;
}

And for the final selector:
To get the output of .test, .container use the function: .test:extends(.container);

.test {
    color: black;
    &:extends(.conatiner);
}
.container {
    color: pink;
}

Compiles to: .test { color: black; } .test, .container { color: pink; }

You can even extend multiple ones in a single line:
.test:extends(.oclas, .tclss);
and its wil work as abose only for both classes. So outputed selectors would be .test, .oclass and .test, .tclass



标签: css less