Adam Wathan - Tailwind CSS Best Practice Patterns

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
first speaker let me tell a story about the first speaker I've been learning so since I started to come to Larrick on I have decided I'm gonna learn how to code and the way I do that is I basically call up Adam Wathan on skype and get him to show me stuff and I videotape it and put it out on YouTube and stuff and the other day he taught me how to write my first 12 lines of view and I posted this on youtube and someone commented they're like oh way to go that's like learning a basic spell from Gandalf so I want you guys to give a warm welcome to Adam whatta and Gandalf hello how's it going alright so talk too short this year so I'm not gonna waste any time my name is Adam Lavin I've been involved in laravel community for a long time but lately I spent most of my time working on this a CSS framework called tail and CSS how many people here have used talent for something before cool so a bunch of people so for anyone who hasn't used it here's kind of the TLDR so normally when you're trying to like build something say we're trying to build this little like chat notification component you might write like a bunch of HTML like this put together a bunch of classes like chat notification chat notification content whatever right and then go ahead and open up your CSS file and implement all those classes and bang you're done everything styled the way that you'd build this same thing with toind it's more like this we have all these horrible ugly classes that you use instead like p6 and ml6 and text excel and stuff like that right but the cool thing is that when you build something this way using telland you don't actually have to write any CSS at all so the way that I like to think about to--and because a lot of people kind of have this idea that like this is like mixing everything this is ugly this is crappy the way that I kind of like beautify it in my head is by thinking tone is really like an API for your design system so instead of writing HTML inventing class names jumping over to your CSS file and implementing them your HTML instead becomes sort of a consumer of this like class-based API where everything that you've sort of built in your tail and CSS file defines all the sort of allowed or available style rules that you can add to any of the components in your project so like box shadows for example maybe you decide okay these are the five box shadows that we want to be able to use in our project these are sort of the elevations in our design system so there's a class for each one and you just slop it on an element if you want to add that shadow or same with things like text sizes you know text large is supposed to be this size in our project we just slopped the class on we get it no more like don't your CSS file mucking around with hard-coded values everything comes from this sort of like constraint set so it's a little bit of a weird way to work at first and kind of seems like a little bit contrary to sort of all the advice you've probably ever heard about writing the whole life but I find the in practice this is actually really practical and productive because maintaining CSS is a nightmare and editing HTML is super easy and and the thing I think it's kind of interesting about this a lot of people kind of will think like well it's supposed to be hard to maintain it's it's only good if it's hard to maintain but it should be a lot of work you know that doesn't make any sense it's hard to maintain that it's bad like that's the whole point they're trying to write good code so that's easy to maintain so if writing your Styles this way is easier to maintain then maybe it's not such a bad idea after all so what I'm gonna be talking about today a talk that I've always wanted to see other framework authors give as sort of a user of those frameworks it's like how do they use it how do they solve common problems like I'd love to see Evan give a talk I'm like here's how I build a view app and here's a walkthrough of like my thought process or Taylor here's kind of a tour of like a laravel app that I built and why I named my controllers this why organize things this way or whatever so I thought well I made the CSS framework maybe people would be interested in seeing sort of like how I solve common problems with it and what I think is sort of the idiomatic way to use it and how to deal with things that maybe are a little bit trickier at first so today we're just gonna be talking about sort of a bunch of principles and practices I like to keep in mind and follow when I'm building applications by using Talent CSS so the very first one is to extract components not classes so let's head over to some code here so I've got this little kind of like splash page demo that I put together here and here is all the code for it right so a common thing that people were running to is they'll see something like this little button down here and they'll look at the code and see okay well we've got like 13 classes to build this button there's a real good chance I'm gonna want to use this button multiple times on my site and copying and pasting all these classes all the time seems like maintenance hell like I don't want to do that I don't want if I decide to change the border radius on a button I want to have to change it in a million places in HTML files so toen has a cool feature for trying to solve this problem that lets you kind of like extract out common repeated utility patterns so if we head over to like our app dot CSS file just gonna copy all these classes you can do something like this or we could say okay well maybe we want to create like a button class and we want this button class to just be like kind of the abstraction on top of all these utilities so instead of writing all the CSS by hand we can just say apply paste in the list of classes and then head back here or place this with button and now it looks exactly the same and if we wanted to add more buttons you know we just used that same class and we're good to go if you wanted to change the border radius on all these buttons we have a single source of truth for it now right which is kind of cool so that works really well for these sort of really small like single HTML element sort of abstractions but I find people try to abuse this feature in places where I think like there's a better solution so here's like another example see you down here we have all these sort of cards with his image and title and link and stuff like that in the HTML here's kind of how that's implemented so we just have this like blade loop that spits out a bunch of columns that have you know all these utilities building up all these cards so the first thing to understand I think is that trying to create these abstractions is it's only really a good idea if you're trying to solve a duplication problem so it's only really when you're actually repeating stuff in a bunch of places that you want to create sort of a single source of truth so in this case there actually isn't any duplication because we're actually just doing it in a loop if I want to change the border radius for all these items I can already do it in one place right but say we were reusing this card somewhere else on the site or in a different part of the page and we're copying and pasting it okay now I have like an actual duplication problem you might want to solve so something that I see people do though I think it's sort of an anti-pattern is they jump into their HTML and they think oh well I used apply to kind of solve that button problem maybe I can use it here too maybe i'll create like a destination card class and maybe this is like a destination card title and then they'll head over to their CSS and use apply and sort of build up all these styles the problem with this approach in my opinion is that this list of classes is only really one part of the duplication problem it's you know all of the different styles that are used but the thing is when you have this sort of complex component I'm you still have to worry about the structure and the elements so even if you can actually abstract away all this list of classes into reusable component classes you're still copying and pasting all this HTML everywhere if you decide ok actually this should be an h4 not an h3 and all these cards so you still have to go through every single place where you've pasted this HTML and update that so you've sort of only solved half the problem so I think a better way to solve this problem is to extract like an actual JavaScript component or even like a blade template partial so if already gone ahead and done that and I'll show you kind of the outcome so say we were doing it with view we could just kind of pull in like a destination card component here and just kind of bind in like the current destination from the loop right so we just like JSON and code this stuff and you know with any luck if you've done this right and I get rid of this div because that's not right you know everything's still the same and if we head over to this destination card component well now there's actually no pressure to extract any classes here because you still have a single source of truth for the list of utilities I can still change the border radius for everything just in one place and you can do this exact same thing with blade right so if you wanted to do this with blade blade has just like includes four partials right and the cool thing about includes is they're actually parameterizing so we could do like include you know partials destination card and you can actually just like pass through what should be in scope there so we can just say like destination it's cold up here my hands are struggling to type destination and if we did that right for no typos everything yes still shows up and now if we go over that you know blade partial again we can do like the same thing we can just like okay we want all the corners to be square now they're square we have that single source of truth so if you're using something like view or react you can extractive view or react component if you're just doing sort of a vanilla serve a rendered blade thing you can you can still apply the exact same principles so in general I think it's a better approach to solve these kind of component issues using real components I'm not trying to do it purely with CSS because you need to solve the HTML do Kayson problem - and when you solve the HTML duplication problem you actually have no CSS duplication problem left to solve it's not kind of the first thing that I think is important to keep in mind next one no sass no problem so a lot of people are super super accustomed to building their sites with pre-processors like sass or less and they're used to features like sort of like build time imports or nesting or variables and stuff like that and they don't want to like lose those features when they start using something like telling so I personally don't use sass or less or anything like that would tell and so I just wanted to show you a quick demo sort of what my workflow actually looks like so instead of using a preprocessor I just use post CSS so this is what my web pack mix file usually looks like so instead of like dot sass or anything I'm just using dump Oh CSS here's sort of my info file where I want to spit it out and then these are the three plugins that I use most commonly so post CSS import solves that sort of import problems so lets you kind of organize your files and structure them in you know however you want so if you go ahead and look at my till or my app does CSS file right now we kind of have it just using like the vanilla to--when way right I'll show you how I actually do this normally though I just have a bunch of import statements like this and I don't use like the at toe and stuff so now I have an import for tailwind base styles and import from my own custom global styles and import for tailwind components then an import for any of my own custom components then tones utilities then my own custom utilities that's sort of like the basic structure I use for every single project so now what I would do with this like button class for example is instead of putting it in this file I'll just head over to my awake components the CSS file and keep it in here and then everything works the same and and now you can break up your files and sort of organize them however you want kind of like you're used to with sass or less so the other plug-in that I use a lot is I don't once say a lot but I use it frequently is post ESS nested which handles sort of the nesting problem people like to nest things in SAS because it makes things sort of feel more contained and organized I'll show you a real-world use case of where I actually would use this with sewing so if we hand over to another URL here here is an example of a page where we're like rendering some markdown on screen all right so if we look at like the route you can see I just have some markdown content we're sending it to a view you can imagine a real project maybe this is like content someone typed into a CMS like rich text editor or something and the HTML that's generated when you compile markdown of course has no class attributes and telland is all utility classes so how do you actually style this stuff so the way that I do this is by creating a class that sort of targets all of the global selectors inside of it and it's sort of a scoped way and I'll show you the implementation here so if you head back over to our components CSS file got like a secret component here at the bottom this markdown component and all I'm doing is like setting up some basic typography Styles adding some space between each element and styling like the h1 styling the anchor tag styling the lists that sort of thing so now when we head back over to like the view I can just like drop this markdown class in and now we have some basic typography sauce so um this is the sort of situation I personally use nesting in and it's only really because it just it makes it feel kind of more organized right we know that we're trying to target stuff that's nested under this markdown class so this kind of mirrors the structure of the HTML a little bit better instead of just duplicating this prefix everywhere it just feels a little bit tidier pretty superficial you don't really need it but if you miss that nesting feature that's how I would do it I would pull in this post ESS nested plugin so the benefit of using post CSS for everything instead of SAS and then post CSS is everything is way faster because you're only running through your CSS and compiling it once and you're not sort of like mixing tools and there's some gotchas that you can run into when you're kind of combining things too so this makes the workflow nice and smooth alright next use SVG like it's going out of style so I use SVG for everything all the time so I'll show you some common use cases so the most common one is like doing icons right so here's like a couple storefront icons designed by my friends Eve down in the front row sub Steve so the cool thing about using inline SVG for stuff is that you can add classes to your SVG elements because they're just in your HTML and then you can use tellings classes to style them so here we're using the height and width utilities to just like set the icon to whatever size that we want right cool kind of convenient you can do the same thing with colors so here we're saying make the fill of the SVG match the current text color and then we just set the text color to change the color of the icon so this saves you from writing a bunch of weird custom CSS or exporting images with stuff baked into it or whatever it's just much nicer if you can just drop inline SVG N and then style it using that same design system API that you're using to style your HTML so real worlds kind of more cool use case I'm here's like a little search input and I think the way that a lot of people would build this is this icon they would they would implement it using like a before pseudo element or something to try and get a position and kind of bury all that information in the CSS hotel and the philosophy is kind of like your CSS is this sort of pure untouchable place as much as possible and your HTML is where you're actually building your UI that's where like you're actually putting stuff together so the way that I would build this is using an inline SVG for the magnifying glass and the cool thing about doing it this way is I can say okay I want the main find glass to match the current text color and then sort of in the wrapper element above I say okay well I want the default text color to be gray 600 but then whenever any element inside this div is focused using this focus within variant I want the text color of this div to change to blue so since this input is inside now whenever the input is focused the icon changes to blue and I was able to sort of compose all this behavior directly in the HTML without even having to go and write weird CSS and this is the sort of thing that I think at first glance you would almost immediately assume I have to write custom CSS to solve this problem because there's all this sort of dependencies between these elements but it turns out by sort of structuring things this way you can still do everything in the HTML which is really need another example so we had that splash page we were looking at right I'm say we wanted to kind of tweak it I had this cool sort of like diagonal slant to it again this is a sort of thing I think a lot of people were trying to implement with like before-and-after pseudo selectors I think it's cool that do this with that's Fiji instead so let's just kind of do it on the fly so I'm gonna head back to our home page here I will just look at this on like this large breakpoint it's a little small you can kind of get the idea I think it's more important that we see the code then the design here but maybe I can give us a little bit more room so I'll show you how I would actually build this so the important thing to think about or two to see here anyways is this as implemented using sort of two halves so this half is kind of all this content and then we've got this half over here which is where this giant image is so what I'm going to do is in the second half I'm just gonna create an SVG shape and overlay it on top of things so what I want to create is sort of like a parallelogram so we've got like a shape that's like kind of like this and I'm gonna Center that over the seam in between the two pieces so that it looks like we have this diagonal slice so here's like a fun little exercise we're just going to literally create an SVG image by hand by typing it out instead of like in sketch or something like that so I'm just gonna create an SVG I want it to be like stretchable by the browser so I'm gonna say preserve aspect ratio none and then we need to create like a canvas size using view box so since we're able to stretch it the easiest way to sort of draw the shape in terms of understanding of the coordinates it's just to make it a simple square so I'm just gonna make it a 100 pixel square which is nice and easy to understand okay so now what we want to do is create this actual parallelogram so I'm gonna create a polygon and then we need to define some points for the polygon so the first point is going to be in the middle at the top so that's gonna be 50 on the x-axis you're on the y-axis then we're gonna be all the way to the far corner so a hundred on the x-axis is you're on the y-axis then we're going to be at the bottom in the middle which is going to be 50 on the x-axis a hundred on the y-axis and then in the bottom left corner which is gonna be zero on the x-axis a hundred on the y-axis so I don't think we'll see anything right now but if we add some classes to this SVG will give an absolute position so we can actually just see it to start make sure that we kind of got the shape rain yeah okay and there's our sweet parallelogram so I'm gonna use incense y0 to kind of lock it to the height of the parent h fold just to be safe kind of see what that gets us okay so now it's kind of filling the right amount of space this background color here is BG gray 100 and we want to sort of blend in so let's do Phil Curran and then text gray 100 so we can set the color of this to match and now we have to kind of give it a size so right now it's way too wide right so why don't we give it a width of like 32 and that's gonna change kind of the angle too so that's getting closer and then to Center it we're just gonna use some negative left margin of half of the width so we'll do negative ml 16 and there we go now we have that kind of thing in place so like how much how much cooler is it to be able to just do that and your HTML instead of writing all this hockey CSS how many times have you like been trying to debug something and like then go through dev tools trying to find these weird elements and figure out what screwed up class it is and this is so much easier right it's like right there in the HTML it's weak it it's cool all right more don't be afraid to extend the framework all right so I get so many people opening issues on the repo saying oh how come you don't have this feature how come you don't have this feature and the thing is for every site there's always gonna be a thing or two that tell one doesn't support because either we didn't think about it or because maybe only your site needs it no one else's the site needs it so we sort of anticipated this and tried to build a framework to be extendable as possible and to sort of give people guidance on how we recommend extending it so I'm gonna show you how I would extend the framework today so let's pull up another example here I've got this drop down example so we just got this little like drop-down that opens right but it's kind of boring cuz it just kind of pops into place there's no like animation or anything now telling doesn't actually have any transition or animation classes built in because we haven't just really had the time to really figure out a great kind of generalized API for it so this is something that I end up kind of implementing myself and a lot of projects it's just kind of a way to test out what's kind of the nicest way to do it is so I'll show you all the classes that I created because we don't have time to just do everything from scratch and I'll just kind of explain it so the first thing to think about when you're extending toind is you don't want to just open your CSS file and write a bunch of like custom hyper project specific CSS you want to think like what is my design system missing and how can i build how can i sort of extend my api to include the things that i need to consume so in this case we need like some sort of like motion system some sort of positioning transformation system so the classes that I've added are not like very specific to this project it's just me trying to create like another set of generalized utilities that I can use in whatever way is useful to me so I want this drop-down to pop out of the right corner so I know I need to set the transform origin but instead of just adding the only one I needed which is this I do a little bit of investment up front and try to figure out okay what are all the things that I might need and put them all in at the same time same for like what properties do I want to transition I know in this case I wanted to be able to transition all but I thought you know what it's pretty common when I transition the color or the opacity that transforms separately so I'm gonna add all those at the same time you want to sort of like invest upfront to add everything that you need so that you don't have to keep coming back and editing the CSS because that kills like the whole workflow that we're trying to achieve same thing for transition speeds so I probably only need one or two for this particular animation but I invested some time into figuring out a good set of durations to add same for easing so I define a couple easing so I think will be useful and then I know I wanted to sort of grow as it sort of animates into place so instead of just adding the scale stuff that I needed I added I came up with a system like what's like a reasonable amount of values to have let's add them all so now I can consume them whenever necessary so I'll show you how I would do this so let's go to this drop-down example so let's add a transition component here we're using view because that's kind of a quickest and easiest way to do this and I thought a lot of people using laravel are comfortable with view so it seemed like a good choice now what a lot of people will do with view is they'll do like this transition name thing and you can do like name fade and then you have to create all these custom classes like fade enter leave fade interactive whatever there's a better way to do this when you're working with tail and that makes things a little bit more composable I'll show you how to do it so first let's add this origin top right class to the drop-down kind of content so it comes in from the right spots and now what we're gonna do here is instead of just giving it a name we're just gonna override what classes view uses so I'm gonna say enter active class leave active class enter class leave class enter to class and leave to class now kind of organize these nicely okay so when the animation is happening when it's entering what do we want to sort of be active so we we want to be able to transition everything so we're gonna say transition all because that's what we called it over here right we want it to maybe pop in pretty fast so maybe we'll go like transition fastest and we need to set like a speed so maybe we'll have it like ease out so it kind of slows down as it enters the screen now for leaving let's do transition all whoa cold fingers maybe we'll have it leave a little bit slower so we'll go with faster and we'll have this ease in which though contradictory in your head but we want the animation to like be slow at the beginning and fast at the end as it kind of pops out so enter class so what should the state of it be before it shows up well maybe we'll have it be invisible so opacity 0 I'm able to scale it down to like 75% and then at the end of the animation we'll have it be full opacity and like the full scale and then we'll do the opposite on leave so we'll start full opacity full-scale will transition to invisible and scale 75 so if we didn't screw this up should anime now yeah pretty cool and the cool thing about this is it's all composable right so if we want to change what properties were animating or change how it's working again we can do this all in our HTML we don't have to go write custom CSS to do it all right let's keep banging through this prefer inline styles to weird custom classes okay so here's another example of that home page we were working on but kind of a different treatment so we got this kind of image in a box and then we got this like blob behind it right beautiful blob designed by my beautiful friend Steve yeah so here's the blob it's like this sweet purple pork job so I think what a lot of people would do if they were trying to implement this is they would end up trying to create some weird class like here OBG pork job and write all these like weird CSS rules to kind of get it into place because this is 100% the sort of thing we're gonna be like top- 117 pixels right whatever right show you how I would do it instead so let's jump out to another URL here we'll go to the little blob URL and here's how I would do it so over in the blob I've got the SVG kind of here but just nothing done to it yet so when we drop it in we get this right which is I would say it's pretty close but it's not quite perfect yeah um so how I would solve this problem is I would literally just start adding in line styles so first I'm gonna do like style width let's make it match like the intrinsic width of the thing so 768 pixels and then maybe for top I might do like negative 110 pixels and then write like negative 150 pixels I don't know whatever it's arbitrary we're just gonna start with something pretty good actually I actually didn't know those numbers I just kind of I'm just so good but what I would literally do is I would just start like playing with this here and trying to get it looking kind of how I want you know what I mean until it's kind of right and again these are just weird values I wouldn't want these to leak into my design system because they're not really designed system values so I would just kind of fine-tune it here now you might be thinking well what if this needs to change different breakpoints right like maybe it like the small screen like this is like garbage you can't add media queries to analyze styles so what's the solution my solution is to just duplicate the whole thing and just hide it at different breakpoints so here maybe this one will be hidden on like large screens and up like this isn't gonna be perfect so you don't have time to like show every single variation but what kind of do it anyways and then large block so now we have two copies of it and we can sort of edit the one that appears on this screen independently from the other one so maybe we'll make this one smaller maybe this is like 380 pixels or something and okay and maybe it's not quite as like high off the screen and again I would just be like fine-tuning this by hand to try and like get something that I thought looked cool you know bring that down a bit maybe it's not quite as far off to the right so like 150 or something maybe it's like a hundred I don't know yeah like that looks pretty cool right and now when we jump back to like the other breakpoint what we still have like the other version of it instead so that's how I would kind of solve that problem again everything kind of focused in the HTML as much as you can all right last kind of thing I want to talk about removing unused classes with purged CSS so by default with sevenths if you do like a production builds and wait half an hour for it to compile you know this is like when you go and argue with people on Twitter about active record versus datamapper or whatever and then we head over to our public app does CSS file you'll see that the file Jim telling generates by default is like pretty aggressively large just like 360 kilobytes CSS file and the reason for this is because again tellen is designed to be this like API for your design system so it's supposed to contain everything you could ever need to your sight in reality you end up only using like 5% of the classes because maybe you do use like mt4 but you don't use like MD ml6 ever just by chance you it obviously makes sense to exist because it's part of your design system but you might not use that particular value in that specific case so the class kind of goes to waste so the solution to this is to use this awesome library called purge CSS that'll just remove any CSS you're not using so the easiest way to do this with toen since we only got 50 seconds here is to just require clarabelle mix purge CSS by our good friends at spotty how're you pass a company's name I don't know all of those guys but I'm from North America so so you just throw them in at the top then kind of add it at the end here and then if we do another production builds we'll see did you did you purchase the slows things down even more that's okay now our CSS file is only 6.7 kilobytes and gzipped it's 2 kilobytes and everything still works and looks the same all right so that's all I got into the talk the end thank you so much for checking out work on I hope you enjoy the hacker [Applause]
Info
Channel: StreamACon Streaming Conferences
Views: 64,402
Rating: undefined out of 5
Keywords: Laracon, Laravel, PHP, TailWindCss, CSS, Adam Wathan
Id: J_7_mnFSLDg
Channel Id: undefined
Length: 30min 54sec (1854 seconds)
Published: Thu Aug 08 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.