khan / aphrodite Goto Github PK
View Code? Open in Web Editor NEWFramework-agnostic CSS-in-JS with support for server-side rendering, browser prefixing, and minimum CSS generation
Framework-agnostic CSS-in-JS with support for server-side rendering, browser prefixing, and minimum CSS generation
Hello.
Sorry for the newbie question, but what's the best practice?
While I was reading the README, I was thinking that nothing about this library has any dependence/lock-in with React. Although it pairs wonderfully, the beginning of the README says:
Support for colocating your styles with your React component.
Which implies it only works with React. I found this isn't the case, with my demo using Custom Elements and template strings here:
https://gist.github.com/tbranyen/4336b59e11812fb679d3
Would it make sense to follow the Redux approach ("Redux is a predictable state container for JavaScript apps."), and not focus on React?
It would be nice if people were able to write:
const color = 'blue';
const styles = new StyleSheet({
myStyle: {
padding: [5, 10, 15, 20],
border: [2, 'solid', color],
}
});
Any advice on how to get marginBottom: 50
as in this snippet with .listItem + .listItem
?
listItem: {
'@media (min-width: 600px)': {
width: `${HUNDRED_PERCENT / itemsCount}%`,
marginBottom: 0,
display: 'inline-block'
},
display: 'block',
width: '100%',
textAlign: 'center',
'listItem + listItem': { // NOTE: How do I do this one here?
marginBottom: 50
}
}
})
EDIT: Clarified some stuff. Note that some CSS props might be removable. I'm a bit CSS-rusty these days.
We currently generate monotonically increasing IDs to differentiate multiple styles with the same name, which isn't going to work for server-side rehydration.
One idea is to take the CRC32 of the JSON.stringify
of the style definition, then append that to the style name (or possibly even use that as the entire style name -- something like s${base58(crc(JSON.stringify(styleDefinition)))
Base 58: https://en.wikipedia.org/wiki/Base58
Small JS CRC implementation: http://stackoverflow.com/a/18639999
When trying to install aphrodite via JSPM it crashes not so nicely. It is possible to install package via github, however.
$ jspm install npm:aphrodite
Updating registry cache...
Downloading npm:[email protected]
warn Error on lookup for github:github:khan/inline-style-prefixer, retrying (1).
Error: fatal: unable to access 'github:khan/inline-style-prefixer.git/': The
requested URL returned error: 400
warn Error on lookup for github:github:khan/inline-style-prefixer, retrying (2).
Error: fatal: unable to access 'github:khan/inline-style-prefixer.git/': The
requested URL returned error: 400
warn Error on lookup for github:github:khan/inline-style-prefixer, retrying (3).
Error: fatal: unable to access 'github:khan/inline-style-prefixer.git/': The
requested URL returned error: 400
err Error on lookup for github:github:khan/inline-style-prefixer
Error: fatal: unable to access 'github:khan/inline-style-prefixer.git/': The requested URL returned error: 400
err Error looking up github:github:khan/inline-style-prefixer.
warn Installation changes not saved.
Hi Team Aphrodite,
Thanks a lot for super nice work !
I have a query for you guys, Aphrodite will no doubt help to reduce bytes transferred for server side rendering, but can it effect page performance due to adding css styles while page is at client side ?
Thanks,
Jyoti
The use case for this is React Router's behaviour, where it appends the class active
to the applicable element:
<a class="aphroditeClassName_xyz123 active">Text</a>
Possible targeting syntax:
aphroditeClassName: {
color: 'black',
'&.active': {
color: 'red'
}
}
I'm using react-dom-stream for my server rendering.
I'm wondering if aphrodite is working or could work with streams ?
This may be a bug in the autoprefixer, but I'm having trouble getting CSS transitions to work with Aphrodite on mobile web (specifically, Safari on iOS 9.3.1).
Notice that the unprefixed and vendor-prefixed transition
properties are all cancelled out. (What's strange to me is that it's not rendering with any sort of warning or error; the UI seems to suggest that it's being overidden elsewhere, even though the computed styles reveal no transition
.)
Removing both -moz-transform
and -ms-transform
from either the -webkit-transition
or transition
values enables them properly. I suspect that it's considering transform values with properties using unsupported prefixes to be invalid, though I'm not familiar enough with vendor-prefixing to know if this is a common practice.
P.S.: My desktop Safari (9.1), on the other hand, seems fine with the prefixing:
Hi!
As far as I understand, you're aiming at only having nested media-queries and pseudo selectors, not tags or global class names. How would you go about styling basic HTML elements like body
, input
, h1
, h2
, p
, strong
etc. by their tagname? For instance, the body in the example have the default 8px
margin – a sitewide reset would be in order.
I can think of a few ways to achieve this, good or (mostly) bad:
className
everywhere they're used: <h1 className={styles.h1}>hi</h1>
(whoa!).:global h1
, *h1
, h1
(a space) or something else, as the first char(s) in the selector when looping through the object keys, and treat that more or less like the pseudo selector.This is somehow related to #10 , though I see this as the key issue, and a solution would address that as well. I think @jlfwong described the trade-of quite well:
That definitely was not an intention of the API design, but perhaps is something we should support for the sake of API simplicity.
I hope we find a solution for this. I definitely think this is the most promising way of stylehandling!
Don't know if I'm doing something wrong or ...
I have a style with "display: flex" and Aphrodite output look like this:
display: -webkit-box,-moz-box,-ms-flexbox,-webkit-flex,flex !important
which is not working in chrome and marked as invalid property value!
Should there be code-coverage for aphrodite/src/**/*
?
I'd like to include warning messages for improper usage of aphrodite, but don't want it to bloat production build sizes.
This would be useful for e.g. discouraging the following hack once we have a proper solution (described in #10)
const styles = StyleSheet.create({
parent: {
':hover .child': {
backgroundColor: blue
}
}
});
I see that "Consider removing !important from everything." is listed under TODO in the README.
Perhaps this could be discussed here?
Hi! The following:
.test {
background: 'url(data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7) no-repeat left center';
}
will result in an important statement before base64
like so:
background: url(data:image/gif !important;base64,R0IG
In my use case, I'm requiring the images using webpack. The webpack config decides weather or not to encode this file into a data-uri or serving it as a static file based on the file size.
I hope this makes sense :)
I was thinking more about the whole !important
debate, and why it's there in the first place. Wouldn't another way to raise the presence of Aphrodite styles be to simply prefix styles with an ID?
It could easily go on the body
or a wrapping element around a component, and I suspect it would magically make the precedence problems go away in a way that has none of the downsides of !important
It is also friendlier to component authors (I'm thinking about react-select here), where users providing inline styles is a really important feature, pun not intended.
The old problem:
Legacy stylesheet
.foo div {
color: red;
}
New component
const Component = () => <div className='foo'>
<div className={css(styles.bar)}>
Hello
</div>
</div>
const styles = StyleSheet.create({
bar: {
color: 'green'
}
});
The browser sees:
.foo div {
color: red;
}
.foo {
color: green;
}
... and the text goes red. Bad.
But with an ID, render your React app inside a <body id="my-id">
tag then prefix all the classes with #my-id
:
const styles = StyleSheet.create('#my-id', {
bar: {
color: 'green'
}
});
The browser sees:
.foo div {
color: red;
}
#my-id .foo {
color: green;
}
... and hey presto, the text is green like it should be.
For something like React Select I can ship that library with stylesheets that prefix the ReactSelect
ID, and just wrap the component in a <div id="ReactSelect">
container, and it's highly unlikely any user styles will interfere with the stylesheet in the component.
Technically I'm not complying with the HTML spec if I have more than one ReactSelect
ID in my page, so that's kind of ugly. But it will work, and I think it's a trade-off worth discussing.
npm run examples
> babel-node server.js
module.js:341
throw err;
^
Error: Cannot find module 'asap'
at Function.Module._resolveFilename (module.js:339:15)
at Function.Module._load (module.js:290:25)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at Object.<anonymous> (/home/ricardo/Documents/Projects/aphrodite/src/inject.js:9:13)
at Module._compile (module.js:413:34)
at normalLoader (/home/ricardo/Documents/Projects/aphrodite/examples/node_modules/babel-core/lib/api/register/node.js:199:5)
at Object.require.extensions.(anonymous function) [as .js] (/home/ricardo/Documents/Projects/aphrodite/examples/node_modules/babel-core/lib/api/register/node.js:216:7)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
When I have a component which wraps a component with the intention of putting some default styles on it, e.g.
class FooterLink extends React.Component {
render() {
let {className, ...props} = this.props;
className = [className, css(styles.footerLink)].join(' '); // how to merge?
return <a className={className} {...props} />;
}
it's not obvious how to merge the class names. If you simply use both of the generated class names (as in the code above), there is no way to enforce precedence (later injected style wins, presumably). Of course you could allow an array of style objects to be passed in and then css
them all together, but this changes the API so the component isn't really a pure wrapper anymore.
Any thoughts on this?
I wonder if you guys did any performance comparison of this 2 different approaches:
The one of aphrodite (as far as I understand):
css()
functioncss()
calls are buffered and rendered by asap
flushvs.
The one of jss or better to say react-jss:
Some styles need to be created at runtime because then depend on variables. Currently I'm doing the following which is not very pretty.
const domainStyle = StyleSheet.create({
domain: {
color: webPhoneExercisesEnabled
? globalStyles.colors[domain].domain1
: globalStyles.colors[domain].domain3,
},
}).domain;
Hi!
There's currently no support for attribute selectors. I could make a small PR with support and tests for this, if you're interested, unless it's left out by design?
I'm running an App that uses Aphrodite and Jest. After the test succeed, I get this error, related to Aphrodite:
/home/ricardo/Documents/Projects/reaxor/node_modules/aphrodite/lib/inject.js:29
styleTag = document.querySelector("style[data-aphrodite]");
^
TypeError: Cannot read property 'querySelector' of undefined
at injectStyleTag (/home/ricardo/Documents/Projects/reaxor/node_modules/aphrodite/lib/inject.js:29:28)
at flushToStyleTag (/home/ricardo/Documents/Projects/reaxor/node_modules/aphrodite/lib/inject.js:132:9)
at RawTask.call (/home/ricardo/Documents/Projects/reaxor/node_modules/asap/asap.js:40:19)
at flush (/home/ricardo/Documents/Projects/reaxor/node_modules/asap/raw.js:50:29)
at /home/ricardo/Documents/Projects/reaxor/node_modules/jest-util/lib/FakeTimers.js:351:18
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
npm ERR! Test failed. See above for more details.
Is there a way to support pseudo state with nested children?
eg.:
button: {
color: 'white',
':hover': {
color: 'red'
icon: {
color: 'inherit'
}
}
},
icon: {
color: 'blue'
}
In this case, I need to change my icon color to inherit
only when button is hovered
I'm trying to convert a project with css written with react-look to aphrodite and I'm in a little pickle when it comes to fallback values.
In CSS you write fallback values as:
.class {
color: #435;
color: hsl(40, 50%, 50%);
}
And since we can't have dublicate keys in javascript objects, react-look solves this with arrays:
{
class: {
color: ['#435', 'hsl(40, 50%, 50%)']
}
}
In my project I'm using a lot of height: '100vh'
with px height fallbacks. I've gone through the docs and issues on github but can't find the recommended way to solve fallback values with aphrodite.
Any suggestions?
I'm trying to figure out how to include 2 font styles for a given font family.
I tried the following, but the italicFont
_@_font-face isn't being added to the stylesheet.
const font = {
fontStyle: "normal",
fontWeight: "normal",
fontFamily: "My Font",
src: `url(${myFontWoff}) format("woff"),
url(${myFontTtf}) format("truetype")`
};
const italicFont = {
fontStyle: "italic",
fontWeight: "normal",
fontFamily: "My Font",
src: `url(${myItalicFontWoff}) format("woff"),
url(${myItalicFontTtf}) format("truetype")`
};
fontFamily: [font, italicFont, "serif"]
Am I missing something or does this not yet work in Aphrodite?
I'm trying to use aphrodite in my project. Everything works great so far except one scenario. I have a Tooltip component that measures children dimensions in componentDidMount
and componentDidUpdate
. But actual css gets injected after these functions were called. What's worse is that sometimes styles might be already injected, so dom element have unpredictable styling in above functions.
I created an issue on react to discuss how react might help with this problem: facebook/react#6816
Inspired by @rofrischmann's fela. It appears to be a pretty slick API. Something like:
StyleSheet.create(props => ({
bar: {
fontSize: props.big ? '25px' : '15px',
// etc.
}
}))
Hey guys, this is not a specific issue related to Aphrodite, more a general question. I started integrating Aphrodite into a React project and everything works well so far. However, one requirement is to use a css framework (skeleton) for the site I am working on. That's for having a base grid and base style. I'm loading the min version of the framework in the via a traditional and everything works fine.
Question: is this against the inline css methodology? Could I not have a base stylesheet for a global scope and then maintain local css via components? How would you handle grid styles via components otherwise? Does this information not have to be in the global scope? Is this bad practice? Same with using react plugins (e.g. slider), those come with css which will be in the global scope.
Any thoughts?
Cheers
<div className={css(styles.div)}></div>
style.div = {
':before': {
content: "test",
}
};
generates
.div_1pd8e9z:before{content:test !important;}
which just leaves the div empty (notice the missing "" around the content string).
A convoluted workaround exists though:
style.div = {
':before': {
content: `"test"`,
}
};
which generates the following CSS:
.div_10tj0xl:before{content:"test" !important;}
I just upgraded to [email protected] and stuff broke. I'll look into it further, but I thought that it'd be really nice to have a changelog.
I personally recommend automating this though the use of semantic-release.
Sample output:
.wrapper_5h5b2v {
flex: 1 1 -moz-calc(100% - 300px);
flex: 1 1 -webkit-calc(100% - 300px);
flex: 1 1 calc(100% - 300px);
-webkit-flex: 1 1 calc(100% - 300px);
-ms-flex: 1 1 calc(100% - 300px);
}
As you can see in the the image below from Chrome dev tools this is causing non-prefixed rules to be overwritten in the browser by prefixed ones
Hi there, I was testing a simple stateless functional component while encountered this. Here's my component and the test code:
import React from 'react';
import { StyleSheet, css } from 'aphrodite';
const Dummy = ({
name,
}) => {
return <div className={css(styles.preview)}>
<h4>Boo!</h4>
</div>
}
const styles = StyleSheet.create({
preview: {
fontFamily: 'Times New Roman',
},
})
export default Dummy
And the test:
describe('Components', () => {
describe('HTMLPreview', () => {
it.only('Work', () => {
const props = {
name: 'hi'
}
const renderer = TestUtils.createRenderer();
renderer.render(<Dummy {...props} />);
const output = renderer.getRenderOutput();
return {
output,
renderer
}
});
});
});
And finally the error:
Components
HTMLPreview
1) Work
0 passing (154ms)
1 failing
1) Components HTMLPreview Work:
Error: Cannot automatically buffer without a document
at injectStyleOnce (node_modules/aphrodite/lib/inject.js:90:23)
at css (node_modules/aphrodite/lib/index.js:73:33)
at new Dummy (Dummy.jsx:7:26)
at [object Object].ReactCompositeComponentMixin.mountComponent (node_modules/react/lib/ReactCompositeComponent.js:148:18)
at [object Object].wrapper [as mountComponent] (node_modules/react/lib/ReactPerf.js:66:21)
at [object Object].ReactShallowRenderer._render (node_modules/react/lib/ReactTestUtils.js:366:14)
at _batchedRender (node_modules/react/lib/ReactTestUtils.js:348:12)
at ReactDefaultBatchingStrategyTransaction.Mixin.perform (node_modules/react/lib/Transaction.js:136:20)
at Object.ReactDefaultBatchingStrategy.batchedUpdates (node_modules/react/lib/ReactDefaultBatchingStrategy.js:62:19)
at Object.batchedUpdates (node_modules/react/lib/ReactUpdates.js:94:20)
at [object Object].ReactShallowRenderer.render (node_modules/react/lib/ReactTestUtils.js:343:16)
at Context.<anonymous> (html_preview_component_spec.js:62:16)
Any one can shed some light on this?
Thank you!
Applying styles to ':before' pseudo-element doesn't get any results.
'icon': { ':before': { content: '\\2300', }, },
Have I missed something? Or does aphrodite support ':before' pseudo-element?
If I want to apply styles to a child based on its parent's :hover
state, I think I have to track hover state in js. Is that accurate? Do you think handling this is in the scope of aphrodite?
Specifically I am thinking of something that emulates the CSS:
.parent:hover .child {
background-color: blue;
}
I'd like to be able to use some variable (let's say 'ok') to decide on the styling of an element:
<div className={ok ? css(styles.activeButton, styles.okButton) : css(styles.okButton)}>OK</div>
Is there any better way to do it? (e.g. a way to pass along pairs of class names and booleans to css method?)
I'm having some trouble understanding what is causing this issue. I'm using aphrodite as the css inlining library in combination with universal-redux. Since adding aphrodite, everything is working fine in NODE_ENV=development, but started failing when running pre packed webpack builds in production.
I'm not able to decipher the meaning of the below message without some better understanding of the aphrodite internals. Perhaps someone could help me with a brief explanation of possible causes?
ERROR GENERATING ROOT COMPONENT [Error: Cannot automatically buffer without a document] Error: Cannot automatically buffer without a document
at injectStyleOnce (/Users/bartolkaruza/Development/Projects/dmm/dmm-web/node_modules/aphrodite/lib/inject.js:90:23)
at css (/Users/bartolkaruza/Development/Projects/dmm/dmm-web/node_modules/aphrodite/lib/index.js:73:33)
at Header.render (Header.js:47:28)
at [object Object].ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext (/Users/bartolkaruza/Development/Projects/dmm/dmm-web/node_modules/react/lib/ReactCompositeComponent.js:587:34)
at [object Object].ReactCompositeComponentMixin._renderValidatedComponent (/Users/bartolkaruza/Development/Projects/dmm/dmm-web/node_modules/react/lib/ReactCompositeComponent.js:607:32)
at [object Object].ReactCompositeComponentMixin.mountComponent (/Users/bartolkaruza/Development/Projects/dmm/dmm-web/node_modules/react/lib/ReactCompositeComponent.js:220:30)
at Object.ReactReconciler.mountComponent (/Users/bartolkaruza/Development/Projects/dmm/dmm-web/node_modules/react/lib/ReactReconciler.js:37:35)
at [object Object].ReactCompositeComponentMixin.mountComponent (/Users/bartolkaruza/Development/Projects/dmm/dmm-web/node_modules/react/lib/ReactCompositeComponent.js:225:34)
at Object.ReactReconciler.mountComponent (/Users/bartolkaruza/Development/Projects/dmm/dmm-web/node_modules/react/lib/ReactReconciler.js:37:35)
at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (/Users/bartolkaruza/Development/Projects/dmm/dmm-web/node_modules/react/lib/ReactMultiChild.js:241:44)
Since I did not find any documentation, I just wanted to ask whether it it possible to set multiple values for the same attribute.
Like for example when you would want to use multiple values with vendor prefixes:
.myClass {
cursor:-moz-grab;
cursor:-webkit-grab;
cursor:grab;
}
const styles = StyleSheet.create({
transition: 'border-color 300ms ease-in-out',
})
produces:
transition: b-ms-order-color 300ms ease-in-out,b-webkit-order-color 300ms ease-in-out,border-color 300ms ease-in-out !important;
-webkit-transition: b-webkit-order-color 300ms ease-in-out,border-color 300ms ease-in-out !important;
Notice that border-color
has been mangled as b-ms-order-color
and the like. I am also seeing webkit-transition
styles with duplicate entries (and…mangled).
Let say I have a button css.
{
primary: {
backgroundColor: 'green'
},
secondary: {
backgroundColor: 'red'
}
}
Then I want to add disable for these.
{
primary: {
backgroundColor: 'green',
disable: {
backgroundColor: '#eee'
}
},
secondary: {
backgroundColor: 'red',
disable: {
backgroundColor: '#999'
}
}
}
and then having it
<Button className={ css(styles.primary, styles.disabled) } />
Now it doesn't use disabled classes inside primary.
I think it should find styles.primary.disabled as well.If you are using primary and disabled is under primary.
Looks like your main is lib/index.js
but you're publishing stuff in dist/
now? 0.3.1 works just fine.
We ran into an issue here at Spring when upgrading to the newest version of Aphrodite.
We use inline data uris for image icons, with styles like:
cartIcon: {
backgroundImage: 'url(data:image/svg+xml;base64,PD94...',
...
}
which produced
.cartIcon-somehash {
background-image: url(data:image/svg+xml !important;base64,...
...
}
I looked at the code and noticed it would also fail on something like:
content: "'my content;'",
I have a fix, and will PR.
Hi there! I'm not sure what's going on, but in version 0.3.0, there's a bug with StyleSheetServer
. Here's a reproducible example:
const {StyleSheet, css: aphroditeCSS, StyleSheetServer} = require('aphrodite')
const {html, css} = StyleSheetServer.renderStatic(() => {
const styles = StyleSheet.create({body: {display: 'flex'}})
const className = aphroditeCSS(styles.body)
return `<html><body class=${className}">hi</body></html>`
})
console.log(css.content)
This will log:
.body_poyjc{display:flex,-webkit-flex,-ms-flexbox,-moz-box,-webkit-box !important;}
As you can see, that's an invalid value for display
. My hope is that someone familiar with the codebase will see this and immediately know what's going on. But for me, I have no idea why that's happening.
Note:
I cannot reproduce it outside of a server rendering context (see here)
<style type="text/css" data-aphrodite="">.body_poyjc{display:-webkit-box !important;display:-moz-box !important;display:-ms-flexbox !important;display:-webkit-flex !important;display:flex !important;}</style>
The shorthand syntax for animations doesn't work and i would like to have this:
{
animation:
first-animation 2s infinite,
another-animation 1s;
}
Is it possible?
IE9 will only use the first 31 <style>
tags (https://support.microsoft.com/en-us/kb/262161). Since AFAICT Aphrodite creates a <style>
tag for each class, it won't work on IE9 with a lot of components.
I don't know what the perf implications of this are, but I know that webpack's style-loader (https://github.com/webpack/style-loader) has an option for whether to use a single style tag or to use multiple.
I suppose one could export two items...
//base
export const base = {...};
export default StyleSheet.create(base);
That said, it would be nice to have some sort of way to extend from a base set of styles... so that a deep join could be used on the base styles...
//base-style.js
export default StyleSheet.create({
button: ...
})
//my-component-style.js
import baseStyle from 'base-style.js';
const style = StyleSheet.create({
button: [
base.button,
{
...
}
]
});
Trying to get server-side rendering going with aphrodite. I am getting the following error, Uncaught TypeError: StyleSheet.rehydrate is not a function
. Isn’t it assuming that this is a global? How would I make it available to the client?
Here is what I am doing. Am I missing something?
import React, { Component, PropTypes } from 'react';
import serialize from 'serialize-javascript';
export default class Body extends Component {
static propTypes = {
assets: PropTypes.object,
css: PropTypes.object,
component: PropTypes.node,
store: PropTypes.object
};
render() {
const {css, html, assets, store} = this.props;
return (
<body>
<div id="content" dangerouslySetInnerHTML={{ __html: html }}/>
<script dangerouslySetInnerHTML={{ __html: `StyleSheet.rehydrate(${JSON.stringify(css.renderedClassNames)});`}} />
<script dangerouslySetInnerHTML={{ __html: `window.__data=${serialize(store.getState())};` }} charSet="UTF-8"/>
{Object.keys(assets.javascript).map((asset, key) =>
<script src={assets.javascript[asset]} key={key} charSet="UTF-8"/>
)}
</body>
);
}
}
Thanks for your help.
We're building a wrapper around aphrodite that makes our lives a bit easier.
One concept we have is styling based on tagname vs classname. And our styler resolves styles based on priority of: tag, class (ordered by appearance in class array or string).
One weird case is psuedo effects. Say I have:
<tag class="link active" />
Let's say link
gives a hover style:
link: { ':hover': { color: 'red' } }
But then active should set a new color:
active: { color: 'blue' }
Because aphrodite uses a single classname for both the selectors, the hover on the link
style will override on the active
color (when hovered of course), and I don't (think) there's a way to override it without manually setting hover in active.
For now I think the only way to fix would be to have our system detect psuedo attributes and auto-add that hover style, but that would be a lot of code/overhead.
Not sure the best way to handle this, one idea would be some under-the-hood style priority key that could potentially use CSS magic to override precedence.
{
link: { _priority: 0, hover: { ...styles } }
active: { _priority 1, ...styles }
}
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.