Giter VIP home page Giter VIP logo

icss's Introduction

CSS Modules Logo

CSS Modules

A CSS Module is a CSS file where all class names and animation names are scoped locally by default. All URLs (url(...)) and @imports are in module request format (./xxx and ../xxx means relative, xxx and xxx/yyy means in modules folder, i.e. in node_modules).

CSS Modules compile to a low-level interchange format called ICSS (or Interoperable CSS) but are written like normal CSS files:

/* style.css */
.className {
  color: green;
}

When importing a CSS Module from a JavaScript Module, it exports an object with all mappings from local names to global names.

import styles from './style.css';

element.innerHTML = '<div class="' + styles.className + '">';

Table of Contents

Why CSS Modules?

  • Local Scope Prevents Clashes: CSS Modules use local scope to avoid style conflicts across different project parts, allowing component-scoped styling.
  • Clear Style Dependencies: Importing styles into their respective components clarifies which styles impact which areas, enhancing code readability and maintenance.
  • Solves Global Scope Problems: CSS Modules prevent the common issue of styles in one file affecting the entire project by localizing styles to specific components.
  • Boosts Reusability and Modularity: CSS Modules allow the same class names in different modules, promoting modular, reusable styling.

icss's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

icss's Issues

[rfc] Disallowing duplicate keys across :export blocks

I'm writing to suggest a revision to the icss spec (If this has already been discussed, my apologies).

Currently, duplicate keys and multiple :export blocks are both valid icss, but I think the combination is awkward.

Consider the case where you edit a file with two :export blocks - one at the start and one at the end, not appearing on screen at the same time. If a key is duplicated between these blocks, changes made in the 'obvious' place (the first block) will appear to be silently swallowed.

I can see a few possible changes that reduce the impact of this:

  • Disallow duplicate keys between blocks (I'd hope there are not many cases where this would break)
  • Disallow duplicate keys at all (I can't think of a situation where duplicate keys are something other than an accident, but backwards compatibility makes this hard)
  • Disallow multiple export blocks (backwards compatibility also makes this hard)

RFC: Require imports to appear before they are used

The current spec as written requires a backtracking parser, as it does not enforce that imports appear before they are used.

Writing a backtracking parser is significantly more work than writing a single-pass parser, and this makes implementing compatible tools harder.

I propose that the spec be amended to state that :import applies from that point in the file to the end of the file and does not modify anything earlier in the file.

Test cases

I'm keen to see multiple implementations of this (and am interested in contributing one).

Would this repo be an appropriate place to add test cases which implementations should conform to? Are there already test cases I can crib from another project?

ICSS2 implementation questions

  1. How to deal with imported media queries? I got a bit of mess in postcss-import to resolve and and or operators. Should we even implement whole spec complexity.
// imported.css
@media screen or (min-width: 2) { .foo {} }
.bar {}
// importer.css
@import "imported.css" (max-width: 3);
// becomes
@media screen and (max-width: 3) or (min-widh: 2) and (max-width: 3) { .foo {} }
@media (max-width: 3) { .bar {} }
  1. Should imported identifiers be localized If local-by-default is enabled? Spec allows to specify exported tokens but @import syntax is too simple for that. So only :global improted identifiers make sense.
// imported.css
.foo {}
// importer.css
@import 'imported.css';
.bar {}
// becomes
.foo--hash {}
.bar--hash {}
:export {
  bar: bar--hash;
}

Ref https://medium.com/@sokra/79583bd107d7

/cc @sokra @geelen @sullenor @michael-ciniawsky

Ignoring leading dot class name

Using the replaceDeclarations feature of postcss-nested-ancestors you can reference parent selectors of nested blocks not only in your selectors themselves, but also in your declarations. For example:

.cell {
  padding: .5em;

  &--id {
    composes: ^&; /* replaced with `composes: .cell;` */
    font-weight: 500;
  }

  &--value {
    composes: ^&; /* replaced with `composes: .cell;` */
    font-style: italic;
  }
}

This would enable pretty straight forward BEM-ish composition, where the user only needs to add a modifier class (.cell--id) and the base class (.cell) gets applied automatically.

However, the replacement composes declaration is invalid, since the class name is prefixed with a dot.

Build Error (CSSModules) in foo.css:27:5
postcss-modules-scope: referenced class name ".cell" in composes not found

I could write a postcss plugin that removes the leading dots automatically or adds an unclass(^&) function or something like that, but this seems like a rather simple change that could be made in this plugin, possibly behind a flag.

Original css-modules/postcss-icss-composes#168

ICSS added as Stackoverflow tag

I want to invite everyone to add more substance to the wiki entry of the newly created ICSS tag on Stackoverflow.
I proposed to add the tag and a mod followed the proposal and created it.

I wrote a small wiki excerpt, closely following the phraseology from your README.

Imported local aliases not working when used in selectors

I'm trying to import a class name from one CSS module into another. The find and replace works if I use the local alias as a declaration value but not when used in a selector. For example:

// foo.scss
.foo {
    color: blue;
}
// bar.scss

:import("foo.scss") {
    fooClassName: foo;
}

.fooClassName .bar { // <-- this doesn't get replaced :(
    color: red;
}
// baz.scss

:import("foo.scss") {
    fooClassName: foo;
}

.baz {
    color: fooClassName; // <-- this does get replaced :)
}

When bar.scss is compiled / output, fooClassName hasn't been found and replaced with the generated local-scope class name from foo.scss. However, when baz.scss is compiled / output on the page, the declaration value of the color property does indeed have the correct generated local-scope class name (obviously that's not helpful, but it demonstrates that it pulls through the correct class name, even if the context in which it's being used makes no sense).

The ICSS spec mentions:

An :import statement allows importing variables from other CSS files. It performs the following operations:

  • Find and replace the usages of localAlias in certain places (described below) within the current file with the dependency's exportedValue.

The places within the CSS file that are checked for localAlias are:

  • In any selector: e.g. .localAlias .MyComponent {}

Unfortunately it's not working as expected. We're using Webpack – is there a special option or flag we need to set to get this working? Appreciate any help.

PostCSS plugin?

Is there any PostCSS plugin that implements this specification the same way webpack css-loader does?

Problem is that when using other PostCSS that depends on imported constants, the order of loaders makes using this feature from css-loader not a possibility. So I was thinking if there was any PostCSS plugin that could help me with that, otherwise I would like to try to write one. Any guides in order to do it properly?

PS: I know this exists, but I do agree with this comment on that not being what I'm looking for.

Using : instead of @

First off, love the idea behind this spec. It seems to be very well thought out and something we should strive to achieve.

However, one thing really stood out, is that the spec is using : instead of @ for its structures, for example, :import compared to @import. It looks like an at-rule @ would be a far better choice, as it has built in functionality for such a use case, like:

At-rules seem to be the go to for such functionality that "defines", for example: @charset, @font-face, @keyframes, etc.

Is the only reason for avoiding at-rules is that @import has already been taken? It seems like it would be a great opportunity to extend @import and provide a super-set of functionality.

@import "path/to/dep.css" {
  localAlias: keyFromDep;
  /* ... */
}

JSON IR for icss

In order to make icss implementations reusable in a variety of languages and environments, it is desirable to have a standard way to store the mapping between logical and generated class names.

The obvious (to me) way would be to store <filename>.icss.json containing e.g.

{"button": "CONTACT__button__Xv7f2 CORE__typography-v8s8fj"}

Although I could be persuaded that it should instead be

{"button": ["CONTACT__button__Xv7f2", "CORE__typography-v8s8fj"]}

If the canonical implementations such as css-modules implemented something like this, it would become really easy to consume CSS modules from non-javascript projects.

Tweak to the BEM example

In README.md:

In BEM, that takes the form .block-name__element-name--modifier-name, or .BlockName__elementName--modifierName.

Looks like your second example is meant to illustrate the SUIT CSS flavor of BEM. If that is the case, it should be: .BlockName-elementName--modifierName.

Supporting global sections

Right now, if we have a bunch of global classes, that are interpreted in a locals-by-default context, we need to do this:

:global .classOne {
	background-color: black;
}

:global .classTwo {
	color: yellow;
}

/* This one is local */
.classThree {
	border: 1px solid yellow;
}

It would be nice if we could do something like this instead:

:global {
	.classOne {
		background-color: black;
	}

	.classTwo {
		color: yellow;
	}
}

/* This one is local */
.classThree {
	border: 1px solid yellow;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.