Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend dynamically-generated selectors #1539

Closed
radium-v opened this issue Sep 10, 2013 · 10 comments
Closed

Extend dynamically-generated selectors #1539

radium-v opened this issue Sep 10, 2013 · 10 comments

Comments

@radium-v
Copy link
Contributor

Hi,

I'd like to have a recursive mixin that generates step classes, which can be used for extends.

Here's an example. For now, let's disregard that the ._t--prefixed classes get output in the compiled CSS (that's for another ticket).

@base-font-size: 16px;
@min-font-size: 8px;

._t {
    .step(@font-size) when (@font-size > @min-font-size) {

        &-@{font-size} { // this is the dynamic class

            font-size: unit(@font-size / @base-font-size, rem);

            .no-cssremunit & { // modernizr hook
                font-size: @font-size;
            }
        }
        .step(@font-size - 1);
    }
    .step(9px);
}

.box:extend(._t-9px all) {
    display: block;
}

Here's what I'd like it to output:

._t-9px,
.box {
  font-size: 0.5625rem;
}
.no-cssremunit ._t-9px,
.no-cssremunit .box {
  font-size: 9px;
}
.box {
  display: block;
}

Here's what it actually outputs:

._t-9px {
  font-size: 0.5625rem;
}
.no-cssremunit ._t-9px {
  font-size: 9px;
}
.box {
  display: block;
}

The issue depends on #1177 and probably a few others - of course I don't want every selector between ._t-140px and ._t-8px but if mixins could be extended, I wouldn't have a problem with writing the font classes manually (which would prevent them from being output in the generated CSS).

Any thoughts on the best way to implement a system like this, or should I adjust my approach?

@radium-v
Copy link
Contributor Author

Most likely related to #1196.

A workaround for the future is to build the mixin to a separate, temporary stylesheet and then include it as a reference import.

First, build type.less

@min-font-size: 8px;
@base-font-size: 16px;
._t {
    .step(@font-size) when (@font-size > @min-font-size) {
        &-@{font-size} {
            font-size: unit((@font-size / @base-font-size), rem);
            .no-cssremunit & {
                font-size: @font-size;
            }
        }
        .step((@font-size - 1));
    }
    .step(11px);
}

Then, build box.less

@import (reference) "type.less";
.box {
    &:extend(._t-9px all);
}

Outputs:

._t-11px { font-size: 0.6875rem; }
.no-cssremunit ._t-11px { font-size: 11px; }
._t-10px { font-size: 0.625rem; }
.no-cssremunit ._t-10px { font-size: 10px; }
._t-9px { font-size: 0.5625rem; }
.no-cssremunit ._t-9px { font-size: 9px; }
._t-9px,
.box {
  font-size: 0.5625rem;
}
.no-cssremunit ._t-9px,
.no-cssremunit .box {
  font-size: 9px;
}

The problem of course is that two separate stylesheets need to be built. It works, but I'd like to avoid a build script dependency.

What if reference-type @import files could be compiled independently? It'd require that the referenced build be able to compile without requiring other sibling imports as dependencies.

@theoephraim
Copy link

+1

Another useful case where this comes up is when generating grid system classes. Ideally, you should be able to use the grid classes directly in your html or extend them in your LESS.

I've been working on porting over the Foundation 4 grid to LESS and it works well, except I can't extend the grid classes. I can use a mixin instead, but it will result in a ton of repeated code.

A simplified example of how I'd like it to work:

@num-cols: 12;
@mq-screen: ~"only screen";
@mq-small: ~"only screen and (min-width: @{small-screen})";

// recursive call to generate column classes
.createCols(@size, @index) when (@index >= 1){
  .@{size}-@{index} {
    position:relative;
    width:@index/@num-cols;
  }
  .createCols(@size, @index - 1);
}


@media @mq-screen {
  .createCols(small, 12);    // creates .small-1, .small-2, ..., .small-12
}
@media @mq-small {
  .createCols(medium, 12);    // creates .medium-1, .medium-2, ..., .medium-12
}

.my-classname{
  &:extends(.small-3);
  &:extends(.medium-5);
}

This should ideally make the .my-classname class show up with the small-3 and medium-5 classes within their respective media queries.

@Craga89
Copy link

Craga89 commented Jan 8, 2014

👍 to this. Currently working on a project using FontAwesome and it would be great to be able to extend their @{fa-css-prefix}{} classes for use in CKEditor.

@seven-phases-max
Copy link
Member

Just in case for the FA there's "FA specific" workaround (the second example).

@Craga89
Copy link

Craga89 commented Jan 9, 2014

Great! I worked around it like so, should anyone stumble on this:

// Font Awesome helper
.icon() {
    display: inline-block;
    font-family: FontAwesome;
    font-style: normal;
    font-weight: normal;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.icon(@icon) {
    &:before{
        @fa-icon: "fa-var-@{icon}";
        content: @@fa-icon;
    }
}

Unfortunately I had to repeat the styles of the ~{fa-css-prefix}{} class, but other than that it works great.

@seven-phases-max seven-phases-max changed the title Extend dynamically-generated selectors Extend dynamically-generated selectors (interpolated identifier + concatenated identifier) Sep 18, 2014
@seven-phases-max
Copy link
Member

^ I'm just trying to slightly sort all these "extend dynamically generated selector" issues by adding a bit more specific names to them (the problem is that most of such tickets cover 2-3 quite unrelated extend issues together and thus overlapping by 1-2 of those with each other but with no clear point which one could be merged with which another :)

@lukeapage
Copy link
Member

@seven-phases-max I wanted to fix it in a general way - if a selector includes interpolation, attempt re-parsing it. I haven't given it a go yet though. Was thinking to pull selector parsing into its own class.

@seven-phases-max
Copy link
Member

@lukeapage OK, I was just thinking of maybe merging all these into one issue with minimal and simplified example for each "sub-issue" for easier tracking. But probably it's not worth that (yet at least).

@lukeapage
Copy link
Member

Great, sounds good, didn't mean to sound anti what you were doing, was just
replying quickly.

@seven-phases-max
Copy link
Member

Merging to #2200.

@seven-phases-max seven-phases-max changed the title Extend dynamically-generated selectors (interpolated identifier + concatenated identifier) Extend dynamically-generated selectors Sep 18, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants