ReactNL 2016 Max Stoiber - Styling React.JS applications

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
whoa welcome everybody to reactor Nell I just want to take a second before I start and appreciate the venue because holy cow this is well decorated this is amazing really good job organizers as you said my name is Max this entire tweet this entire tweet this entire talk is live tweeted by Nick Groff in the audience so if you follow me on Twitter at MX s DVR you'll get sort of all the necessary information I work as an open source developer think milk as the introduction said think no we're a full-stack JavaScript agency nobody really knows what that means it means we use tons of node.js on the backend and lots and lots of react and react native on the front end and on mobile respectively I also make a bunch of open source projects I'm the creator of react boilerplate one of the most popular RIA start the kids with almost 10,000 stars now I maintain Keystone J's which is a node.js content management system that we make at thinkno and I'm also a container of elemental UI which is a react UI library that we built to build Keystone the Keystone admin interface and Nick graphical friend of mine sitting here he's also going to talk today he's a the creator of Bell so I've thought about and talked about this styling thing a lot both in the in this sense of Halloween style of react UI library and how do i style the apps that I build so today I want to talk about styling now I made this comparison between all the different methods that exists but I needed some sort of baseline that I could you know compare them upon so there's a checklist it's the checklist all right this is mostly stolen from the great repo it's from Michelle Bartoli it's called CSS - in - yes you can cool it then it's a huge table of 75 different or maybe 50 different styling methods with what they do you know checks checks checks checks but there's no code examples and I wanted to really dig in and see what is the best that what are the best methods that we have at the moment so I cut the checklist that changed it a bit these are the requirements that I tested all of these methods against I don't want to have any build requirements if I style my application I don't want my developers to have to learn a new build system just to start that's a bit ridiculous it should be small and lightweight I shouldn't have to think twice about dropping it in and starting the application it should support global CSS because while we want isolation for our components in a component based system sometimes you do need global CSS right sometimes you need to add a font face for example and font faces are global so it should support global CSS it should support the entirety of CSS we have a language that's made for styling right that's what it's made for we have hover styles with active styles with focus we've checked with all we have a tiny bit of logic in CSS right that we can use to style our applications why should we alias that in JavaScript why should we do that with JavaScript if we have support for it in our styling language right let's just use CSS for what it can and help it be even better the style should be co-located and I'll talk more about what that means soon they should be isolated because while CSS is very global right and that works for websites but in the component based systems you really want your Styles to be isolated to the component you're building right you don't want the styles of the button to affect how the header looks like that doesn't make any sense right the styles of the button should only be concerned about what the button looks like there's an old joke about CSS - CSS selectors walk into a bar a bar stool in an entirely different bar falls over that's what CSS sometimes feels like right you change something somewhere and something somewhere entirely different breaks and we want to avoid that in a component based system the styling method should be easy to override if my designer says the button on page number 100,000 22 should be red instead of green I shouldn't really have to you know make an entirely new component and do all of that stuff I just be able to override the stylist at one time it should be female this is an important requirement for UI libraries and I kind of want to style my UI to like the UI libraries that I use in the same way that I style my application right I don't want to have to styling systems in the same app that doesn't make any sense so to be theme able it should be it should have some sort of built-in support standard support for theming and it should support service at rendering because you might want to do that and it should not have any wrapper components because I hate looking into the react dev tools and having to dig through hundreds of components to find my own ones right so the thing with this checklist is there is no allgreen solution there is no solution that ticks all the boxes that's a very important point that's because every app is different and every app has different trade-offs right when you build an app you have certain trade-offs that enable certain features and the same thing is true for styling libraries right they take certain trade-offs as we will see but for that they get support for some very special features that some others might not have so that's something to keep in mind there is no allgreen solution here there is no solution that takes all of the boxes now to compare these styling methods we need something to compare them against and I wanted to simulate sort of a real-world example right I didn't want to just build another to-do list right I wanted something where I could actually like have all of the things that I need all of the things that could happen in the real world app in one small example so Michelle Bertolli made an example which is this the design is obviously blatantly stolen from the Twitter mobile interface this is entirely custom built it has some interactions so when you hover over it it shows an underline if you hover over the links it shows an underline and you can click on the like button and it has this sort of small popping bouncy animation and turns red very fancy I know it's like you know beautifully designed obviously and it also has some it's also responsive so if you resize it it adapts to bigger screens it has this sort of jump if you look at it on a bigger screen you're going to get a bigger font size and then when you get smaller than the minimum size what happens is it just squeezes together it's all size with percentage you know very standard responsive design stuff nothing special happening there let's take a look at how this is implemented right so we have this app component that wraps everything and a groundbreaking stuff here right this is I mean nobody's ever done this before and I've component inside of which there's a tweet component well who would have thought that sweet component is made out of three components header the content and the footer component I know it's genius right like this is blows my mind ladies components like your standard react components right except for some small things like if we look at the content component you might notice something pretty weird dangerously set innerhtml underscore underscore HTML this text what that sounds dangerous why would you do that so we have full control over the data that this gets this component gets right and we have full control of the rendering why would we pass in an HTML string and then dangerously set in range tomorrow well since we wanted to emulate a real-world app we have some artificial constraints right we have some constraints in this example that are totally unnecessary for this example but there are constraints that you will hit eventually in your app right I've had to use dangerously set inner HTML in two years of writing reactors that they use dangerously set inner HTML maybe five times if even that but the five times I've had to use it I've really really had to use it and I don't want to have to add an entirely separate build step just to style the stuff that I inject by a dangerous set into an HTML when I have to write the styling method should support that so really these constraints aren't artificial they're just constraints that we put in right there constraints that or most apps will reach one way or another and we wanted to see where the edge cases are of these styling methods I've been staining styling methods styling methods a method with which methods am I talking about well these are the five methods I want to look at today the first one vanilla CSS very fancy I know but we need some sort of base line to go from then we'll take a look at CSS modules which is the most popular way to style react applications at the moment except for vanilla CSS and then we'll go to CSS EGS with GSS and Aphrodite entering lens styles with radium I just said CSS and GS and inline styles what's the difference there why is that different things so when you write your styles as a JavaScript object in react it and that is built-in supported you can attach it to the style prop so you can go P style equals an object of CSS right and that just works and what happens is react takes that object loops over it takes every property and every value and sort of puts it into the Dom as a string and attaches attaches it to the element as inline style right it just says P style equals and then a string of whatever styles you have whereas with CSS in GS you attach something to the class name instead of attaching something to the style you attach something to the class name and this isn't but this isn't built into react or anything you need a library to do that and what the library does is it takes your styles that you write as JavaScript objects it makes it CSS and then somehow inject it into the Dom and sets the class name of the thing you want to set the class name on to something unique so it's isolated and you don't have class name overlaps so that's the difference between inline styles and CSS in GS so let's start with CSS it's very special this is what CSS looks like I know I know bear with me we have some you know global Global styles we have a class and then we have a media query nothing really nothing fancy going on this is what the stars of our content component look like the one thing to note here is that we use pen notation so we do tweet underscore underscore content to avoid naming clashes and we also do nesting because into this content as we know we use dangerously set in HTML to inject the content but the links inside that injected content need to have a certain color and to need to have an underline when you hover over them so this is the way to do that in CSS right we've all seen this before it's nothing fancy what this looks like in the component well we touch class names and that's it you know we've all done this before nothing fancy going on here let's let's take a look at the checklist what that's like for CSS so we don't have any build requirements obviously it's the smallest and lightweight as it could be it totally supports Gloria says it obviously supports the entirety of CSS it is CSS after all it's totally not co-located it's totally not isolated it's easy to override there is kind of theming support with custom properties and that's going to be like as soon as they're supported everywhere theming in CSS will be amazing but right now they're just not supported everywhere so you can't actually use them so that's why it's a kinda it totally supports service of rendering obviously and there is no wrapper components the thing is the four other methods that I want to talk about today all of them are trying to beat this checklist right all of them are trying to be better than this in the sense that they want to have colocation and isolation as features and for that they take some trade-offs right they don't have some other things to give you support for colocation and isolation and that's the whole idea behind them so let's take a look at CSS modules right our code is again CSS it doesn't actually look any different right it's global stars if you want them either in a class you know a media query everything it's just CSS our content opponent cluttered styles look a tiny bit different because we don't use been notation here so the whole tweet underscore school thing is gone everything else is exactly the same how do we use this in our components well you import styles from your component style files styles file so all the styles for that component are in that file every component has a style file and you import your styles from there and then you attach a class name of style store content and the thing is what you will see in the Dom will not say P class equals content it will say P class equals content and it's got a score abc123 some sort of random hash how CSS will just work why does that why does it do that so if you have a class in your component specific CSS files what it does is it uniquely files it so it prepends the name of the component and it appends a hash of the contents of the class that means that even if you have the exact same class in an entirely separate file it won't be the same it will be a different one and that way you never have class name overlaps which is amazing let's take a look at the checklist here we have huge build requirements CSS modules requires you to use webpack they're easy post to assess implementation but it's kind of hard to use so everybody uses the webpack implementation and then you have to use webpack kind of annoying it's totally smaller lightweight there's no extra JavaScript it supports Global CEO says it's supposed to the entirety of CSS it's kind of Colo catered in the sense that it has to be in a separate file and we'll get to why that's the kind of very soon it's isolated it's easy to override it does not have any special theming support its service at renderable and there is no wrapper components Michael Chan recently put out this great article about styling components and he had this quote in there where he said if you're writing react you have access to a more powerful styling construct than CSS class names you have components and that I think is very much the crux of why people like inline Styles instead of having to rely on global CSS classes you can suddenly rely on JavaScript and you can do logic and math to style your application actual logic and math not pretended logic in math we can abstract implementation details so if you imagine a primary button component right that can just render a button component with the second class and your user the person who uses your primary button doesn't even have to be aware what the class is or how its styled or it doesn't like it it just doesn't matter in react the component matters right that also means that that was just an example of math right because if you have a primary button that renders a button with an extra class that's partial application and we can do things like composition with components which are totally not possible in CSS it's just so much more powerful as a language that what we have in CSS so I just talked about this a bit but let's elaborate a bit why do we want to co-locate our styles in the same file as our component and really the question is why do we want to put our Styles in our JavaScript as I just said we can use the power of JavaScript right I can just copy and paste code from wherever to wherever and it's going to work I no longer have two languages I need to worry about right I just have JavaScript files I don't have any CSS files anymore with CSS modules if you want to use it with CSS if you want to move some Styles around you have to go to the right file you have to cut the right part then you have to find the other right file I need to paste the right part many of - and it's it's a lot harder than just taking that block and putting it into another file right dependencies are really easy to find like everything is just imported at the top of my file I know exactly what my component uses we have really good code view search because we can share constants between CSS and JavaScript we can really easily adapt to the environment a lot better with very complex requirements right in JavaScript we have a lot more information about what the user does and who he is or who they are right and that way we can adapt our styling based on what the user does based on a lot more complex queries than we can do in CSS right and CSS we've got media queries but that's about it this is a great quote by Jordan scales also from an article where he said separation of concerns you might chance well I've separated my concerns for ten years and now I'm too scared to touch my CSS and I'm sure that's a feeling that many people have felt right with CSS you just sometimes you just get these bugs where something breaks and you've no idea why and you're looking at a two-year old project and you your takes day to do anything because everything always breaks it's really annoying and so we're trying to solve that especially in the component based systems the whole global thing with CSS is just not what we want right we don't want global stars we want our component to look how our component should look like right not any different why should that affect anything else with that in mind let's take a look at jss the first CSS NGS implementation this is what global Styles look like in JSS as you can see it's written in object notation it's in JavaScript you can have media queries that works perfectly fine with global styles in CSS you need to do this inject cheat thing at the very bottom and set the option of named to false otherwise JSS will go ahead and unique if I your class names which you don't want because you want the HTML files to be on the HTML tag and not some random class name this is a bit weird because inject cheat returns a component so we then have to render the result of this into the Dom which feels a bit weird but I know all like it's very much at work making this API better so that's great to know this is what the styles for a component look like as you can see again object notation and we have full nesting support so this is the styles for a Content component again we need to style the links a bit differently and they're injected so you can just nest your things right that just works and then how do you use it well JSS has this again inject cheat the same thing except this time we don't pass the name false option to it and what that does is it injects the sheet into your component so you go and your component gets this sheet property that has a class property and you can use those classes you can like you can just add them to the elements and JSS will take care of injecting this he says properly making sure it works everywhere prefixing it you know all that stuff it just does all of that you just write inject read styles and content and that's it let's take a look at the checklist here we have no build requirements whatsoever it's small and lightweight it's like a few hundred lines of code it kind of supposed Global CSS again you have to it returns a component and you get to render it which is a bit weird but that's going to be fixed tuned it supports the entirety of CSS it's totally co-located it's totally totally isolated it's kind of easy to override because you can use inline styles to override your component stars on a specific at a specific point right but there's no like mechanism for it there's no built-in mechanism for it that's standard so everybody's going to do a bit differently which isn't what we want there's no special theming support its support server-side rendering and there are wrapper components the nice thing about GSS is contrary to all the other methods it has a plug-in system so you can write plug-in systems to do something with the CSS you write with the styles you write which is how nesting support was added right that's very nice that's a very good idea so if we look at this right as the first true CSS and Jess method this sort of gets the co-located and isolated but loses the no rapper components and the global CSS against non dealer CSS right so that there's a trade-off you have the true collocation and isolation but for that you lose some other things right and that might fit the use case that your app has or it might not and if it doesn't search for another library like for example Aphrodite every dieter this is what the styles for a content component look like look like there is no support for global stars so I can't actually show you how to do global stars because it's not possible there's no nesting either you don't see any anchor tags here it's just the stars for a content component this is how you use it in your component you have the CSS method and you say class name equals CSS and then you pass in style store content and that's it nc Aphrodite will take care of you know uniquely fiying it injecting it into the Dom that sort of thing the checklist here is very interesting because there's nobility comments it's it's very small and lightweight it does not support global CSS at all it does not support the entirety of CSS at all but it's co-located isolated it's kind of easy to override the thing with Aphrodite is that it's built by Khan Academy we have a huge pre-existing code base that they're introducing react and styling into right so when you use Aphrodite preet like two months ago if you used it every single property every single CSS rule that it outputs into the Dom would have exclamation mark importer dependent right so if you wrote call a black background read what would be injected into Dom would be color black important background red important and that's because Khan Academy solved their own use case first which is integrating with the legacy system and if that's a use case you have every died is a great choice right and now they've also added the no important mode so if you use that again you can use inline styles to overwrite your component but again there is no standard mechanism for it there is no special theming support they service a trainer income support and there are no wrapper components so Aphrodite has this whole okay it's real easy to integrate in a legacy system in a pre-existing code base right and it's co-located and isolated and all that but for that the I love is that we don't support entirety of sucess and we don't support global CSS so again it's all about trade-offs right they have a different use case in their application so they have different traders in the styling libraries let's take a look at radium and this is really interesting because radium is the only true inline Styles method that people use except for in react native this is how global Styles work in radium and I think this is a great API they export this style component which just works exactly like a style tag and CSS except it takes CSS and J's and they take care of injecting it and making sure it's global we have media query support which is very nice this is what the styles for a content component look like again there is no nesting support in fact radium doesn't even support most peerless pseudo selectors radium supports hover active and focused I think but it doesn't support any of the others and that's because it's inline Styles and if you attach Styles as a string to elements in the Dom you cannot have serious selectors so what they do is when you use radium they say is that in JavaScript so they check which of your components use hover and then they go in and say okay onmouseover add another class add other styles like to hover stars and onmouseout remove them again right so this is what it looks like in your component you just import radium from radium say wrap your component in radium in a high order component and just say style equals styles or content or style equals styles of media let's take a look at the checklist here and this is what radium is really interesting there are no build requirements it's very much small and lightweight it supports global CSS it does not support the entirety of CSS but it's co-located isolated they have a very beautiful / overriding mechanism they have theming support its service ID venerable and there are wrapper components so what we see here is actually this is really green right there's lots of boxes that radium ticks for the trade of that they don't support all of CSS taking a lot of other things right for the trade of that you that you have to use JavaScript for hover and media queries and that sort of thing you get everything else essentially which is interesting to think about now let's compare them all side-by-side if we put all of the check lists next to each other this is what it looks like I know that's not very readable let's add some more you know let's let's see what what this actually looks like now something you might notice is that small and lightweight and server-side rendering both are all green so let's remove them because if they're all green they don't help us compare the methods right like there is no reason to have them there so this is what the comparison looks like but there is one more thing I want to talk about today let's take a look back at our comparison what if I told you that you could have this and not only that but that there's one more category to beat that nobody's ever done before exactly so Glen Madden who is the original creator of one of the original creators of CSS modules and I we met in Australia when I was down there on a holiday and we chatted about CSS because I thought that was sort of on my mind at the moment because we were thinking how are we going to style elemental UI how are we going to style the Keystone admin interface what are we going to do and I chatted with him and he showed me this thing they like the third iteration of something he had built and the API was horrible right I looked at in Ireland oh my god why would you ever know please just go away why and he was like no no no no look look look just try it give it ten minutes right build something very small with it just try it and I tried it and it was amazing the development experience even in that very early stage was beautiful you know I got so much done in a really short amount of time we've since reworked that IP I it's much better now so there's two weird ideas that we have right we want to give you full colocation and isolation and all that stuff right but we also remove the mapping between styles and components because if you think about it all of the other methods like aphrodite JSS all of them they all have a way of having styles and then having components and you attach the styles to the components either via inject cheap or saying style equals styles or content or class names or whatever right but really we're we have components now why do we even have styles what if we used components as the lowest level styling construct right what if we use components to our full advantage and then there's a second very weird idea that we have we want you to be able to write actual CSS next to your components we're talking full collocation styles in the same file as the component but still being able to write actual CSS and also supporting all those CSS because we have CSS right it's made for styling by which we try to force that at any other language right so today I'm incredibly excited to announce the release of styled components thank you I like how everybody just clap without even knowing what it's like yeah that's a great name max you did good so let's take a look at what this looks like right this is it we input styled from styled components right nothing fancy going on there but then what we do is we say cons title equals style h1 and I want to focus on this style h1 because what this does is it creates a react component so our title what what is called title here is now a react component that we can render in our JSX and then after that we pass in some styles as actual CSS what you see here this weird syntax with like calling a function with the backticks that's called a tag template literal it's an es6 feature I had no idea that existed I looked at it I was like well that's weird but that's an actual es6 feature right and it allows us to handle your interpolations very interestingly which I'll get to very soon so this is an h1 that has a font size of 1.5 m is aligned in the center and as the color of pale violet red you know it's CSS we can just read it and then we have a wrapper component that's a section you know it also the color of pale violet red it has some padding it's you know the full width and height of its of its parent element and as a background of papaya whip the pipe is an actual CSS column and by the way it's beautiful so these components title and wrapper we can just render in our JSX they're just react components that's what they are so you can now go rapper and wrap the title in that and then passing some children in our case some text hello this is my first styled component and this is what it looks like in a browser right it's an h1 and the section and the style it's styled component make sense right now that's cool um all right so we've got we've removed the mapping between this you know blah blah blah but we have some really cool features in there because we have tag template literals so we can allow you to really easily adapt your styling based on the props of the component right you're rendering a component in j6 like the title those components as properties right they have properties you can pass in you could say something like title big or title small you know how do we handle that well let's say you have a button and you've your primary button and those should look you know slightly different because primary buttons are primary they're red and big and you know in your face whereas normal buttons and sort of like yeah here I'm here I'm clickable so we styled components what you can do is we again just say styled a button but then you can pass as interpolations into the template it rolls right these interpolations can be anything they can be just variables or objects or whatever you want right but if you pass as a function internet interpolation we pass you the properties that are passed into the component and you can adapt the styles of your component based on the properties that are passed in so in this case we adjust the background color and the color based on the primary property right if it's primary the background should be pale violet red and the color white and if it's not primary the other way around the background should be white and the color should be pay a violet red so again with a normal button with a button primary it's like your standard react components and when you render them one of them is normal and one of them is primary so you now have really a lot of control over your styling you know you have your components and you can really easily adapt it you can be easy the designer says hey in the key a in the new comment section you know the buttons should be blue not green you're like oh my god no in this case you can just you know add a property you know say button blue and that's it we also have theming built in we really wanted to solve this issue because there's so many great third-party component libraries that are a pain to use just due to the fact that you can real it's really hard to style and theme them right you can it's it's just it's it's not a solved problem in the react world well we have this theme provider component so you can wrap certain parts of your app in theme providers and provide a theme to all its children and what this will do for example is it will set the primary the primary property of the theme to pale violet red you know oops the theme to pray violet red right and then you can just render it and all these children will have that theme so in your styled components what you can do is you can we inject that theme as a property into your component so you can go hey here the property is the component oh hey there's a steam oh yeah I'm gonna do the primary thing you know the background of this button is now primary and the thing is if you have two different sections of your site's right if you like a sidebar and main area the buttons are supposed to look in hi like all the same in the sidebar and all the same in the main area but they're different between the main area and the sidebar you can just wrap a theme provide around them and provide a different theme and your button will just adapt right so in this case we have a red team and the blue theme right nothing fancy going on here we render two theme providers one with the red theme one with the blue theme and we rent the buttons inside them and these buttons we don't do anything special with them we just render them and they just adapt to the theme of the parent so this also works as many levels of components deep as you as you can imagine it uses Reax context to bypass the whole parent children relationship and so a button that's five levels deep with it within a team container within the theme provider sorry still gets the same theme now that's all very cool right that's all you know with theme support with overriding support you know you write actual CSS you remove the mapping between stars and components but that's not everything styled components has full react native support that means for the first time ever we're able to style your react native applications with actual CSS right and not only that you can really easily share styles between react native and your web applications so cross-platform apps styling them is all the same it doesn't matter if you're in Android it doesn't matter if in iOS or web you style all your components the exact same way instead of having to jump around between different api's let's take a look at what this looks like the one thing you have to do is you have to import style from styled component slash native and that will give you access to the react native primitives so you can now go Const wrapper equals style dot view and view is just a react native primitive write like a div on the web this is just the react native equivalent and we can style that view with style component so we say background color papaya web flex 1 just if I come to the line everything we just style it with CSS and the same thing is true for our title right we just say it's a style dot text a react native primitive again right and then which is solid we set the font size to something in beeline the Texans and the blah blah blah and then we just render it in our react native application like any other react component and well this is what it looks like yeah I like I like whether that is this is an actual screenshot from my phone I went when I took this facial I was like holy cow this actually works that's awesome so we've checked off more boxes than any other styling method before us not only that we've checked off so many boxes that we believe that style components is a very good way to sell your react and react native applications so that's all cool and all right but can you actually use it yeah you can npm install styled components and it works right now I know two days ago right we all remember so right now it's yarn ad start components right forget the npm install just do yarn ad and that perfectly works the whole thing is open-source so if you go to github.com slash styled component slash style components you will see the entire source use it submit issue submit pull requests let us know what you think give you the star we've been working on this for a few months we use it in our project we love it we think it's great I want everybody to use it there's a few more links you will have to take a look at there's the comparison repo github.com slash styled component slash comparison which has all the code you just saw it has the the example tweet built with every single styling method you can take a look at it you can take a look at the code it can run each of the examples you can see what they behaves like you can see what it looked like to start applications with either with each of these methods we have an amazing website that I built in two hours style - components come take a look at it it's very nice and I also want to point to this great repo github.com slash Michelle but totally slash CSS injuries this is a big part of where I stole the part of the checklist from there's a huge table with 50 different methods of styling with the checklist that says ok it can the district and the dot that's how it works it's very nice Thank You Amsterdam you've been great enjoy the rest of the day enjoy the remaining talks
Info
Channel: ReactNL
Views: 13,956
Rating: 4.9652176 out of 5
Keywords: ReactNL, Xebia, front-end, JavaScript, frontend, React.js, Max Stoiber
Id: 19gqsBc_Cx0
Channel Id: undefined
Length: 38min 37sec (2317 seconds)
Published: Thu Nov 10 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.