postcss / postcss-simple-vars

PostCSS plugin for Sass-like variables
MIT License
419 stars 35 forks source link

!global and !default support? #54

Closed ryoikarashi closed 8 years ago

ryoikarashi commented 8 years ago

Does this plugin support !global and !default as SASS does support or any postCSS plugins that support these?

What I'm trying to do is to override variables, which is very useful for theming.

.foo {
   $foo: 'bar' !global; 
}

$foo: 'foo' !default;

// $foo => 'bar'
ai commented 8 years ago

Nope https://github.com/postcss/postcss-simple-vars/issues/52

ai commented 8 years ago

Can you show me your real case. You need !default only because you are thinking in Sass-way. In PostCSS you have much more power, so you could find much better code design.

ryoikarashi commented 8 years ago

@ai If I could make variables defined in local scope global, I could override them and switch themes only by changing class names. Here is the real case belowl. Are there any better code design for theming?

index.html

<html>
<head>
<link href="/assets/main.css" rel="stylesheet">
</head>
<body class="theme-A">
...
</body>
</html>

main.css

@import 'themes.css';
@import 'variables.css';
@import 'base.css';

themes.css

.theme-A {
   $bg-color: red !global;
   $text-color: blue !global;
}
.theme-B {
   $bg-color: green !global;
   $text-color: yellow !global;
}

variables.css

$bg-color: white !default;
$text-color: black !default;

base.css

body {
   background: $bg-color;
}
p {
   color: $text-color;
}
ai commented 8 years ago

This code will not work in Sass.

The best way is to use CSS Custom Variables, they support it native in browser. But not all browsers support CSS Custom Variables. In PostCSS we have polyfill, but it works only for :root definitions, so it is useless here.

ai commented 8 years ago

But I have awesome idea. Let’s write a polyfill for dynamic CSS Custom Properties!

You pass this <body> switching classes to plugin:

require('postcss-dynamic-custom-props')({ rootClasses: ['theme-A', 'theme-B'] })

Then plugin will find all overrides definitions like and remember a variable names:

.theme-A {
   --bg-color: red;
   --text-color: blue;
}

Then it will find all rules, where this variables used, like:

p {
   color: var(--text-color);
}

On final step it merge themes classes and overrides and generate this:

.themeA p {
   color: blue;
}

Sorry, maybe my description is little confused. Please ask me any question about it.

What do you think about this idea? Do you have time for it? (I will help you step-by-step)

ryoikarashi commented 8 years ago

@ai Your idea looks great but the npm module you provided, postcss-dynamic-custom-props is not found in npm registries. Is it already deprecated?

ai commented 8 years ago

πŸ˜† it is only idea. We need to write it πŸ˜‰.

Do you want to do it?

ryoikarashi commented 8 years ago

Oh I got it. πŸ˜† I'm trying to do it πŸ‘

ai commented 8 years ago

@RyoIkarashi here is a issue for this idea: https://github.com/postcss/postcss-plugin-suggestion-box/issues/6

Here is our chat for quick help: https://gitter.im/postcss/postcss

Here is links how start develop a plugin: https://github.com/postcss/postcss/blob/master/docs/writing-a-plugin.md

ryoikarashi commented 8 years ago

@ai Thanks! ;)

sekoyo commented 8 years ago

My use-case would be consuming node_modules which use postcss, and being able to override variables defined there before compilation time, thus being able to theme them. For example:

$ns_bg_color: 'red';

body {
  background-color: $ns_bg_color;
}
@import "./test.css";

$ns_bg_color: 'blue';

Background should be blue.

ai commented 8 years ago

@DominicTobias use mixin for it ;)

This variables logic is non-intuitive, there is no languages with such logic

sekoyo commented 8 years ago

@ai thanks, do you mind giving a basic example of what you mean pls?

ai commented 8 years ago

@DominicTobias

@mixin myTheme(blue);
sekoyo commented 8 years ago

Hm not sure how that would be implemented in a real world scenario - for example

node_modules/slider/slider.js <-- imports ./slider.css which has $slider-color: 'black'

app: index.js <--- imports './bla.css' import 'slider'; <-- some module in app imports this which imports slider.css

How would you go about changing the colour of the slider in that scenario using mixins? (Without literally overriding the output css of the slider module)?

ai commented 8 years ago

@DominicTobias are you a developer pf that node_modules/slider?

sekoyo commented 8 years ago

Yep I am so can modify it however - this is for an sdk of components and consuming apps (we control both)

On Monday, 22 August 2016, Andrey Sitnik notifications@github.com wrote:

@DominicTobias https://github.com/DominicTobias are you a developer pf that node_modules/slider?

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/postcss/postcss-simple-vars/issues/54#issuecomment-241469356, or mute the thread https://github.com/notifications/unsubscribe-auth/AAuZ-hgWkMcr3jSqlpmmn4Ebuz5M7UgMks5qic4jgaJpZM4JIzlz .

ai commented 8 years ago

@DominicTobias so, just define a mixin in that node_modules/slider/slider.css ;)