You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Sep 21, 2022. It is now read-only.
Repository navigation
This repository was archived by the owner on Sep 21, 2022. It is now read-only.
Server-side: Media queries and pseudo classes for inline styles #8
For media queries, I would suggest to just read window dimensions in JS and re-render the entire page.
For pseudo-class like :hover, my thought is to do hoverStyle={...}. This way if your component also implements hover in pure JS, it can use the same API.
For :before and :after, just insert a new element in the DOM.
I am having problems with the :focus pseudo classes.
Is the typical TagList, where you have an input as the end of the tags. This input is small, but when :focus it gets a css outline. The element have an inline style of outline:none, but is ignore on :focus.
That sounds interesting, I've thought previously about a method where the styles are written into a style tag for server side rendering and parsed by code on the client similar to how the DOM is with current server-side rendering. This would leverage the css engine even for js-enabled browsers, but I don't know what kind of performance impact there would be from reading out the styles client side. And for inaccessible styles rules like :visited, the client side code could also write into a style tag.
@contra i like that solution for media queries applied client side, I was thinking more toward spicyj's point for sites that use react exclusively on the server side. And I think a large part of the reasoning behind the server-side rendering of react in general is that you get the initial static content pop, which may require media queries.
@ainscore Server-side media queries could specify a default that is executed, or possibly parse user agents to guess the device specs and do your own matching. I'm planning on playing around with those ideas soon
The "specifying a default" approach is the one I took with react-mediaswitch. The UA stuff is separate IMO, though it could be used to decide which media case is the default. We're also considering sending a separate XHR request for the initial view which passes along device dimensions (or a string that indicates which of the server-defined device dimensions is appropriate).
changed the title [-]Media queries and pseudo classes for inline styles[/-][+]Server-side: Media queries and pseudo classes for inline styles[/+]on Nov 5, 2014
@sebmarkbage I fail to see why side is important here, server-side you could have default value or parameter passed from the client ; Am I missing something ?
@contra That's pretty much what I'm trying to accomplish with my mixin.
@sebmarkbage I fail to see why side is important here, server-side you could have default value or parameter passed from the client ; Am I missing something ?
A "default" value, or event a guess from the user-agent, will sometimes be wrong.
"Isomorphically", you need to be able to handle media-queries the same way on both side. So you need a fallback value for when you don't have "screen size".
But I don't see why we would need to have a specific way to handle it server-side. It seems overkill to me.
@Cethy The mixin seems too complicated. I think something as simple as re-render on window.onresize and a sugar this.media object (with info like this.media.screenWidth, this.media.pixelRatio, etc.) as a mixin would suffice just fine.
@Cethy: There are two separate things being discussed here:
Conditionally returning different DOM trees from render() calls based on JavaScript values (such as those that come from matchMedia, component state, a React mixin, etc.
Having a way to use CSS media queries for the a React element's CSS styles.
These two things are different and have non-interchangeable behaviors. Your mixin is a way of doing (1). This issue is about finding a solution for (2).
@contra you've got a point, I'll try to split my work to have something more simple.
@parshap Thx for the clarification, i hadn't read the inline styles proposal (since the link from spicyj is broken, aha) ; now I understand, so forget my last intervention :)
Perhaps it's a stupid proposition but with that kind of thing : https://gist.github.com/fdecampredon/86ccbba3863bccaec7dd
We could obtain client media information while we stream server response and still have the same result from rendering on client and server.
If we're sticking to a very strict application of server-side rendering in which no javascript needs to run in order for the media queries and pseudo-classes to work correctly, I see two approaches.
One would require compiling a stylesheet from the Javascript logic and sending that down with the html. The dom and stylesheet would then be parsed by React on the client side and any further application of styles would happen on the DOM.
This would not necessarily render the exact same DOM tree on the server side as the client side(in this example, both bigContent and smallContent would be rendered on the server side and only one displayed on the client, whereas on the client side only one would be inserted in the DOM), thus it could result in rendering an unnecessary amount of HTML. However, the extra content would be removed after a render pass on the client side, so functionally this shouldn't be an issue(at least in a pure react environment).
I'm not entirely sure if the javascript logic can be parsed into correct media queries in all cases but this code is how I imagine it happening in a simple case.
(Showing examples for media queries but pseudo classes could be applied in a similar way)
render: function(){if(screen.width>=480){// desktop stuffreturnReact.DOM.div({},bigContent);}else{// mobile stuffreturnReact.DOM.div({},smallContent);}}
Rendered html:
<divclass="disp_0" ><!-- big content --></div><divclass="disp_1" ><!-- small content --></div>
A second, simpler approach would allow specifying the media queries in React StyleSheet objects, so that only those objects would need to be processed by the stylesheet compiler.
render: function(){returnReact.DOM.div({},bigContent({style:StyleSheet.create({base: {//set prop as "none" if width < 480display: React.Media.maxWidth(480)("none")width: 1024,height:40}})}),smallContent({style:{base: {display: React.Media.minWidth(480)("none")width: 480,height:40}}}));}
Rendered html:
<divclass="disp_0" ><!-- big content --></div><divclass="disp_1" ><!-- small content --></div>
Thinking about this problem I describe my solution in the following blog post, which introduces a new abstraction called VirtualCSS which is similar to CSS like VirtualDOM is to the DOM in react terms:
Activity
vjeux commentedon May 26, 2014
For media queries, I would suggest to just read window dimensions in JS and re-render the entire page.
For pseudo-class like :hover, my thought is to do hoverStyle={...}. This way if your component also implements hover in pure JS, it can use the same API.
For :before and :after, just insert a new element in the DOM.
Do you see anything else I missed?
sophiebits commentedon May 27, 2014
It would be nice to be able to do actual media queries so that server-rendered pages can be laid out correctly.
:visitedis probably the trickiest because it can't be faked in JS.yocontra commentedon Jun 10, 2014
window.matchMedia would work well here
guillermo commentedon Jul 8, 2014
I am having problems with the :focus pseudo classes.
Is the typical TagList, where you have an input as the end of the tags. This input is small, but when :focus it gets a css outline. The element have an inline style of outline:none, but is ignore on :focus.
ainscore commentedon Aug 25, 2014
@spicyj Would the intention be that server-rendered pages would display correctly sans-JS?
sophiebits commentedon Aug 25, 2014
@ainscore Yes, that's what I meant.
ainscore commentedon Aug 25, 2014
That sounds interesting, I've thought previously about a method where the styles are written into a style tag for server side rendering and parsed by code on the client similar to how the DOM is with current server-side rendering. This would leverage the css engine even for js-enabled browsers, but I don't know what kind of performance impact there would be from reading out the styles client side. And for inaccessible styles rules like :visited, the client side code could also write into a style tag.
yocontra commentedon Aug 25, 2014
To solve media queries I ended up doing this https://github.com/wearefractal/react-responsive which I think makes way more sense
ainscore commentedon Aug 25, 2014
@contra i like that solution for media queries applied client side, I was thinking more toward spicyj's point for sites that use react exclusively on the server side. And I think a large part of the reasoning behind the server-side rendering of react in general is that you get the initial static content pop, which may require media queries.
yocontra commentedon Aug 25, 2014
@ainscore Server-side media queries could specify a default that is executed, or possibly parse user agents to guess the device specs and do your own matching. I'm planning on playing around with those ideas soon
matthewwithanm commentedon Aug 26, 2014
The "specifying a default" approach is the one I took with react-mediaswitch. The UA stuff is separate IMO, though it could be used to decide which media case is the default. We're also considering sending a separate XHR request for the initial view which passes along device dimensions (or a string that indicates which of the server-defined device dimensions is appropriate).
Cethy commentedon Oct 23, 2014
Another take on react & media-queries : https://github.com/Cethy/react-mixin-media-query
I used a "
mixinapproach" instead of the "classical" component one. It might seems less flexible, but it makes a lot more sens to me.The nice side-effects I wanted to attain were :
Feel free to try it and send me some feedback. :)
[-]Media queries and pseudo classes for inline styles[/-][+]Server-side: Media queries and pseudo classes for inline styles[/+]sebmarkbage commentedon Nov 5, 2014
I clarified in the title, that this issue is concerned with server-side rendering.
yocontra commentedon Nov 5, 2014
What do you think about having media information become a new object that updates a view (similar to this.state and this.props)?
RReverser commentedon Nov 6, 2014
@contra You can already do this via
if (screen.width >= 480)+onresize.Cethy commentedon Nov 6, 2014
@sebmarkbage I fail to see why side is important here, server-side you could have default value or parameter passed from the client ; Am I missing something ?
@contra That's pretty much what I'm trying to accomplish with my mixin.
parshap commentedon Nov 6, 2014
A "default" value, or event a guess from the user-agent, will sometimes be wrong.
Cethy commentedon Nov 6, 2014
@parshap And how would you fix that ?
"Isomorphically", you need to be able to handle media-queries the same way on both side. So you need a fallback value for when you don't have "screen size".
But I don't see why we would need to have a specific way to handle it server-side. It seems overkill to me.
yocontra commentedon Nov 6, 2014
@Cethy The mixin seems too complicated. I think something as simple as re-render on
window.onresizeand a sugarthis.mediaobject (with info likethis.media.screenWidth,this.media.pixelRatio, etc.) as a mixin would suffice just fine.parshap commentedon Nov 6, 2014
@Cethy: There are two separate things being discussed here:
Conditionally returning different DOM trees from
render()calls based on JavaScript values (such as those that come frommatchMedia, component state, a React mixin, etc.Having a way to use CSS media queries for the a React element's CSS styles.
These two things are different and have non-interchangeable behaviors. Your mixin is a way of doing (1). This issue is about finding a solution for (2).
Cethy commentedon Nov 6, 2014
@contra you've got a point, I'll try to split my work to have something more simple.
@parshap Thx for the clarification, i hadn't read the inline styles proposal (since the link from spicyj is broken, aha) ; now I understand, so forget my last intervention :)
sophiebits commentedon Nov 6, 2014
Updated the original link so that it works again.
fdecampredon commentedon Nov 9, 2014
Perhaps it's a stupid proposition but with that kind of thing : https://gist.github.com/fdecampredon/86ccbba3863bccaec7dd
We could obtain client media information while we stream server response and still have the same result from rendering on client and server.
ainscore commentedon Nov 10, 2014
If we're sticking to a very strict application of server-side rendering in which no javascript needs to run in order for the media queries and pseudo-classes to work correctly, I see two approaches.
One would require compiling a stylesheet from the Javascript logic and sending that down with the html. The dom and stylesheet would then be parsed by React on the client side and any further application of styles would happen on the DOM.
This would not necessarily render the exact same DOM tree on the server side as the client side(in this example, both bigContent and smallContent would be rendered on the server side and only one displayed on the client, whereas on the client side only one would be inserted in the DOM), thus it could result in rendering an unnecessary amount of HTML. However, the extra content would be removed after a render pass on the client side, so functionally this shouldn't be an issue(at least in a pure react environment).
I'm not entirely sure if the javascript logic can be parsed into correct media queries in all cases but this code is how I imagine it happening in a simple case.
(Showing examples for media queries but pseudo classes could be applied in a similar way)
Rendered html:
Rendered stylesheet:
A second, simpler approach would allow specifying the media queries in React StyleSheet objects, so that only those objects would need to be processed by the stylesheet compiler.
Rendered html:
Rendered css:
mtford90 commentedon Dec 13, 2014
+1 for a simple way to apply inline pseudo styles
koistya commentedon Dec 16, 2014
@ainscore 👍
jviereck commentedon Mar 31, 2015
Thinking about this problem I describe my solution in the following blog post, which introduces a new abstraction called VirtualCSS which is similar to CSS like VirtualDOM is to the DOM in react terms:
https://medium.com/@jviereck/modularise-css-the-react-way-1e817b317b04
minaseem commentedon Apr 5, 2016
use radium
https://github.com/formidablelabs/radium