npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

postcss-reference

v2.2.1

Published

PostCSS plugin for referencing selectors' rules from CSS files and defined rulesets.

Downloads

128

Readme

PostCSS Reference Build Status

PostCSS plugin for referencing selectors' rules from CSS files and defined rulesets. Will not output rules unless directly referenced in your stylesheet. Concept follows LESS's @import (reference) 'filename' functionality but with slightly different syntax and usage. The goal for the plugin is to allow for the kinds of advanced usage of LESS's @extend and @import(reference) methods as outlined in this article on Semantic Remapping for PostCSS. The Plugin can currently replicate most examples for this article.

Basic syntax:

Rules placed in the @reference block are mapped to a comparison array and discarded from the AST. Rules from your style sheet which then use an @references selectorName; declaration will have their requested selector compared against the rules in your comparison array. All instances of @references have to be declarations.

/* Input */
@reference {
    header {
        display: block;
    }
}

header {
    @references header;
    margin: 0;
}
/* Output */
header {
    display: block;
    margin: 0;
}

Using the all flag:

When a @references selectorName declaration uses the 'all' flag, [PostCSS Reference] will look for all selectors in the @reference block which begin with the requested selector.

/* Input */
@reference {
    header {
        display: block;
    }

    header h1 {
        font-family: Arial;
    }

    .header-alt {
        color: blue;
        font-family: "Times New Roman";
    }

    .widget header {
        padding-left: 1em;
    }
}

header {
    @references header all;
    margin: 0;
}
/* Output */
header {
    display: block;
    margin: 0;
}

header h1 {
    font-family: Arial;
}

Note that .header-alt and .widget header are ignored as those rules are not an exact match, pseudo-class, sibling, or descendant of the requesting rule.

Make sure the rules being referenced come before the rule whose @references declaration is making the request; i.e. put your dependencies first. This allows for very powerful CSS component abstractions.

Media Queries

Additionally, [Postcss Reference] can read rules from inside media queries. Items can be referenced across matching media queries, or if a non-media-query wrapped rule references a selector with the 'all' flag, and the requested reference rules have matches wrapped in any media queries. For example:

/* Input */
@reference {
    article {
        width: 100%;
    }

    @media (min-width: 900px) {
        article {
            width: 75%;
        }
    }
}

@media (min-width: 900px) {
    article {
        display: block;
        @references article;
    }
}

/* Output */
@media (min-width: 900px) {
    article {
        display: block;
        width: 75%;
    }
}

...or...

/* Input */
@reference {
    article {
        width: 100%;
    }

    @media (min-width: 900px) {
        article {
            width: 75%;
        }
    }
}

article {
    display: block;
    @references article all;
}

/* Output */
article {
    display: block;
    width: 100%;
}

@media (min-width: 900px) {
    article {
        width: 75%;
    }
}

comma separated @references requests will return declarations from any matched selectors. So...

    header {
        @references header, footer;
    }

...would match any header or footer selectors. It would also match selectors that have the same comma separated combination in any order. So a reference rule with a selector like footer, header would return the same declarations as just header. Superfluous or unmatched selectors are ignored. So footer, header, section {} would still return a match, and section would be ignored.

Comma separated reference requests can have their own parameters. So a declaration like @references header all, footer would return all exact and related matches for header, but only exact matches for footer.

Cross media-query references

PostCSS Reference has the unique ability to reference selectors across disparate media queries.

Referencing a selector that has no media query, when the requesting selector is in a media query will yield a match if the @references request is wrapped with an @references-media atRule with no params

  /* Input */
  @reference {
    .my-glorious-selector {
      color: blue;
      display: block;
    }
  }

  @media (min-width: 768px) {
    button {
      color: black;
      display: inline-block;

      @references-media {
        @references .my-glorious-selector all;
      }
    }
  }  

  /* Output */
  @media (min-width: 768px) {
    button {
      color: blue;
      display: block
    }
  }

Referencing a selector that has a media query, when the requesting selector is in a different media query will yield a match if the @references request is wrapped with an @references-media atRule and has the target media query as a parameter

  /* Input */
  @reference {
    @media (max-width: 479px) {
      .my-glorious-selector {
        color: blue;
        display: block;
      }
    }
  }

  @media (min-width: 768px) {
    button {
      color: black;
      display: inline-block;

      @references-media (max-width: 479px) {
        @references .my-glorious-selector all;
      }
    }
  }

  /* Output */
  @media (min-width: 768px) {
    button {
      color: blue;
      display: block
    }
  }

Since the v2.0 rewrite [PostCSS Reference] does not currently provide predictable support for nested style inside the @reference block. This is something I may work on if there is desire for it.

Using @import:

postcss-import and most other @import related plugins do not resolve well inside the @reference AtRule block, so [PostCSS Reference] includes its own logic for retrieving the contents of local files and injecting any parsed rules into the requesting stylesheet.

In this example we import the entirety of Yahoo's PureCSS core library so that we can reference the .pure-button and .pure-button-primary rules. The unreferenced rules in pure.css are discarded.

/* Input */
@reference {
    @import 'pure.css';
}

button {
    @references .pure-button, .pure-button-primary;
}
/* Output */
button {
    display: inline-block;
    zoom: 1;
    line-height: normal;
    white-space: nowrap;
    vertical-align: middle;
    text-align: center;
    cursor: pointer;
    -webkit-user-drag: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    font-family: inherit;
    font-size: 100%;
    padding: 0.5em 1em;
    color: #444;
    border: 1px solid #999;
    background-color: #E6E6E6;
    text-decoration: none;
    border-radius: 2px;
}

All the strategies and considerations detailed above should hold true when using @import inside the @reference block, and media-queries can be referenced or included if desired.

While other @import related plugins do not work well for use inside of the @reference block, use of them outside of it should be unaffected. Initial tests with postcss-import and ParcelJS's in-built @import functionality work just fine when they are the first node in the stylesheet.

Usage

At present, [Postcss Reference] does not take any options. That may be subject to change.

postcss([ require('postcss-reference') ])

See PostCSS docs for examples for your environment.

TODO's for the next release:

  • Adding logic for (or identifying a compatible plugin for) @importing remote resources; i.e. download and inject CSS from a URL
  • Handling nested reference block contents