thysultan / stylis Goto Github PK
View Code? Open in Web Editor NEWlight – weight css preprocessor
Home Page: https://stylis.js.org
License: MIT License
light – weight css preprocessor
Home Page: https://stylis.js.org
License: MIT License
I'm using stylis through styled-components and you already fixed an issue I had a few months ago (styled-components/styled-components#530) but I found another one when I wrote this
.item {
.wrapper button& {
/* styles */
}
}
It should out put .wrapper button.item {}
but it wasn't working for me. It works as expected on styled-components 1.X.
Would be great if we could get some syntax errors for invalid CSS. Is this possible with stylis?
Hello,
I'm using styled-components, which has a dependency on stylis. In their update 2.0.1 they upgraded stylis, and now my PrinceXML specific css stopped rendering correctly.
(PrinceXML generates PDF's from CSS/HTML/JS)
So previously I could do:
@page {
@top-left {
font-size: 11px;
content: "this is an example string shown in the header";
}
}
which is plain css, not pre-processed syntax or anything.
As of late, it completely ignores these selectors and prints out the cssRules outside of these selectors.
Any way to fix this?
On an iPhone 6 (running iOS 8), stylis is outputting:
align-self: center
It needs to be:
-webkit-align-self: center
Thanks!
When I run Lighthouse on my website it complains about old flex box spec being used. It doesn't like for example display: webkit-box
.
Is this something that could be configurable if you don't need to support really old browsers?
This is definitely a nice-to-have (not a big deal) but we could get rid of extra spaces and trailing ;
for smaller footprint.
At some point, I think stylis has stopped supporting universal selectors :(.
When I do this (on the playground):
.MyComponent > * {
color: blue;
}
it outputs:
.MyComponent > {
color: blue;
}
And well, in every position I try to use a universal selector. It's this intended?
I just updated styled-jsx
from 0.5.7
to 1.0.0
. Previously, this same rules were working and, with this update, all got broken >_<.
Just a heads up, the year should be 2017
, not 2016
for this year's entries 😉
https://github.com/thysultan/stylis.js/blob/master/CHANGELOG.md#3015-june-02-2016
Is there a way like in stylus to select a parent from it's children ? (see https://davidwalsh.name/stylus-parent-selectors)
I have tried to add & at the end but it didn't do anything.
I need a way to enable plugins to execute on empty blocks.
I see two use cases for this:
The issue:
.selector {}
This will not trigger my plugin.
I did fixed it in my project by modifying the source.
I added config called lossless
stylis.use({lossless: true})
and changed this code block
// execute plugins, block context
if ((lossless && current[0] !== '') || (length > 0 && plugged > 0)) {
result = proxy(BLCKS, out, current, parent, line, column, length, id)
if (result !== void 0) {
length = (out = result).length
}
}
I can submit a pull request but I wanted to create an issue first.
10x in advance.
Reproduction: http://www.webpackbin.com/EkLgWziwG
Related to: styled-components/styled-components#446
This is really weirding me out to debug, but I think this is an issue that has arisen in a recent version of Stylis.
With this input:
html {
font-family: 'Proxima Nova', 'Helvetica Neue', sans-serif;
}
Strange invisible characters get inserted just after the commas, that invalidates the whole rule in browsers. All my fonts are Times New Roman now :'(
Using attribute selectors without a value [data-attribute]
causes an error in stylis:
stylis.js:89 Uncaught TypeError: Cannot read property 'charCodeAt' of undefined
// [ attr selector
case 91: {
// `[data-id=namespace]` -> ['data-id', 'namespace']
attr = selector.substring(1, selector.length - 1).split('=');
char = (namespace = attr[1]).charCodeAt(0); // Error occurs here
sample code:
const style = document.createElement('style');
style.textContent = stylis('[data-attribute]', 'color: red');
document.head.appendChild(style);
This happens with using [email protected]
.
This can be resolved when using [data-attribute="anything here"]
however that enforces the element to have that value for the attribute, instead of matching every data-attribute
instance no matter the value.
Might be possible to add a check to make sure there is an =
, and if there is then split on it, else grab the value between index 1
and index: length - 1
which would correspond to the [
and ]
wrapping the data-attribute without a namespace.
When possible calc can be precomputed:
calc(10px * 2)
=> 20px
calc(100% / 3)
=> 33.3333%
This is done in many transpilers like stylus, less, postcss etc.
Not possible when dealing with relative values like:
calc(100vh - 5px)
calc(50% - 20px)
When using data uri's embedded in the css, it breaks stylis parsing.
Reproduction: http://jsbin.com/vetude/edit?js,output
I believe this causes styled-components/styled-components#433
::placeholder
is not vendor prefixed: caniuse.
Is there a cli I can use to compile my styled-components css?
Something like this:
npm install stylis -g
stylis -w style.stylis -o style.css
Input:
/* @scope .foo */
input:read-only {
color: red;
}
Expected result:
.foo input:-moz-read-only {
color: red;
}
.foo input:read-only {
color: red;
}
Actual result:
.foo input:read-only {
color: red;
}
/* @scope */
.foo{ font-family: "Goudy Bookletter 1911"}
it removes the font-family declaration entirely.
This is correct:
stylis(`.abc`, `&.foo {color: yesplease}`)
".abc.foo {color: yesplease}"
This is not:
stylis(`.abc`, `&.foo { &.bar {color: yesplease}}`)
".abc .foo.bar {color: yesplease}"
(should be .abc.foo.bar
without space)
This is also not:
stylis(`.abc`, `&.foo { &.bar { &.barbar {color: yesplease}}}`)
".abc .foo.bar .barbar {color: yesplease}"
(should be .abc.foo.bar.barbar
)
as you can see, the second line for the grid-template-areas
is not being passed to the browser.
Is there a way to fix this?
edit
Making it inline seems to work but it should work both ways
.mainContainer {
width: 80vw;
margin: auto;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: auto;
grid-template-areas:
"header header header" ". main .";
}
v1.2.0 landed with what was needed to successfully created a linter, WIP at plugins/linter The bulk of the effort will be in scrapping css syntax data and converting that to regex's or create them by hand to validate known css properties.
given this css:
.foo { color: white; }[role=button]{cursor:pointer}
stylis will stop parsing at [role=button]
and will return only .foo { color: white; }
Different browsers require different sets of prefixes - see http://caniuse.com/. There does not currently seem to be any support for configuring which browsers should be supported with prefixing. Is it intended to be a manual setting - flagging every single prefix you need on your own - or to match e.g. postCSS functionality where you can set which browsers to support?
transition: xy;
/* should become */
transition: xy;
-webkit-transition: xy;
According to CanIUse, by not prefixing we lose about 10% usage support due to UC Browser for Android.
I'm using column-count
css property in my css but the property doesn't get prefixed. I'm not quite sure what properties the library should prefix and what not to. Are you using browserslist or some predefined list of properties to prefix?
I have no idea what escade
is, but it's breaking my react
application that uses styled-components@master
(and has stylis
as a dependency):
It was introduced on this commit: 7c7ebe4
Could you prevent this by first checking if this variable exists or any other way?
Thanks.
Was working on some styled-components stuff, and I think I've found a bug.
Here's the code I'm running (just to get a sense of how the plugins work atm) using v3.2.8
:
import Stylis from 'stylis'
const stylis = new Stylis({
global: false,
cascade: true,
keyframe: false,
prefix: true,
compress: false,
semicolon: true,
})
const plugin_calls = []
stylis.use((context, content, selectors, parent, line, column, length) => {
plugin_calls.push({ context, content, selectors, parent, line, column, length })
})
stylis('.foo', `
bar: baz;
@media screen and (min-width: 600px) {
yeah: nah;
@supports (lol) {
too: right;
}
}
`)
console.log(JSON.stringify(plugin_calls, null, 2))
[
{
"context": -1,
"content": "\n bar: baz;\n @media screen and (min-width: 600px) { \n yeah: nah;\n @supports (lol) {\n too: right;\n }\n }\n",
"selectors": [
".foo"
],
"parent": [
".foo"
],
"line": 1,
"column": 1,
"length": 0
},
{
"context": 1,
"content": "bar:baz",
"selectors": [
".foo"
],
"parent": [],
"line": 2,
"column": 11,
"length": 0
},
{
"context": 1,
"content": "yeah:nah",
"selectors": [
".foo"
],
"parent": [
".foo"
],
"line": 4,
"column": 14,
"length": 0
},
{
"context": 1,
"content": "too:right",
"selectors": [
".foo"
],
"parent": [
".foo"
],
"line": 6,
"column": 17,
"length": 0
},
{
"context": 2,
"content": "too:right;",
"selectors": [
".foo"
],
"parent": [
".foo"
],
"line": 7,
"column": 5,
"length": 10
},
{
"context": 3,
"content": ".foo{too:right;}",
"selectors": [
"@supports (lol)"
],
"parent": [
".foo"
],
"line": 7,
"column": 5,
"length": 16
},
{
"context": 2,
"content": "yeah:nah;",
"selectors": [
".foo"
],
"parent": [
".foo"
],
"line": 8,
"column": 3,
"length": 9
},
{
"context": 3,
"content": ".foo{yeah:nah;}@supports (lol){.foo{too:right;}}",
"selectors": [
"@media screen and (min-width:600px)"
],
"parent": [
".foo"
],
"line": 8,
"column": 3,
"length": 48
},
{
"context": 2,
"content": "bar:baz;",
"selectors": [
".foo"
],
"parent": [],
"line": 9,
"column": 1,
"length": 8
},
{
"context": -2,
"content": ".foo{bar:baz;}@media screen and (min-width:600px){.foo{yeah:nah;}@supports (lol){.foo{too:right;}}}",
"selectors": [
".foo"
],
"parent": [
".foo"
],
"line": 9,
"column": 1,
"length": 99
}
]
To my mind, the first "context": 3,
callback (for "content": ".foo{too:right;}",
) should have a parent of [".foo", "@media screen and (min-width:600px)"]
, not just .foo
. I'm guessing somewhere there's an expectation that at-rules can only be one level deep, which isn't the case (@media
and @supports
work just fine nested, at least).
I'm trying to build a simple plugin that can do the sort of thing described here: threepointone/glam#5 to make stylis' output insertRule
-able.
Would there be a better way to approach this?
I'm working on a big app with lots of CSS, and tried to use styled-components
v2 but everything broke. After some debugging I realised that almost all of the breakage was because we're not very... consistent with semicolons, and stylis
treats semicolon-less lines differently from PostCSS.
Is there any chance we could align that behaviour? Otherwise few people can upgrade to v2 as it'll break their entire app with basically no automated way of fixing it. 😕
This:
html {
text-size-adjust: none;
}
should be vendor prefixed to:
html {
-webkit-text-size-adjust: none;
text-size-adjust: none;
}
Original issue: styled-components/styled-components#950
It would be nice to be able to disable minification completely. This is useful for development mostly. Would it be hard to do so?
The spec is ancient and the prefixes are hurting performance for any browser that is ie11 and above.
New syntax support is: Chrome 21+, Safari 6.1+, Firefox 22+, Opera (& Opera Mobile) 12.1+, IE 11+, and Blackberry 10+.
(https://css-tricks.com/old-flexbox-and-new-flexbox/)
Summary: Old is 2.3x slower than new.
https://developers.google.com/web/updates/2013/10/Flexbox-layout-isn-t-slow
https://developers.google.com/web/tools/lighthouse/audits/old-flexbox
Regardless of how modern browsers are using the older properties, we are sending down unnecessary properties when using SSR.
I think we should remove this for the benefit of all end users. I'm willing to help with the removal if you are open to the idea of removing the old spec.
injectGlobal`
@page {
size: A4 landscape;
}
@page :left {
margin-left: 3cm;
}
@media (max-width: 700px) {
html {
background: palevioletred;
}
}
`
style tag in server side rendered head with
@page{size: A4 landscape;}
@page :left{margin-left: 3cm;}
@media (max-width: 700px){html{background: palevioletred;}}
style tag in server side rendered head with
@page{{size: A4 landscape;}}
@page :left{{margin-left: 3cm;}}
@media (max-width: 700px){html{background: palevioletred;}}
Copied from styled-components/styled-components#957
This:
div {
mask-image: linear-gradient(transparent, black);
}
Should vendor prefix to this:
div {
-webkit-mask-image: -webkit-linear-gradient(transparent, black);
mask-image: linear-gradient(transparent, black);
}
@supports
does not seem to work correctly. Reproduction
// Input:
@supports (display: block) {
background: mediumseagreen;
}
// Output:
@supports (display: block) {background-color: mediumseagreen;}
StackOverflow question that prompted this: https://stackoverflow.com/questions/43562789/using-supports-with-styled-components/43571955#43571955
Input:
/* @scope .foo */
input {
@supports (appearance: none) {
appearance: none;
}
}
Expected result:
@supports ((-webkit-appearance: none) or (-moz-appearance: none) or (appearance: none)) {
.foo input {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
}
Actual result:
@supports (appearance: none) {
.foo input {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
}
The text-transform
is prefixed by stylis.js because the regexp is checking on the transform
keyword.
See styled-components/styled-components#1110
It would be great if stylis removed all these empty examples:
.emptyAttr { color: ; } // should be removed
.spuriousSemi { color: black; ; ; ; ; } // should only keep color: black
.emptySelector { } // should be removed
I saw that you started ast and objectify plugins. cool!
I took the idea and started my own.
here is the gist for it I want to get you feedback.
For example,
.foo{padding:30px 0}
will produce output of
.foo{padding:30px0}
Same result with margin
I found this bug via using styled-jsx
and pinpointed the error.
I tried running this test:
'nth-child with cascade false': {
options: {
cascade: false
},
sample: `b > a:nth-child(2n) { color: blue }`,
expected: `b.user>a:nth-child(2n){color: blue;}`
}
It fails ❌ and the result is this:
46 'failed: ' 'test' '\n\n' 'b.user>a.user:nth-child(2n.user){color: blue;}'
36 'expected: ' '\n\n' 'b.user>a:nth-child(2n){color: blue;}' '\n\n---------------\n\n'
Somehow the 2n
value got namespaced and became 2n.user
😢
I'm trying to use stylis with this input but it's not working with stylis 2.x 😕
stylis(`.${hash}`, style)
@media (max-width: 600px) {
& { color: red }
}
&:hover {
color: orange
}
@media (max-width: 600px) {.OTIfQo {color: red}}.OTIfQo:hover {color: orange}
.OTIfQo:hover {@media (max-width: 600px) {.OTIfQo {color: red}}color: orange}
This is an idea i've been thinking about... since stylis can identify css variables / a css-variables-like syntax for free it could potentially also mark them for faster re compiling of just the dynamic parts that a CSS in JS library can use to plugin into. For example: with s-c.
const Button = styled.button`
color:red;
width: ${value};
`
The s-c library could then pass this to stylis as
// first tell stylis to enable this option
stylis.set({dynamic: true})
// then pass as a string once
stylis('#id', `
color:red;
// prefixed the dynamic value with a hash
width: --hash1203 30px;
`)
stylis would compile this to the following but also record that --hash1203 is a dynamic value that i can quickly recompile later when requested.
#id {
color:red;
width: 30px;
}
s-c could then call stylis to re-compile only the dynamic parts if it has any in cache into a function when needed.
stylis.pipe(hash, fn)
The fn function
would receive only the parts that have changed
const fn = (selector, property, value, index) => {
style.insertRule(`${selector} { ${property}: ${value} }`, index)
}
This is an idea that could go into V3 of the stylis rewrite i'm working on while still maintaining the small 3kb bundle size.
cc @geelen, @philpl, @mxstbr, @giuseppeg in case this is something they might see using.
Please add prefixes for flexbox in IE10. Such as here.
I'm using stylis via styled-components and I noticed a bug in iOS 8 and older.
When using a style like this transition: transform 600ms ease;
, iOS Safari 8 and older requires both properties to be -webkit-
prefixed.
Current stylis output:
-webkit-transition: transform 600ms ease;
transition: transform 600ms ease;
Needs to also include a double prefixed rule like this:
-webkit-transition: transform 600ms ease;
-webkit-transition: -webkit-transform 600ms ease;
transition: transform 600ms ease;
More info on this behavior: http://stackoverflow.com/questions/20669190/browser-specific-prefixes-with-a-css-transition-on-transform
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.