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

How to pass variable to common CSS classes #50

Closed
nsisodiya opened this Issue Sep 12, 2015 · 16 comments

Comments

Projects
None yet
9 participants
@nsisodiya

nsisodiya commented Sep 12, 2015

I recently adopted css-modules

.boxShadow {
    -moz-box-shadow: inset 0 -2px 0 rgba(0, 0, 0, .05);
    -webkit-box-shadow: inset 0 -2px 0 rgba(0, 0, 0, .05);
    -webkit-tap-highlight-color: rgba(169, 3, 41, .5);
}

this boxShadow class I have defined in common style.css. I am reusing composes at several places.
at some places, I want to use -3px instead of -2px. and Instead of rgba(0, 0, 0, .05) I want to use a separate color.
Currently I am creating multiple version of .boxShodow like .boxShadowBlueStyle, .boxShadowRedStyle.

@serapath

This comment has been minimized.

Show comment
Hide comment
@serapath

serapath Sep 12, 2015

There was an issue earlier, see #18

It's kind of related and I still don't know the answer to the problem.
I switched to a module called jss, because it gives me all the flexibility i need.

It allows:

  • defining component based stylesheets (parameterized, because its javascript)
  • updating a components stylesheet at runtime (even individual properties)
  • author your styling in css or in css es6 template strings and use jss-cli to convert it to jss on the fly

serapath commented Sep 12, 2015

There was an issue earlier, see #18

It's kind of related and I still don't know the answer to the problem.
I switched to a module called jss, because it gives me all the flexibility i need.

It allows:

  • defining component based stylesheets (parameterized, because its javascript)
  • updating a components stylesheet at runtime (even individual properties)
  • author your styling in css or in css es6 template strings and use jss-cli to convert it to jss on the fly
@rpominov

This comment has been minimized.

Show comment
Hide comment
@rpominov

rpominov Sep 16, 2015

You can use any css preprocessor before applying css-modules, like sass, less, or stylus. And use variables system from that preprocessor.

We do stylus -> autoprefixer -> css-modules and it works pretty nice for us.

rpominov commented Sep 16, 2015

You can use any css preprocessor before applying css-modules, like sass, less, or stylus. And use variables system from that preprocessor.

We do stylus -> autoprefixer -> css-modules and it works pretty nice for us.

@serapath

This comment has been minimized.

Show comment
Hide comment
@serapath

serapath Sep 16, 2015

How do you update those variables at runtime?

serapath commented Sep 16, 2015

How do you update those variables at runtime?

@rpominov

This comment has been minimized.

Show comment
Hide comment
@rpominov

rpominov Sep 16, 2015

Maybe I didn't understand original question right, but I think @nsisodiya didn't want to update them at runtime.

rpominov commented Sep 16, 2015

Maybe I didn't understand original question right, but I think @nsisodiya didn't want to update them at runtime.

@serapath

This comment has been minimized.

Show comment
Hide comment
@serapath

serapath Sep 16, 2015

I'd like to do that and afaik an es6 import or commonJS require call can get me the generated class names to add them, for example, to my "jsx markup".
It might be awesome to pass in or update "style variables" at runtime.

serapath commented Sep 16, 2015

I'd like to do that and afaik an es6 import or commonJS require call can get me the generated class names to add them, for example, to my "jsx markup".
It might be awesome to pass in or update "style variables" at runtime.

@nsisodiya

This comment has been minimized.

Show comment
Hide comment
@nsisodiya

nsisodiya Sep 16, 2015

I can use compass -> css files -> css-module.
only problem I am having, I do not want to keep generated css files in this flow.
currently I am having .css files in code repo. If I move to scss then I will keep only scss files and generated css files will go in /temp folder, in this case, referencing will be bit difficult.
currently I have having one js file and one css file per component folder.

nsisodiya commented Sep 16, 2015

I can use compass -> css files -> css-module.
only problem I am having, I do not want to keep generated css files in this flow.
currently I am having .css files in code repo. If I move to scss then I will keep only scss files and generated css files will go in /temp folder, in this case, referencing will be bit difficult.
currently I have having one js file and one css file per component folder.

@NekR

This comment has been minimized.

Show comment
Hide comment
@NekR

NekR Sep 16, 2015

With webpack you do not need all those tricks. Just use pipe of loaders.
On Sep 16, 2015 8:22 PM, "Narendra Sisodiya" notifications@github.com
wrote:

I can use compass -> css files -> css-module.
only problem I am having, I do not want to keep generated css files in
this flow.
currently I am having .css files in code repo. If I move to scss then I
will keep only scss files and generated css files will go in /temp folder,
in this case, referencing will be bit difficult.
currently I have having one js file and one css file per component folder.


Reply to this email directly or view it on GitHub
#50 (comment)
.

NekR commented Sep 16, 2015

With webpack you do not need all those tricks. Just use pipe of loaders.
On Sep 16, 2015 8:22 PM, "Narendra Sisodiya" notifications@github.com
wrote:

I can use compass -> css files -> css-module.
only problem I am having, I do not want to keep generated css files in
this flow.
currently I am having .css files in code repo. If I move to scss then I
will keep only scss files and generated css files will go in /temp folder,
in this case, referencing will be bit difficult.
currently I have having one js file and one css file per component folder.


Reply to this email directly or view it on GitHub
#50 (comment)
.

@rpominov

This comment has been minimized.

Show comment
Hide comment
@rpominov

rpominov Sep 16, 2015

Yeah, webpack makes it easy to use transformation pipeline as long as you want. You just specify in the config that you want stylus -> autoprefixer -> css-modules for *.styl files, for example, and then simply do:

css = require('file.styl')
css.myClass // contains name of class `.myClass` from `file.styl`

Probably similar can be done with browserify.

rpominov commented Sep 16, 2015

Yeah, webpack makes it easy to use transformation pipeline as long as you want. You just specify in the config that you want stylus -> autoprefixer -> css-modules for *.styl files, for example, and then simply do:

css = require('file.styl')
css.myClass // contains name of class `.myClass` from `file.styl`

Probably similar can be done with browserify.

@jeron-diovis

This comment has been minimized.

Show comment
Hide comment
@jeron-diovis

jeron-diovis Sep 17, 2015

@rpominov Do you use composes statement from css-modules in your stylus code, or you decided to never use it?
I tried similar pipeline with Sass. Have following files:

// mixins.scss
@mixin myMixin {
  ...
}

// style1.scss
@import "mixins.scss";

@include myMixin;

.someClass { ... }

// style2.scss
.anotherClass {
   composes: someClass from "style1.scss"
}

This simple code fails with

Module not found: Error: Cannot resolve module 'mixins.scss' in /path/to/style1.scss

After removing composes from style2.scss everything just works.

So, do you use css-modules only for providing unique classnames, without any additional features, and prepocessor for everything else?

jeron-diovis commented Sep 17, 2015

@rpominov Do you use composes statement from css-modules in your stylus code, or you decided to never use it?
I tried similar pipeline with Sass. Have following files:

// mixins.scss
@mixin myMixin {
  ...
}

// style1.scss
@import "mixins.scss";

@include myMixin;

.someClass { ... }

// style2.scss
.anotherClass {
   composes: someClass from "style1.scss"
}

This simple code fails with

Module not found: Error: Cannot resolve module 'mixins.scss' in /path/to/style1.scss

After removing composes from style2.scss everything just works.

So, do you use css-modules only for providing unique classnames, without any additional features, and prepocessor for everything else?

@rpominov

This comment has been minimized.

Show comment
Hide comment
@rpominov

rpominov Sep 17, 2015

So, do you use css-modules only for providing unique classnames, without any additional features, and prepocessor for everything else?

Yeah, basically this. I haven't used it very long yet, but so far I only needed unique classnames.

rpominov commented Sep 17, 2015

So, do you use css-modules only for providing unique classnames, without any additional features, and prepocessor for everything else?

Yeah, basically this. I haven't used it very long yet, but so far I only needed unique classnames.

@roylee0704

This comment has been minimized.

Show comment
Hide comment
@roylee0704

roylee0704 Nov 24, 2015

I think the following README from react-css-modules might show-case how css preprocessors and css work together in webpack.
https://github.com/gajus/react-css-modules#sass-scss-less-and-other-css-preprocessors

example:

{
    test: /\.scss$/,
    loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!sass')
}

Note: loader-queries are processed from right to left.

roylee0704 commented Nov 24, 2015

I think the following README from react-css-modules might show-case how css preprocessors and css work together in webpack.
https://github.com/gajus/react-css-modules#sass-scss-less-and-other-css-preprocessors

example:

{
    test: /\.scss$/,
    loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!sass')
}

Note: loader-queries are processed from right to left.

@roylee0704

This comment has been minimized.

Show comment
Hide comment
@roylee0704

roylee0704 Nov 24, 2015

or it can actually be achieved without using any css-processors. Check this out: https://github.com/MadLittleMods/postcss-css-variables

roylee0704 commented Nov 24, 2015

or it can actually be achieved without using any css-processors. Check this out: https://github.com/MadLittleMods/postcss-css-variables

@StevenIseki

This comment has been minimized.

Show comment
Hide comment
@StevenIseki

StevenIseki Nov 30, 2015

Contributor

The best approach I have found so far is to export your variables as @value's

colors.css

@value blue: #0c77f8;
@value red: #ff0000;
@value white: #fff;

header.css

@value colors: "./colors.css";
@value blue, white, red from colors;

.header {
  color: blue;
  background-color: red;
}

Using postcss-modules-values plugin

Contributor

StevenIseki commented Nov 30, 2015

The best approach I have found so far is to export your variables as @value's

colors.css

@value blue: #0c77f8;
@value red: #ff0000;
@value white: #fff;

header.css

@value colors: "./colors.css";
@value blue, white, red from colors;

.header {
  color: blue;
  background-color: red;
}

Using postcss-modules-values plugin

@serapath

This comment has been minimized.

Show comment
Hide comment
@serapath

serapath Nov 30, 2015

If you compare it with javascript it basically means that instead of requireing or importing X, thus re-using X and "customize" it to your needs (=calling a function with arguments)....

While you write X (e.g. define a function in javascript), you already import or require all the arguments you might need...

While writing header.css, how can i possibly know all the scenarios in which i want to use it?
Maybe I could look about everything that is imported by the modules I will use and just overwrite color.css in my new project - but does that work if you have nested dependencies?

For me, when writing re-usable components, the approach css-modules take doesnt work for me and variables or the lack of passing in arguments when importing a css file is only one reason. Another one is dynamically adapting styling based on user interaction, so i switched to jss for now.
There it's easy to use variables, so I can write something like:

module.exports = function header (params) {
  return `
    .header {
      color: ${params.blue};
      background-color: ${params.red};
    }
  `
}

Then when re-using my component somehwere else :-)

var colors = { blue: '#0c77f8', red: '#ff0000', white: '#fff' }
var header = require('./header')(colors)
// use css2jss and jss to attach header css template string to DOM
// write rest of custom module that uses the "header module"
// ... 

serapath commented Nov 30, 2015

If you compare it with javascript it basically means that instead of requireing or importing X, thus re-using X and "customize" it to your needs (=calling a function with arguments)....

While you write X (e.g. define a function in javascript), you already import or require all the arguments you might need...

While writing header.css, how can i possibly know all the scenarios in which i want to use it?
Maybe I could look about everything that is imported by the modules I will use and just overwrite color.css in my new project - but does that work if you have nested dependencies?

For me, when writing re-usable components, the approach css-modules take doesnt work for me and variables or the lack of passing in arguments when importing a css file is only one reason. Another one is dynamically adapting styling based on user interaction, so i switched to jss for now.
There it's easy to use variables, so I can write something like:

module.exports = function header (params) {
  return `
    .header {
      color: ${params.blue};
      background-color: ${params.red};
    }
  `
}

Then when re-using my component somehwere else :-)

var colors = { blue: '#0c77f8', red: '#ff0000', white: '#fff' }
var header = require('./header')(colors)
// use css2jss and jss to attach header css template string to DOM
// write rest of custom module that uses the "header module"
// ... 
@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Apr 30, 2016

I use stylus -> postcss-modules to get the superior syntax and power magic powers that stylus offers. One important issue to note, though, is how much extra fluff this generates. Anything that uses stylus's @import/@require automatically receives all the styles that are imported, as well as all the styles that are composed recursively, in both directions. This generates enormous "modules" for each component, particularly if a comopse references a @require or vice-versa: #145 .

ghost commented Apr 30, 2016

I use stylus -> postcss-modules to get the superior syntax and power magic powers that stylus offers. One important issue to note, though, is how much extra fluff this generates. Anything that uses stylus's @import/@require automatically receives all the styles that are imported, as well as all the styles that are composed recursively, in both directions. This generates enormous "modules" for each component, particularly if a comopse references a @require or vice-versa: #145 .

@kevinSuttle

This comment has been minimized.

Show comment
Hide comment
@kevinSuttle

kevinSuttle May 27, 2016

Here's something I ran into, using composes and @value from various files.

/* Themes/Kratos/Fonts.css */

.lightFontStack {
  font-family: "Helvetica Neue Light", HelveticaNeue-Light, "Helvetica Neue", Helvetica,
  -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",  sans-serif;
  font-weight: 200;
}
/* Themes/Kratos/index.css */
@value colors: "./Colors.css";
@value fonts: "./Fonts.css";
/* Inputs.css */
@value Kratos: "../Themes/Kratos/index.css";

@value Fonts: "./Themes/Kratos/Fonts.css"; /* 
❌  UNREACHABLE, incorrect relative path, produces NO ERROR */

@value Fonts: "../Themes/Kratos/Fonts.css"; 

.inputField {
  composes: lightFontStack from Kratos.fonts; ❌
  composes: lightFontStack from Fonts; ❌
  composes: lightFontStack from "../Themes/Kratos/Fonts.css";  ✅ 
CssSyntaxError: postcss-modules-scope: /css-loader!/[...]/Inputs/Input.css:8:3: referenced class name "lightFontStack" in composes not found

Another attempt:

@value Fonts: "../Themes/Kratos/Fonts.css"; 
@value lightFontStack from Fonts;

.inputField {
  composes: lightFontStack; ❌
Module not found: Error: Cannot resolve module '"../Themes/"../Themes/Kratos/index.css"/Fonts.css"

Yet a 3rd technique, attempting to use the old CSS @import declaration.

/* Themes/Kratos/Layout.css */
.defaultBorder {
  border-radius: 0;
  border: 2px solid;
  border-color: currentColor;
}
/* Input.css */

@import url("../Themes/Kratos/Fonts.css");
@import url("../Themes/Kratos/Layout.css");

.inputField {
  composes: defaultBorder;
  composes: lightFontStack;
  background-color: coreLightGrey; ❌ 
referenced class name "defaultBorder" in composes not found

Is this related to #123?

kevinSuttle commented May 27, 2016

Here's something I ran into, using composes and @value from various files.

/* Themes/Kratos/Fonts.css */

.lightFontStack {
  font-family: "Helvetica Neue Light", HelveticaNeue-Light, "Helvetica Neue", Helvetica,
  -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",  sans-serif;
  font-weight: 200;
}
/* Themes/Kratos/index.css */
@value colors: "./Colors.css";
@value fonts: "./Fonts.css";
/* Inputs.css */
@value Kratos: "../Themes/Kratos/index.css";

@value Fonts: "./Themes/Kratos/Fonts.css"; /* 
❌  UNREACHABLE, incorrect relative path, produces NO ERROR */

@value Fonts: "../Themes/Kratos/Fonts.css"; 

.inputField {
  composes: lightFontStack from Kratos.fonts; ❌
  composes: lightFontStack from Fonts; ❌
  composes: lightFontStack from "../Themes/Kratos/Fonts.css";  ✅ 
CssSyntaxError: postcss-modules-scope: /css-loader!/[...]/Inputs/Input.css:8:3: referenced class name "lightFontStack" in composes not found

Another attempt:

@value Fonts: "../Themes/Kratos/Fonts.css"; 
@value lightFontStack from Fonts;

.inputField {
  composes: lightFontStack; ❌
Module not found: Error: Cannot resolve module '"../Themes/"../Themes/Kratos/index.css"/Fonts.css"

Yet a 3rd technique, attempting to use the old CSS @import declaration.

/* Themes/Kratos/Layout.css */
.defaultBorder {
  border-radius: 0;
  border: 2px solid;
  border-color: currentColor;
}
/* Input.css */

@import url("../Themes/Kratos/Fonts.css");
@import url("../Themes/Kratos/Layout.css");

.inputField {
  composes: defaultBorder;
  composes: lightFontStack;
  background-color: coreLightGrey; ❌ 
referenced class name "defaultBorder" in composes not found

Is this related to #123?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment