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

SASS transformation #5

Closed
rauchg opened this issue Dec 5, 2016 · 24 comments
Closed

SASS transformation #5

rauchg opened this issue Dec 5, 2016 · 24 comments

Comments

@rauchg
Copy link
Member

rauchg commented Dec 5, 2016

Probably outside the scope of this module, but we could document how to make this work:

<script jsx type="text/sass">{`
  p {
    color: red;
    & a {
       color: #fff;
    }
  }
`}</script>
@rauchg
Copy link
Member Author

rauchg commented Dec 5, 2016

Note: whoever writes this transformation must be aware that we auto-prefix already. I know that many SASS compilers do that as well, so we'd have to avoid it

@thysultan
Copy link
Contributor

I'm looking into adding this to stylis, ping me if you have implementation ideas.

@robhrt7
Copy link

robhrt7 commented Dec 12, 2016

Having a documentation about how to add own css transformation rules would be really useful.

Note: whoever writes this transformation must be aware that we auto-prefix already.

Btw, this is also important part missing in docs. Autoprefixing should be at least configurable to define supported browsers.

@drcmda
Copy link

drcmda commented Dec 18, 2016

@rauchg @thysultan @operatino why not simply do it like csjs? They allow compile time babel transforms:

Links:
https://github.com/tizmagik/react-csjs
https://github.com/rtsao/babel-plugin-csjs-postcss

Real world example using CSSNext, Autoprefixer and a minifier/compressor:
https://www.reddit.com/r/reactjs/comments/5gjc08/styled_components_the_future_of_react_styling_in/dat7wr0/

That way any postCSS transform can run over the css, you'd open this up to an entire, existing eco system instead of porting a single thing. You could safely remove the autoprefixer as well as it's no longer needed. PostCSS prefixers are fully configurable so there goes another issue.

{
  "plugins": [["csjs-postcss", {
    "plugins": [["autoprefixer", {"browsers": ["last 2 versions"]}]]
  }]]
}

@thysultan
Copy link
Contributor

So i already got a working version of this for stylis that i'll push with the next release and it's only like ~40 lines so i'm pretty impressed with the results, the way it works is when it finds a block it skips it but adds it as a block to the end of the string buffer namespaced to it's parent, when the parser finally comes across it again the same thing will happen for any nested blocks within it, recursively until there are no more nested blocks.

so this...

h1, div {
        color: red;

	h2, &:before {
		color: red;
	}
        
       color: blue;

	header {
		font-size: 12px;
	}
}

becomes this...

h1, 
div { color: red; color: blue; }

h1 h2,
h1:before,
div h2,
div:before { color: red; }

h1 header,
div header{ font-size: 12px; }

@thysultan
Copy link
Contributor

^^ v0.8.0 now supports this.

@rstacruz
Copy link
Contributor

rstacruz commented Jan 3, 2017

What I'd rather see is postcss support.

More specifically, cssnext is a perfect fit for the styled-jsx paradigm, since it's basically like "babel for CSS." It takes proposed CSS additions and implements them. I'd love to see a more standard approach to CSS variables.

@sidorares
Copy link
Contributor

+1 to cssnext, we would avoid lot's of bugs ( like #68 ) with full-featured css transpiler. Dependency size is not an issue since it's compile time step

@rstacruz
Copy link
Contributor

rstacruz commented Jan 3, 2017

...also it's not mutually-exclusive to stylis! postcss is a css-to-css compiler, so styled-jsx can easily do postcss -> stylis. stylis can take care of the [data-jsx] scoping, postcss can take care of the rest.

Personally I'm looking forward to using postcss-import and postcss-cssnext.
<style jsx>{`
  @import './variables.css';

  .button {
    & .icon { background: var(--color-danger); }
  }
`}</style>

In fact, you can use this approach above to take the CSS out of your .jsx files, if mixing them together isn't for you :)
/* components/button/index.js */
<div>
  <a href='' class='button'>Click me</a>
  <style jsx>{`@import './style.css';`}</style>
</div>
/* components/button/style.css */
.button { background: var(--color-danger); }

@rstacruz
Copy link
Contributor

rstacruz commented Jan 3, 2017

Btw, I tried looking at getting postcss implemented in styled-jsx, but postcss's API is async while (afaik) Babel plugins are sync :\

@giuseppeg
Copy link
Collaborator

Dependency size is not an issue since it's compile time step

Good point. Unlike styled-components we don't compile at run-time so we could as well use PostCSS and take advantage of its ecosystem and the AST. cc @rauchg

More specifically, cssnext is a perfect fit for the styled-jsx paradigm, since it's basically like "babel for CSS." It takes proposed CSS additions and implements them. I'd love to see a more standard approach to CSS variables.

Using PostCSS sounds like a good idea but I wouldn't go as far as picking an opinionated preset of plugins (like cssnext) that sometimes can't fully polyfill css features (e.g. custom properties or color functions).

IMHO we would need a custom plugin to add scoping, autoprefixer and :global. Then we can make the preprocessor so that users can load custom plugins with postcss-load-plugins or like we do it in suitcss preprocessor.

Babel plugins are sync

correct

@rauchg
Copy link
Member Author

rauchg commented Jan 3, 2017

One of the reasons I don't like postcss is that it increases the compilation time and memory allocation very significantly :(

@rauchg
Copy link
Member Author

rauchg commented Jan 3, 2017

That said, I think there's a lot of merit to supporting features like darken(), & etc that come from the SASS / stylus / LESS crowd.

@import is actually a bit controversial for us. We had it in the original Next.js and it led to a lot of really questionable decisions, like using big stylesheets to style a bunch of elements at once instead of creating neatly separated components. We ended up with a bunch of big stylesheets all over the place, and we found that taking away the feature was a really good idea.

@giuseppeg
Copy link
Collaborator

giuseppeg commented Jan 5, 2017

@drcmda I wrote that plugin for styled-jsx! Actually I never read your post and while I was writing the babel plugin I found the csjs one 😅 (should have read the thread more carefully)

https://www.npmjs.com/package/styled-jsx-postcss

It works on styled-jsx transformed code so autoprefixing is still done by styled-jsx.

Hope you find it useful. cc @rstacruz @operatino @sidorares

@thysultan
Copy link
Contributor

I'd love to see a more standard approach to CSS variables.

@rstacruz Like scss? I'm adding this in the next version of stylis and other scss like features see the changelog, including the possibility for @imports via middleware, though i'm still not yet sure if middleware should be a single function that you can optionally compose from many functions as well or an array of middlewares that are composed internally.

@raavanan
Copy link

raavanan commented Jan 9, 2017

https://www.npmjs.com/package/styled-jsx-postcss

It works on styled-jsx transformed code so autoprefixing is still done by styled-jsx.

@giuseppeg , this is amazing. Exactly what i was looking for, but i am having difficulties with implementing it with nextjs. Fails at babel compilation with below error.

Any pointers or examples i can look at that implements into nextjs, since styled-components is used by default.

Property value expected type of number but got string at Object.validate (/Users/ganeshu/Code/mysite/node_modules/babel-types/lib/definitions/index.js:161:13)

Below is my .babelrc

{ "presets": [ "next/babel" ], "plugins": [ "styled-jsx-postcss/babel" ] }

@giuseppeg
Copy link
Collaborator

@raavanan can you open an issue on the styled-jsx-postcss repo? I need to update the dependency to ^0.4.0

@giuseppeg
Copy link
Collaborator

giuseppeg commented Jan 16, 2017

@rauchg people who want advanced features/preprocessing can now use styled-jsx-postcss. I could add a section to the README if you want. Can we close this issue or do you want to keep it open for reference?

@tim-phillips
Copy link

Just for reference, a styled-jsx-postcss example is at next.js/examples/with-styled-jsx-postcss

@ghost
Copy link

ghost commented Feb 3, 2017

That said, I think there's a lot of merit to supporting features like darken(), & etc that come from the SASS / stylus / LESS crowd.

I couldn't agree more, I think these are pretty mandatory actually, especially &

@giuseppeg
Copy link
Collaborator

Those can all be achieved with postcss plugins and https://www.npmjs.com/package/styled-jsx-postcss

@drcmda
Copy link

drcmda commented Feb 10, 2017

@giuseppeg this is awesome. Thanks a lot!

@Hum4n01d
Copy link

What about stylus?

/cc @giuseppeg

@Tomekmularczyk
Copy link

Tomekmularczyk commented May 22, 2017

I would really like to see example how to use scss syntax with styled-jsx-postcss. PostCSS with ton of plugins and modules makes me confused how to even integrate it with webpack and react. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests