Tailwind CSS Tips, Tricks & Best Practices

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey there welcome to the ember Kampf 20 2010 CSS best practices training this training is usually held in person but because of the conference being cancelled it's actually online so we're actually fortunate in the sense that we can share with everyone now this training is going to be about kind of how to best use tailwind and the primitives it gives you you know if you're coming from a framework like bootstrap you might be used to having a lot more high level UI components kind of out of the box tailwind is lower level which is good and that gives you basically unlimited flexibility you can build kind of whatever UI on the web you can think of but it doesn't give you as much out of the box to get started right away so you know if we're using talen for the last two three years and and utility first CSS for about four years now we've learned a lot of kind of tips and tricks when it comes to building entire applications laying out UI components working with SVG's and the tailwind community has also come out with a lot of learnings and best practices over the last few years so this training is not an introduction to tailwind you will get the most out of it if you've already used tailwind and understand the basics of it but it's really more focused on some of the kind of tough lessons we've learned and the best ways to get the most out of the framework so that yeah you can be really effective with it so let's take a look at the repo here so in the training we're going to be going through a set of exercises in this repo this is open source repo here and I'll put a link to it in the video and this is just an ember app so all you need to do is basically clone it run your and install and then run yarn start or ember serve here and so once you do that I have it over here in our my editor right here it's running already you should visit localhost 4200 just like this and you'll get redirected to exercise one and if it looks like this kind of you should be ready to go now the readme here has kind of our basic outline so you can use this to follow along in reference after we're done and this is also just the readme file in the repository so if you want to open this right in the code you can follow along here as well so like I said you will get the most out of this if you've already used tailwind but just as a little quick refresher here let's just see kind of what it is like to work with tailwind so this training app right here is going to have all of our exercises and you can see right here you can you can kind of come over here and choose any one that you want or you can just use this to kind of go through the exercises as we work through the training so here are exercise one this is just going to give us a little playground to kind of play with kind of basic tailwind utilities here and to follow along you'll find in the app components directory this exercises folder and right here we'll have the exercise which is going to be shown on the left here in the training app and on the right we have kind of a solution so as we work through this we'll be changing the exercise and then you can reference kind of the final solution right there in that file so for this exercise let's say you know we wanted to make this HTML right here look like this styled HTML over here and so you know tailwind kind of whole philosophy is HTML first and the idea is that you stay in the HTML as much as possible hopefully completely you can really think of tailwind as a and the tailing classes as an API for your design system now in earlier versions of tailwind you were meant to have more control over your design system and and you would be customizing a lot more than you do today whereas today Taylan comes out with an extremely well thought-out set of utilities out-of-the-box and you really just think about hooking into those with your HTML so let's say we were looking at this design right here maybe our designer gave us and and we see okay the utility first here is a big bigger tech so we won't want to make that bigger so we just come up to here to h1 and we say text and then this kind of intellisense tail when plugin I have shows you all of these classes that you have from talen and this is kind of what I mean when I say tail one is really an API for your designs and if you come down here see these are all of the font sizes that come with tail end so maybe we would just say this is 2 XL font and there you see it gets bigger and it looks bold as well so we can say font let's just try bold here and it looks like it's it's centered as well and it looks like this whole article here is kind of constrained there's a there's some padding around this article so maybe we would add a div around this entire thing here and add some padding and these little P - number utilities are what give us some padding here and the background there is a shade of blue so on this outer div let's go ahead and make the background blue and here you can see all the Blues that come with a tailwind right here that looks like it's the right color and then maybe the article has a background of white and it looks like it has some padding here as well and again I'm just going through this kind of quick just so you can get a sense of what it's like to use tailwind if you aren't super familiar with it we have some rounded utilities here we can used to add a board radius we can add a little bit of margin top here to push this article down so starting to look pretty good and we can add some margin on these paragraph tags maybe eight on this first one looks like the text might be a little bit bigger actually so let's go to for Excel and maybe this next paragraph tag here has some more margin and this list we will give it as well and let's go ahead and add some margin to each one of these paragraph tags right here so this is another thing you'll notice and what we're going to be talking one of the things we'll be talking about is you know if you come from writing your own CSS and every app you do or every blog post you style you might add some global rules here but again tailwinds whole workflow is really kind of like what i'm doing right here which is staying in your HTML keeping all the styling kind of local in a sense it's using these global styles that are already available to us I think this one's called list yeah list disk here so we can get these bullet points in the list and then let's add a little bit of padding here on the left maybe a little bit more for six kind of like this so I'm just playing here again you don't have to follow me exactly and you have the solution there but basically you can see how this is kind of working and maybe we can add an overflow I don't know if this will work overflow why Auto something like that and maybe maybe a height full here but anyways you kind of get the gist here of how this is working and so you know we've been able to style this whole thing maybe add a little bit more padding here using just these classes looks like the color here might be a little bit off black so it's not pure black so we can just go ahead and set the color to maybe gray 700 and so the benefit is you get this this workflow where you are just not writing any new CSS you're staying in the HTML but of course there's some trade-offs as well and so for example here adding margins to every single one of our paragraphs seems like it might be a hard thing to maintain consistently throughout an entire application so these are some of the sorts of questions we'll be addressing in this training but basically the point with this exercise is just to kind of reinforce this notion that tailwind is HTML first the workflow kind of embraces HTML it embraces that this is like the core part of the rendering of our application and so it just says let's hook right into it and not kind of break our flow going to another file or having to kind of tweak certain specific values we're just going to use this constrained set of styles at tail and provides to us and again it's pretty incredible if you haven't used to when extensively how far the default set of utilities can get you in styling a completely custom application and so when it comes to building our own abstractions and using tail and effectively with other tools like ember like a front-end framework we want to stay aligned with this philosophy embrace this idea of staying in the HTML and we'll see kind of Webster actions that leads us to create so if we go ahead and switch over to exercise 2 let's talk about this first point which is that we want to extract components not classes so again when we're working in a framework like ember we have a great primitive available to us which is a Ember component and that's a great way to reuse HTML so this exercise right here we see kind of these two card treatments and on the right is the final version and left is kind of our exercise and you'll notice that this picture on the right it looks it looks good when we resize it that's because the container has a fixed aspect ratio based on the contents of the image here and so as we resize it it doesn't change let's come over and take a look at that code here in exercise 2 and here we see kind of our image right here and then the lorem ipsum text is in this div right here and so the question is we want to make this image right here kind of preserve its aspect ratio so the way we can do this first kind of has nothing to do with with tail and or with ember it's just a little CSS trick that is really handy to know so the way we would do this is go ahead and wrap this image tag in a div and it uses this trick in CSS that percentage padding is based on the width of the immediate parent the container right here so if we use some of these padding-bottom utilities right here we have the kind of spacing scale from tailwind with these numbers but then if we go down we have a bunch of ratios as well and so let's say we were to go ahead and add this padding bottom of 75% padding bottom three fours if I save this and check out the code we're gonna see that this div has taken up this space right here and let's go ahead and make it red just so we can kind of see this div so this is adding a padding of kind of 3/4 of the widths of the container and you'll see if I shrink this that the the aspect ratio here stays the same similarly if we were to say padding bottom is full so a hundred percent we should get a perfect square right here that stays the same as I resize this window so that's kind of the the overall trick with this fixed aspect ratio component here now in order to get the image to position itself within this div which is now kind of a fixed aspect ratio we can go ahead and make this image absolutely positioned but we want it relative to that div right here so we need to actually set a position of relative on this div so that it uses this as its positioning parent and so now you know if we were to pop open the inspector here and just make this let's say opacity 50% you can see that this image is positioned within this parent div right here and the last thing we can do is make it fill in the whole space another really cool workflow tip here with tail 1 is to use these dev tools in this class list right here inspector this is gonna let us quickly add and remove classes just here in the dev tools and kind of see immediate feedback and I use this all the time when I'm building apps with tailwind so what if we were to give and I have this image selected right now so it's right here it's selected and so we can see that the image already has this h28 which is a fixed height right here it has object cover and this class controls kind of how it resizes if the image dimensions don't match up with the native image dimensions and then it already has a width of full right here so let's just uncheck these so we can kind of get a good understanding of how this absolute positioning is working so right now we have the the image absolutely positioned in the parent we want it to take up the full parent because that's that's what's controlling the ultimate display here so if we were to make it full width and full height like this the image does take up the full parent but now it's kind of distorted so we could go ahead and add this object cover back and we'll see that the image will retain its original dimensions and we'll just crop off whichever dimension kind of overhangs here similarly we could use the object contain if we wanted to make sure that the picture could be seen in its entirety and then we could maybe use some black bars or something like that to show outside but for our cases we want to use the cover utility here so that we always fill up the parent so now if we come back to the parent here we can see we have this padding bottom of a hundred percent and we can see here if we were to try some different padding values let's say 2/3 2/3 looks pretty good for this picture so now we basically have this behavior that we have in the solution here so let's come back and add the padding bottom of 2/3 as well as the full width and height through our image so padding bottom 2/3 we already have the width full and we'll just remove this hard-coded height and make it height full here and so now we have this fixed image right here so that's pretty cool it's a really nice technique to use if you want to maintain the aspect ratio and also when you first load a page as the image is loading the height is already known so the content won't reflow so this is like a really useful CSS trick to have in your code base and now if you're used to normally working with kind of CSS files or just custom CSS that you write yourself you might think that a good way to extract this behavior and share it is with a custom CSS class and in fact other CSS frameworks have classes for fixed aspect ratios like this because it would be a lot of details to remember you know every time I need a parent with the padding bottom and relative and then I have this absolute it's kind of hard to reuse if we have to repeat all of these classes so again you might be tempted to do something like well let's go ahead and make a aspect ratio container class and then we'll have an aspect ratio child class here and then maybe we can have something like a 16 by 9 aspect ratio or a 1 by 1 for a square things like that the problem with this approach is that you know it really kind of breaks up our flow we have to go start writing custom CSS and we end up just introducing a new way to add styling to our application where so far it's nice that we've been able to stay in HTML and just hook in to tail and utilities so because we are using a front-end framework like like ember components are actually the perfect way to reuse some of this behavior even if it's just styling even if you would normally think I'd only make you know an ember component to share JavaScript behavior it's actually a great way to reuse both CSS and HTML as well because as you'll notice from this problem that we're working on it's not just the Styles that we need to share we actually have some structure to share as well so this is why ember components are such a great solution for this problem of how to share this fixed aspect ratio behavior so let's go ahead and generate a new component and I'm just going to call it aspect ratio and so now we have this new aspect ratio component right down here and so far it's just kind of an empty template that just yields out so let's think how we might abstract this well if I could just drop an aspect ratio component right here maybe pass in ratio as an argument and then go ahead and pass in the ratio maybe it was something like 16 : 9 I think that's pretty clear that that's like a 16:9 aspect ratio which you know you would see from a movie or a most videos on the internet and then whatever is kind of in the contents here we would just be able to position this thing however we wanted to so let's see what this might look like I'm just gonna grab this HTML right here and paste this in our aspect ratio component and so this parent is going to be relative it's gonna have the padding we'll leave this as 2/3 right now and then inside instead of having an image here let's just make a div that is absolute and it's full width and full height now with absolute positioning we can actually use another little trick here we can use the inset utility to go ahead and set the top right bottom and left of this div it's just another little way to kind of say go ahead and fill in your parent so if we save this aspect ratio component and we come up here and save this and we come and take a look we'll see that now we have the relative there's the absolute and it's the same dimensions and there's our image okay so far so good now let's make it so that our aspect ratio component can actually I use the ratio that was passed in so for this we'll need a JavaScript class so we'll go ahead and generate a component class for our aspect ratio component and basically what we want to do here is instead of hard-coding this padding bottom of 2/3 we're gonna want to say the style here is just padding bottom and then whatever percentage we end up calculating based on this ratio right here so let's make this a new property called style on our component just like that and so here we'll have a new getter called style this ratio argument we can get from this args ratio and we can split that on the colon and then we want to divide so in the case of 16:9 right here we want to take 9 over 16 and we get 50 6.25 so if we multiply that by 100 we get 50 6.25% so let's just hard code that and see this working if we were to return padding bottom of 50 6.25% here and save that well let's take a look at our Dom looks like our image is kind of cutting things off but it does look like the container here is sized correctly so if we were to hide this image we can see that our container does look to be sixteen by nine so it's giving us the right container and it's still up to us with this image child here to say let's go ahead and make this height full with full and then we can say we want this to cover this so let's slap these classes on our image here and now we have this wider image so to finish this off after we split the ratio by colon we'll have 16 and 9 we just need to divide them we can use reduce here to take the first and second numbers and basically we just want to return the second over the first so in the case of 16 by 9 we want to calculate 9/16 to get that 50 6.25% so that's going to be our actual padding and then we want to return padding bottom padding times 100 to get into percentage terms so back in our app here we should be able to change this to let's say 1 to 1 and now we have a square and we can use you know the other object properties to say you know let's put this on the left or let's put it on the right so this is kind of showing you how you can still use tailwind to compose in our UIs we have the responsibility of maintaining this fixed aspect ratio up here in our aspect ratio component but then our children our child here the image tag is kind of able to do whatever it wants with that space so maybe now that we're we're narrow what if we were really narrow I was like 25 to 9:00 and we want to just show the bottom we can do that and so now we have this you know HTML approach here and of course we don't even have to put an image in here what if we wanted to just do some text hello world and what if we wanted to Center this so we could do something like wrap this in a Flex that's height full width item Center and justify Center and we can make this thing background gray of a hundred and so again we can make this a 16:9 again and it's really up to us how to use this this space so this is kind of something that took me a little bit of time to get used to when working with day one but has proved to be such a vastly superior way to build UIs because you never get it makes it much harder get stuck into a bad abstraction you can imagine here trying to come up with something you know way more high-level like a you know a fixed ratio image and it takes in a source and it kind of basically gives you a new API for all of these things but as I've used to and more and more I've gotten more comfortable with with with keeping my abstractions lower level like this because you're gonna get way more reuse out of this aspect ratio component now that it basically doesn't care what is being rendered inside of it it really is just about providing this fixed wrapper here and calculating the aspect ratio so when you see folks in the table and community say things like you should extract components not styles this is exactly what we're talking about so let's move on to exercise three so here we have some nested routes we can see we're at the URL exercise 3 - child 1 child 2 and child 3 and over here you can see in the final result that we have some active styles so if we come over to exercise three it says let's add the text and it goes 600 and border indigo 500 as the active class arc so you might see this an ember or I even see this in Gatsby basically a lot of frameworks have this sort of API where you have a link that lets you link to you know internal client rendered URLs here they take in the name of the route and then this is a normal class attribute but we can also pass in something like an active class argument and so if I were to grab these classes here and paste them in and go ahead and do this to both of these other links as well every time this class is active ember is going to go ahead and apply these classes so this is a nice API you know it's very tailwind friendly because talen is all about using classes in our HTML but you'll notice we have a problem here actually and that is that our hover styles are colliding with our active styles whereas in the final version over here they don't and so you'll run into this from time to time where we have this class argument and so we have over here hover text gray just go ahead and wrap views and this is always being applied since it's our static class attribute and then when the class is active we get text indigo 600 and the hover class is basically taking precedence over that indigo class but we don't want that when the link is active so what we really would want here ideally is to say something like inactive class and when the class is inactive then we want to go ahead and add these hover styles like this and also we want to make it grey and that way you know we're just composing these utilities and we're not trying to fight over you know which version wins we have text gray 500 and text gray indigo 600 on these links down here and it just so happens that it looks right but when we hover it doesn't so you know ideally we want to come up with very tail and friendly api's like this so what might we do here well this is a the great use case for creating another component that is just a very light low-level wrapper around linked to that gives us this API so let's go ahead and make this so we're just going to generate another component and we're just going to call it link and we're going to need a JavaScript file as well so I'll just go ahead and create a link j/s right here and start out with an empty component so for link and I'll bring these down here we basically want to wrap the native link to right here so we'll paste this in will yield this and we'll make this one up here a link so we pass a long route so we can pass along route right here like this this is the route argument that's being passed in from our calling template now for class since class is an attribute we can just say dot dot dot attributes and if we go ahead and remove these two for now and just take a look at this we'll see that some of these styles are still being applied here because we have passed that attributes through except for these two right here since we're not doing anything with those yet so in octane this is how you can afford any HTML attributes from the calling site to the underlying HTML tag so that's how we can ford-class and so now let's take care active class so active class is also going to be an argument so we'll just pass that on through active class equals active class and now this should turn into go when we when it's active and it does and so now we need to take care of the inactive class API that we want to add to our link component and for this we'll come over to our JavaScript here and we're going to need to use the routing service so we want to go ahead and inject the router here so let's import inject here from member service we'll call that service here and now we basically need a new property to tell us whether this link is active or not so we'll go ahead and define an is active getter here let's just drop it the bugger and then over here in our template we'll just say if this is active go ahead and output a little active label right here so if we come back to our app pop open the console here and reload we should have access to this dot router and the router has a current URL property which tells us what the current URL is and it also has a URL for method here that takes in the name of route so if we were to call this darkstar out we can calculate what the route is for this link so basically if this dot router dot current URL starts with this router URL for this dot args dot route then we know that this link is active so now if we check out our app we'll see we get a little active label here when our first link is active so we know that property is working and so to finish this off what we really want to do here is toggle between the class lists based on whether our link is active or not so instead of using active class we can just use class right here and say if this dot is active we want to pass in our active class from the argument else we want to pass in our inactive class argument and class is actually a concatenated property so so this class will append itself to any classes that are applied through the splat tributes here and we can go ahead and get rid of this label right here so now if we save this we see our active class is being applied but when we we don't see anything and then when we go off we see the hover class as well so there we have basically fixed our bug whereas over here we're still using the old API and we can see the bug so now we should be able to just come up here replace all these link twos with links and I'll just grab this class right here and use this one as well because we know we want that for the static class list and then I'll grab the inactive class as well and paste it in just like that and it looks like these last two had some margin left on them as well so margin left eight right here so there we go we fixed the issue and now we're not having to worry about classes clashing with each other and again I've basically run into this problem with a you know almost every front-end framework that I've used and so kind of embracing these lower level components coming up with this API here you know again we could have opted for a much higher level component that did a lot of this work for us but just by building this very simple link component that just kind of does this one aspect of what we need it to we see that we've kept a lot of flexibility when it comes to building our UI even right here we can go ahead and apply a margin left of eight to these latter two links and and just not this first one and we weren't hit with any kind of unnecessary abstractions that didn't work out for our use case here but now we have this really tailwind friendly API in active class an active class and again this just kind of goes back to this idea of embracing the workflow so that folks who use your components and api's can stay in in HTML land and not run into conflicts now of course if you didn't want to repeat this class list right here for each one of these Navs and let's say that this was you know a page header nav in your ember app that you were using on many pages what I would do here is wrap this up into kind of another higher level component which would be something like you know a page link or something like this right and this would basically render a link but it would just take in a label and a route maybe but it would go ahead and use the link that we just created passing in these lists of classes right here to reproduce this UI so this is kind of how you can stack these different components to reduce some of the duplication and ensure that developers are using your style components consistently throughout your application okay so let's get away from some of these components and talk a little bit about layout with tail end so in exercise 4 we have kind of this button group right here and right now it's kind of left aligned and over here the final solution shows up being centered so let's come check out the code for this exercise so the button group here is laid out using kind of this old-school float technique where the parent is inline block and each one of these buttons is a float left now you're probably not using floats as much in your layout code anymore but again for me when I started using you know first tachyons and then tailwind learning about different layout techniques this was basically how I learned about these techniques was through using these utility libraries and originally building some one like this floats would be just fine but you start to learn there's some pretty funky things about CSS so if we wanted to achieve kind of this final result over here where this button group is centered how would we do it well right here this parent is an inline block so we see it has this width of 221 it's just based on the width of its children right but because it is inline we can come here to the parent come over here and look at the Styles tab and use text Center right so tech center on the parent will Center any inline elements that are children but as you do more and more app UI development there's a lot of inconsistencies between how you think and layout inline elements and block elements and if you just take a step back here the fact that we're adding in class call Tech Center which is just setting the text align property CSS property on this div to layout a button group is a little strange I mean we're not centering text we're just trying to Center this UI element and so in particular flex box ends up being something that you become very familiar with when you use tailwind because it's just extremely powerful and the utilities let you work with it very very easily so the way I would lay something like this out today would be let's go ahead and get rid of these floats as well as this inline block parent and come back and take a look at this now we're gonna see over here that there's some space between the buttons right now this is basically just a div with some rounding in a shadow and then we have three buttons here the spacing is coming from just a significant whitespace in our template and then we have this shadow on the parent so clearly we have kind of a layout issue going on right now so fluxbox was gonna help us out we can go ahead and grab this parent turn into a Flex parent with Flex and right away we're gonna see that all these children kind of snap into place and flex box is really about laying out children of different widths kind of having this behavior of them snapping into place and then describing what happens kind of when they wrap but you can see already just for basic situations here this is just so powerful right we just added a flex on the parent the buttons we didn't have to float them or change anything about them and right there we have some control now by default we are using the Flex row direction that's just a default property in CSS Taylan also gives us this flex column CSS property which changes the direction to column so you can imagine a situation maybe you're doing a vertical now where that would be useful but in this case flex row works out great for us and then the last bit here is that because we have in this UI component the shadow being applied to the parent here so it goes around all three buttons we can see it's overhanging right now because this div is taking up the full width so by default flex is going to be display flex but we also actually have an inline flex right here which again is going to make this an inline element similar to how inline-block makes it an inline block element and so with just the inline flex class we're back to having this look just about right so we can go ahead and add that to our HTML and it looks good and we could come back and do the same thing here where we grab this parent and if we were to add text Center it will Center it because this is an inline element but again we kind of want to move away from this and we can't want to use these great CSS primitives we have that are specifically for layout like flexbox so how would we think about doing this to Center this with Flex box well again like I said as I've used to when more and more I've gotten way more comfortable with small bits of my template kind of taking one piece of responsibility on at a time so in this case you know I look at this div right here and these three buttons this is really kind of one UI component this is really you know our button group component right here and I think it's nice that we can just render this button group and it just kind of does its thing and naturally by default lays out to the top and left of the parent it doesn't do anything special and that gives us more control and so when it comes to laying things out a lot of times I'll just make a new div just for the purpose of laying things out or what eventually might become another component to lay things out and we saw we could add text center here but we can also use flex here on this parent to lay this out so let's come back to our inspector let's go ahead and grab this parent right here and I'm gonna make it a flex parent as well and so from the perspective of this parent it kind of has this one child whose width is you know 221 right there and so if I am a flex parent well now I can lay out my children with the items utilities as well as the justify utilities and the justified utilities are gonna apply along the main axis here and so because by default we are flex row justify will determine whether the children are at the beginning middle or end of the row and so so right here you can see you know these are all affected the layout of this button group I can say justify:center to put it right in the center of the page I can say end to put it right at the end or start to put it at the beginning so in this case we want a center here and I'm just gonna make this a little bit bigger so we have some more room and just like that the button group is kind of laid out by Center so again just adding a flex and a justify Center right here is enough to layout anything that is a child in the center of this parent which just happens that this is a button group right here but as you practice with this more and more you'll just get comfortable reusing this pattern throughout your application and so again this is just kind of to point out you will get very good with flexbox as you use tailing more and more and it's pretty neat to see this work with two button groups we could just go ahead and duplicate this and now our Flex parent here has two children we can see when we're centered over here it's just kind of putting these next to each other right in the center but if we were to take that off we can look at some of these other justify options we can put space around we can put space between push them to the edges I use this one a lot when I'm building navigation where you kind of have part of the nav on the top left and then the top right part you want push to the right we can put them both at the end or we can put them at the beginning so flexbox is just really really cool definitely something you want to get familiar with let's go ahead and delete this actually let's leave that second group and just say let's go ahead and justify between kind of like the way that looked so that's the basics of flexbox you know we haven't even pulled up the docs yet in this course because I do have this really handy plug-in and I've used to enough to know it and this is honestly it kind of how I work I usually just stay right here my code just because of this excellent plug-in but I do find myself from time to time using tailwind Doc's of course the docs are great here and so especially if you're learning about something new like flexbox you can find it over here in the side here's all the different properties or you can just press slash and search for flex and see all the rules right here so let's go ahead and jump over to exercise 5 where you're going to kind of have a little layout challenge so if we open up exercise 5 and go to the exercise this is what we see and if we look at the behavior of the solution we definitely see kind of a different layout right here over here in our exercise we just have you know an image and then we have this div with this text right here kind of all on top of each other whereas over here on the right the image is on the left and the copy is over here on the right also you'll notice if I grab this and resize this the text flows over there and if we get too small on the left hand side the image starts to shrink but in the right hand side the image kind of stays the same so for that you're going to want to look at the Flex grow and flex shrink utilities here to see how to reproduce that behavior over in the exercise so for this part go ahead and pause the video try to get the left hand side of exercise 5 looking and behaving like the right hand side using these flex box utilities see how far you get and I'll see you after you give it a shot alright welcome back let's compare our work so when I think about laying out something like this I like to break it up into you know different pieces and so right here because this is really just it's more or less like a two column layout and we see the right column which is holding the text is kind of resizing Andry flowing the text whereas the left for the image there it's kind of staying fixed so this is really like there's there's kind of a parent flex box right here this is kind of one child the image and then this is kind of the other child right here so that's kind of how I would first approach this so let's come back to the code and here we can already seen the markup we have the image and then we have kind of this div right here wrapping these bits of content so I think we should be able to just make this guy a flex and because flex is Rho by default we're gonna get the image right here and then the copy right here so that's a good start now we see that there's some weird stuff going on here when we change this the the image is growing and that's because by default flex children are gonna expand to fill their their container and so as the text wraps it actually makes the parent taller and the image is going to fill that height as well but we don't actually want that to happen so an another trick is a lot of times especially when dealing with images because of just unique ways that the browsers will choose to kind of position them sometimes it really helps to go ahead and add a div so that the Flex child is a div it's more of like a layout element and not the actual content you're laying out and sometimes I can make things work a lot more predictably so if we were to just add that lets see kind of what the behavior is okay well now the image has shrunk down a bunch but it does look like it's not kind of getting distorted like it was before so it seems like we might be a little bit closer here but if we look over in the solution we see that you know the image is kind of taking up its own space and really that the text is the only thing that's being resized so over here in the docs you might have found the Flex shrink documentation which controls how Flex items shrink and so we have flex shrink which allows an item to shrink if needed and then we have flex shrink zero which prevents an item from shrinking and again looking at this layout that kind of sounds like what we're looking for so if we were to go ahead and add a flex shrink zero to this this flex child right here and save it well now we can see that you know it's not going to shrink even when we run out of space so that's kind of a behavior that we were looking for now we see a little bit of gap right here between these two children and the easiest way to deal with that in Flex box is to just go ahead and add some margin here so if we add some margin left using an eighth value here maybe it looks a little bit less maybe six then I think we've kind of recreated this layout okay one more with Flex box just because I love it so much there's so many neat things you can do with it and I want to make sure you're aware of all the ways all the problems that can solve with layout and with CSS so here we kind of have a blog post and if we zoom out a little bit we'll basically see that the solution over here is has this fixed width aspect to it the text is has a certain measure to it whereas over here on the left the text is not constrained at all and so in typography there's this idea that there's an ideal number of characters per line to help readability and so it's a really good idea in your UI is to constrain your text in a certain way so let's come and open exercise 6 here in our project and we'll see that we have a little bit of markup with some tail and classes and and that's what's styling our content over here now with constraining the width you know you might be tempted to go ahead and add kind of a max width on the parent so let's pop open the inspector here and we'll see we already have this article element wrapping the entire thing and talen gives us these max with classes so we can say let's do a max width of let's say medium and so now the article is constrained here so we can see the text is much more readable and then we can say let's go ahead and say M X Auto so that the margins are Auto and now this is kind of measured and centered but sometimes you'll have treatments like this where the the image should be kind of full bleed and if the parent is constrained well that makes it pretty hard okay so what if instead we were to apply the max width to each one of these paragraphs so this first paragraph right here let's just add a max width of medium to it and so that kind of makes sense that this this class right here would be on this paragraph text because it really knows best about how to make this paragraph text readable you know in the same way that paragraph chooses its own size and font weight and color having this measure be embedded within the paragraph is something that is a really elegant solution to this problem in a lot of ways so let's say that this was good and we like this let's go ahead and grab these other paragraphs and throw a max with the medium on them so then the question becomes well how can we Center them and if we open up the inspector and look well the paragraph does have the max width so we could come here and add an M X of auto to Center it but that kind of feels like we're starting to mix layout concerns with the actual paragraph of text right here and again as we've seen a lot of times it's much much better to try to separate these two things even if it means adding a wrapper or something like that well fortunately with with flexbox we don't have to worry about that we can actually just come up here to the article make the article a flex parent and we see by default the row is not going to be what we want right here so we'll go ahead and make it a flex call and so now we're kind of back to just having the parent lay the children out in a single column remember we have the align items and the justify content classes to help us layout flexbox children here and the justify classes work along the main axis so because this is flex column the justify classes are gonna affect how the content is laid out vertically we don't care about that it's laid out fine vertically what we care about is kind of left and right the horizontal axis here so we want to use the align items utilities so if we go ahead and take a look at these and we scroll through well now we see that these are in effect exactly how those children are laid out and because the children are fixed with the parent is able to Center them just by using item Center so this is really cool and I was really excited when I first kind of found this trick out flex flex call item Center because what does it mean well it means that you can use these paragraphs of text with this class list here and not have to worry about whether they're going to be laid out to the left or to the right and you see this a lot when you're building marketing pages so if you wanted to reuse this kind of text treatment throughout your site we can go ahead and generate a component it's gonna be a text component I'm just gonna grab this right here come down to our new text component paste this in and I'll just replace this with text and it's just like before so this means we can replace all these with text we have a super easy way to reuse these Styles right here say if we're writing kind of some longer form content like this but our parent still has total control over how it's laying these out so I thought this was really neat and just goes to show how powerful Flex box is and letting you you know put these responsibilities together like the measure of a text which is going to change based on the font size so you could imagine having this max would be dynamic based on the text size of the text component here but still giving the parent control over layout so just another really powerful technique okay if flex box wasn't cool enough we now have CSS grid and CSS grid utilities in recent versions of tailwind so let's take a quick look at that so over here on the right we have these three cards kind of laid out like this and on the Left we see them just stacked like this and if we make this smaller we can see on responsive screens the right hand side does stack with the spacing in between before laying them out kind of in this three column grid so you can totally build this with Flex box and it is good to understand how you might do that so let's pop open exercise seven here and here we kind of see our three cards just like that so we can make this a Flex and that should lay them out like this and then we basically want this three column grid so the way you would do this in Flex box let's go ahead and wrap each card with a new div that has a width of 1/3 and I can't type 1/3 and Emmet here because it doesn't like that so I just always do this and then do it like that so now we have a Flex parent and we kind of have these three children with one third with one third with one third just like that so now we see kind of all the cards are filling up the total space of the parent in this kind of three column grid treatment but over here we have kind of these gutters and the trick for doing this with Flex box and tailwind and you can actually find this in the docks but I'll just show you real quick is for each one of these column elements right here let's just add some padding in the x-direction so let's say padding X of three so there we see it adds some padding but note that it also removed the side from right here so these do have gutters now but they're no longer actually filling up the parent and that's because they each have padding on both the left and the right the way to fix this is to account for this padding of three by adding negative margin in the X direction of three on the parent so you can see here when I toggle this it kind of gives us back that room and you can see the left-hand side now lines up with the text over here so if we were to add negative em X three right here we now have this kind of treatment so that works but it's a little bit of a pain in the butt and if we were to go ahead and make this small again you know now we have to change our markup so let's say on small screens we have flex column and then on larger screens we use flex row and so this should make it a column on smaller screens and then and then back to our normal layout here but you can see kind of our whole layout is messed up here because we are adding these gutters in the x-direction now that we're on small screens we'll have to add them in the y-direction so we'd have to come back and update all this so this is kind of how working with flexbox to do grid treatments is a little bit of a pain so let's go ahead and undo all this will even undo the wrappers and bring us back to just this kind of raw markup and instead we're gonna use grid to make a three column grid so I'm gonna type in grid and grid calls three and right here you can see kind of all these utilities that come with tailwind and just like that we have a three column grid we didn't have to do anything to the children but the Mike drop here really is this gap property so gap three just like that we have a gap looks like the gap is a little bit more so let's make it six or five so gap is automatically going to apply spacing in between the elements here and this is really cool we got three columns on large screens let's go ahead and start with a one column calls one and then on large bump it up to three look at that we have a one column grid on mobile screens the gap property is is still applying just in between and once we get to big screens we have the three column layout so needless to say if you're using grids in your layouts and you need gutters and you need to change these things responsibly CSS grid is an absolute game changer so go ahead and switch over to exercise eight you're going to see this kind of details this data layout here and on the right hand side we have this kind of to up treatment but once we get down to smaller screens we see all these things stacked but basically once we get up to the large screens here we see that the label is in the left and then the data is over here in the right so if you come back to your code and open up exercise eight you'll see some instructions go ahead and add a grid on large screens hint it's a three column grid and you can also look up the grid column start and end section in the tail and docks and this is going to give you access to some classes you'll need in order to reproduce this layout so go ahead and pause the video and see if you can recreate the solution over here in your own code base see how you did so if we come over to the template here we see that we're kind of iterating over the items and so I think on large screens we just want to turn this into a grid that has three columns so we'll add grid and grid calls three okay so it looks like we do have three columns but this text doesn't look quite right one really cool thing about grid is if you use the inspector you'll kind of see the actual grid and how its laid out so this is really really neat and basically here we want these last two spots in the grid to be reserved for this content right here and so by default grid is gonna give each child kind of one section one column or row based on how its laid out but over here for kind of a second column we want this to take a span of two and that's the class that you would have needed to define you know if you look here in the docs at grid column star end you'll see that's kind of how you span different columns or rows so if we were to save this come back and look at our work now we see that these spans both of these columns right here so that's pretty neat and again we can see right here this kind of gets right up on this and so maybe we want to add some gap between these two simple enough large gap three or six so again hopefully you can see kind of just how powerful gap is it really is a super powerful tool for laying out your UI components and I think the tail-end utilities do a really great job of keeping it super simple and approachable okay all right let's talk about a few more tips and tricks with tail end so an exercise 9 and we're going to be looking at working with SVG's and this is something else that really tail when taught me the whole the whole workflow is how to think about laying this out and a lot of times you know you might see these kind of before pseudo elements if you want to get you know something like this treatment right here with an icon in the input tag or an SVG as a background or just SVG is going to use throughout your UI even right here you can see in the app I have some right here and again the tail in perspective of staying in the HTML even applies to SVG so you'll you'll kind of be surprised how easy it is to work with SVG's if you just treat them like every other HTML element so let's say we wanted to add this little email icon to our input just like this well the first step is to basically get the raw SVG and you know you're probably using an icon library or icon set in your project somewhere but when it comes to doing kind of custom layouts like this it's really best to be working with this kind of underlying raw SVG element a good resource to get some is a hero icons dev which actually comes from the creators of tailwind these are all free and this is a cool little Explorer you can use to just find an icon click on it and and it copies it for you can bring it right in your project so let's say we already had this icon picked out and it's right here so this is an SVG icon it's gonna look like this we want it to the left of our input right here so let's just come down within this div and paste it in so it looks a little bit big but if we go ahead and select this we see that it is in fact right next to our input but you can see from the solution it really just needs to kind of hug the left side of this border here and that border is coming from the shadow on this parent div so just like we used absolute positioning earlier we can actually use that directly on the SVG element right here so if we were to make this absolute we can see it takes it out of the flow right there but the top left of the SVG is actually bound to the top left of that div whoops I lost my class so the positioning is actually correct it's just the sizing that's wrong so how can we sighs this SVG well the easiest way is to just use tailwinds width and height utilities so let's say we want it to be width of five we can kind of zoom in here and see that looks pretty good and most icons are gonna have the same width and height that's just kind of how they're designed and you can see that width five turns out to be 20 pixels on the screen and so that's gonna be a 20 by 20 SVG icon so the orientation is right the size is right but we actually want it vertically aligned here and again flexbox is going to come to our rescue here we don't want to deal with vertical alignment and trying to figure out whether this should be in line or block we're just going to go ahead and wrap this in a div that is specifically for positioning this SVG icon to make our lives a lot easier so let's go ahead and throw these classes on here we know we want this to width to be 5 and height to be 5 and we'll just leave that alone for now and let's just work on this kind of wrapping did that we're going to use to help us position so this is going to be the thing that gets an absolute position right here and if we could find this in our markup we really want this to be kind of the height of the parent and that way when it gets its child who's gonna be with a five it'll take up that much width the height will be full and again because we're using absolute it's a little bit more expressive I think to use these inset why utilities which are gonna set the top and bottom to zero so let's go ahead and make this inset y0 which is going to make it hug the top and bottom of its parent and absolute and then let's go ahead and stick this SVG right back in there so now we've got the SVG it's still 20 by 20 we can zoom in a little bit we've got this parent who's laid out like this and let's use flexbox to Center this so we'll make this flex and if we drop items Center it should vertically Center it just like that so flex item Center right on the parent let's add a little bit of padding to push this over and then on the input we can add some padding as well and that way when we type we don't kind of cover this icon here so this will get padding left of three and then we'll come down on the input and drop a padding left of ten and this is starting to look much closer now the next thing you'll know here is our color of our icon and this is blue right now and it's coming from this fill property on this path element so a lot of times when you get SVG's different parts of the SVG's will have either fills or stroke color applied to them and again to kind of think in terms of tailwind and composition and reuse the best way to deal with this is in this case we can go ahead and get rid of this fill just like that we see the browsers going to default it to black right here but then we can use a little trick on our parent SVG and say the fill should be the current color this is a really cool SV you property which is going to let us use tailwind color utilities to style this icon so what do I mean well if I were to come to the SVG come up here to the parent and say text read 500 check that out now the icon is changing based on the color of the parent so we can come back to our code right here we only have to look at the SVG we can see that our input has a placeholder of gray 400 so let's go ahead and make this text gray 400 now we could either do it here or we could even do it on our SVG itself but that way you've kind of encapsulated the details within the SVG but you can still treat this you know just like you were styling any other HTML element and so now the icon matches the placeholder color it's looking really good lastly we have this kind of weird behavior where if you click if you happen to click on the email itself you don't get anything happening because it's being rendered on top of the input but in our solution you can see that doesn't happen well we can disable pointer events for this entire div because it's really just there to see it so we can use the pointer events none class and now we can click right through it to the underlying input element so that's really the basics of how to work with SVG with tailwind the answer is basically just treat it like any other element so that you have kind of full control and flexibility here right in your templates so let's go over to exercise 10 and give you some practice with this here we should have in the exercise file the icon right here it says it should be color red 500 so go ahead and add that to this input using the positioning techniques we just talked about making sure to account for you know all the details here like if I kind of have a lot of text here we still have room for the icon and so go ahead and give that a shot okay let's compare our work so back here in our exercise we've got the SVG icon and we'll do a similar kind of treatment here this time it's on the right-hand side so so they'll be a little bit different but let's go ahead and start with our absolute wrapper will throw the SVG in here will give the SVG with a 5 and a height of 5 and there we see it for our positioning div let's go ahead and use in set y0 flex item center just like before I should vertically Center it but then let's use write zero so that it hugs the right side of the input over here now we can remove the text black the fill here from the path and go ahead and make this text red 500 hoops we forgot to add fill current color there we go and we can give it a little bit of breathing room here padding right 3 pull this away from the edge pointer events none and if we go ahead and paste we don't want that to happen let's add that padding to the right of the input here and now we should be all set now you also might have happened to notice sometimes when I add classes to my template here like padding right 10 and I save it it kind of resource this is another vs code plug-in that I'll link to in the readme of the training which is automatically sorts your classes just another nice little workflow tip that makes working with tail and a bit more pleasant ok we're getting near the end here so let's go over to exercise 11 and this is really just kind of a little tip to make sure that you're aware of if you come to Google and search for tailwind custom forms you'll find this little nutloaf eyesight and this is actually a custom tailoring plugin that was built by the creator of tailwind CSS and explains that it helps you kind of make forms more easy to style with tailwind the default forms and browsers are kind of hard to get consistently looking and feeling the same way so when it comes time to customize them and build them as part of your UI if you don't have any sort of reset around forms it's pretty tough so that's basically what this is for and this exercise is just making sure that you're aware of this custom forms plug-in and this documentation page so over here I have it wired up and this is basically a copy pasted from this getting started right here of this form right here and you can see you know they're they add some icons to the input tags and these are all going to look they're consistent across browsers and it's also really easy to change so for example this account type right here if we wanted to make this button a different color we could just come down to exercise 11 account type and on our radio button let's just say it's text green 500 and now when we click on that it's going to be green so it's just kind of a nice way to tweak the UI here for form elements and you'll just see that there's these form - classes that's exactly how you use it so on an input you apply form input on a radio gets form radio form select form checkbox these things make it really easy to work with so you know here we have a custom selects but it's gonna look kind of nice and match your theme again in every browser still using the native select so that when you click it you get the native UI but you know if we want to change the text well we can just come to the selects right here and say text Excel and it's going to behave exactly how we would expect it to if it was a normal HTML element so that's more of just a resource to make sure you're aware of if you are using forms with tail-end I definitely recommend using this I think eventually will make its way kind of into the framework officially but for now it's just this little plugin that you install and add to your tail and config okay so exercise 12 this is another really cool one I got really excited when I found this one so the idea with this exercise is you see this kind of really nicely design component somebody's components by the way are coming from the tail and you I project which are a set of components built with tailwind but just goes to show you kind of how nice beautiful components you can build with tail and I just think a lot of the subtle details here are really great but anyways one of the details with this button group is these focus States and there's a little bit of animation on them and they look pretty nice but you'll see over here in the solution they don't exist and a problem you'll often run into with focus States is that even as good as these ones look I think it looks a little bit better it looks a more expected that when you click on a button you know you get this feedback from the active state in the hover state but you don't have extra focus state and focus state is really there for keyboard accessibility so you can see here I'm using my tab key and shift tab and that's what the focus se is designed to help us do but some browsers like Safari won't even render the focus State when you click on them but some of them will so here we're in chrome and you can see when I click on this we get that treatment so what if we didn't have to make this trade-off what if we could keep our components accessible and even looking really nice when we're using the keyboard but when we click on them we get kind of a treatment we want from a visual perspective well we can do just that with the focus visible polyfill here so focus visible is a new kind of pseudo state that's coming to CSS it's not available today about with this polyfill we can actually get it today so the the polyfill is just an NPM package is called focus visible I've already installed it here over in the project so you can see it's in our package JSON and if we check out ember CLI build we also import it right here so depending on your setup you know if you're not in an ember app it's still there's going to be the same idea you just include this in your bundle and then you'll be able to use it so the next question is you know how can we use this from the perspective of our developers and us actually writing application code right so let's close these old exercises here and pop open 12 so 12 is showing us the button group here and we can see you know these buttons have these classes which are giving us that's that nice focus state and they're all using the focus kind of pseudo selector right here so see so these are the classes that are giving us the blue shadow now ideally instead of using focus we could just use focus visible here are the three kind of decorative ones and we basically want these to be only when you're focusing using the keyboard which is exactly what this focus visible new CSS pseudo class does so I think if we could end up with this API it would be really nice it fits in with the philosophy of tailwind it will probably make its way into the framework at some point but how would we get this today well if we want to get this today we could write our own tailwind plugin so let's go ahead and open tailwind config here in app styles here's where we have the tailwind theme defined and any extensions that we would make you can see here I'm using tailwind UI and we're using the inter font for our font family but other than that is pretty empty so let's add this new variant ourself first we're going to comps plugin equals require to go in CSS plugin and if you come over to the guides here at the tail-end guides and search for custom plugin writing plugins this is basically what we're gonna follow and this is a way to hook in a tailwind and do things like add utilities add components or even add variants we can see here there's a whole guide for it so it says to add a new variant called the add variant function passing in the name of your custom variant and call back that modify the affected rules as needed so this is a cool thing about tailing you can basically just write plugins in line here we're using you know one from tail and UI which is a separate NPM package but we can also just do this so what do we say we wanted to add what we want to add the focus visible variant so let's go ahead and do that right here and instead of modifying the class by adding a disabled colon we're gonna add this kind of focus visible colon class name class right here and you know this you can see this is hooking into the default browser disabled pseudo state that exists and we don't have access to that but what we do have is a new property which is given to us by this polyfill so the polyfill is gonna add a data focus visible added attribute to any element that was focused with the keyboard and that's exactly what we want to target so instead of using that we'll use our own little data method right here so that should give us this new focus visible variant available to us to apply to our different classes now if we look back at our template we'll see we need focus visible on the z-index on this shadow and I think we might have missed it for this border right here so let's pop open the docs for border color right here so we'll go back to tailwind search for border color and down here we can see the docs con variance this is the this is true for every module but you know we're just getting an example right here this is how we add variants to our different modules so we can copy this come back to our tail and config add a new variance key and these three are the default and we're just going to go ahead and add focus visible and with any luck if we come back and check out our work clicking on this first button doesn't trigger at the focus state because we're using focus visible but if I were to select it with the keyboard there we see the border is turning blue so I think this is all working now we also want this for the Box shadow plug-in and the z-index plug-in and if we come back now we see all the styles are being applied when we focus with the keyboard but when we click we don't see anything very cool so let's come back and change the rest of these will grab the focus border blue and make it focus visible and the shadow outline as well and also the z10 right here focus visible z10 and now we have our visual Styles kind of being exactly like we would expect them to but if we start tabbing we get this really nice focused treatment and so now we don't have to kind of make this trade-off between the UI the visual UI that we want and keeping our UI elements accessible so I really love this focus visible variant and the the polyfill and the plug-in it's a good example of how easy it is to add plugins to talen on your own and it also is just so nice because you know those blue boxes show up everywhere and it's so tempting to disable them but if you just kind of copy and paste this from project to project now you have no reason not to keep these around for keyboard users and so yeah that's just kind of a great win all around and you know again we're just to re-emphasize we're keeping all the decision-making here in our template we haven't had to go write CSS one little plugin and now we won't break our workflow when I actually comes to styling our application all right last exercise here lesson 13 and this is really just kind of a hard one lesson and it has to do with responsive design so here we can see we're looking at this kind of page navigation treatment and on desktop we have the nav items up here and then when we collapse it we have this little menu that we can use to expand and see so you know clearly these are two very different UIs right the navigation the mobile menu has this vertical navigation and then the desktop has this horizontal and there's you know obviously you similarities between the treatments but if you're going to build them you know you use you know very different layouts and in fact if we come here and take a look at exercise 13 HBS we see that we've built this with a desktop menu right here and then down here we have kind of a button for the mobile nav so that's that button and then down here if the is open state is true we go ahead and show the mobile menu right here so basically right here you can see our four nav items dashboard team projects and calendar you know they're being duplicated here between our mobile menu and our desktop menu and when you start working on certain layouts it can be really tempting to try to keep your layout the same and tweak the responsive parts and even add a lot of wrapping and new elements just to account for you know the styling needed on either mobile or desktop but so many times especially when the the layout radically changes between breakpoints it's way easier to just split it up in your template you know we are duplicating the four nav items here and down here but it's so much cheaper to just copy those and versus making the HTML basically so complex that it's really hard to change an update because inevitably you're gonna have to add new new classes and change the styling to account for new things that come your way so we've just found it's much much better to just keep these separate again it's kind of a hard one lesson going too far down the wrong path and just making it too painful to change things but here you'll just see on the desktop menu the wrapper here has a hidden class which is just display:none right so you can see right here display:none so it's not going to show up and then on medium size we go to flex and so that's going to make it visible and then same down here with the mobile menu you know it uses the is open state to say whether it shows or highs because even when we're on mobile the menu isn't always there but on desktop the menu should never be there regardless of that is open state so you can see here we have the medium hidden class apply and this will always take precedence over these two and so this is just really simple you know good technique hiding the content that you don't need on the screen sizes where you don't need it and being able to keep these layouts separate it's just worked really well for us and we feel like it's a really good solution for some of these trickier kind of page wide layouts now if you really did want to remove this duplication how might you do it well you know we have a front-end framework here it's pretty easy to loop over data so dashboard team projects and calendar why don't we just come over to our component create a new links property with dashboard team projects and calendar right you can see where I'm going with this and instead of just rendering these like this we can just each over this dot links as link you know you'd probably want an H ref in here but just for the just to keep it simple for the sake of this and I think this dashboard link is actually active so let's just grab the use inactive ones render one of these get rid of the rest render out the link and now we have our four and ave items right here and we can do the same thing down here for the mobile menu but you know we have our own link tags down down here we have our own set of classes and so you know just again embracing this philosophy of keeping things separate keeping things small not getting stuck into too bad of an abstraction that's hard to undo later and so now we have no duplication of this content you know if this were dynamically generated from you know a back-end or something or we were to add a new link we only have to do it in one place and everything works just fine so again that's just you know explaining that these are kind of different problems we're solving if there's a duplication problem here there's one way to solve it this is just one way you could also imagine kind of creating a higher-order contextual component that renders the two menus separately but from the calling perspective maybe in your application template you only have to pass in the data once if you wanted to do it in the template instead of on you know Java Script class like this but keeping the your your HTML code maintainable and easy to understand it's kind of a separate concern and so when the when the layout is really different between breakpoints just go ahead and split it up it's the simplest thing to do so kind of the last point I want to make about this template here and about responsive design in JavaScript frameworks like ember is that we used to use a Java Script to detect the viewport width a lot more and have that affect our design so you can imagine something like here in the desktop menu instead of using these Tailwind CSS classes to say go ahead and hide this on mobile and then let this show up on medium sizes we could use a JavaScript helper to say something like if screen is mobile or up right and then we would just render this and the cool thing about this is that ember wouldn't be doing any extra work on smaller screen so it wouldn't render any of this and then once JavaScript detects that the screen is bigger let's say if the user kind of reorients their device or makes a window bigger then it would go ahead and render this so from that perspective it can save some work that the rendering engine has to do on the client's behalf but the problem with it is that it's not robust to server-side rendering so because javascript isn't running on the server and it doesn't know the size of your device if you were to pre render your app on the server let's say using fastboot with ember when you ship that up and it initially renders you know you're gonna have to just make a decision about which UI to render and you can end up with some bugs there we've had that on our own projects before where basically we're showing the desktop version and so it renders that first with just static HTML and CSS and then once the JavaScript kicks in it realizes you're on a mobile device and so things flicker and they start hiding kind of once the JavaScript takes over and hydrates the page so since learning all of that and again going through that kind of hard lesson 1 we've basically unraveled all of that usage of JavaScript to look at the viewport and instead just rely on CSS media queries using these responsive prefixes like MD and LG and everything so again there's a nice win here where it's just one way to do things you stay until when you stay with your your classes right here and you also make sure that your site is going to work on that initial render because if everything is in tailing classes when the browser actually renders your screen it knows what the what the screen dimensions are and so it's going to know which classes to show in which ones to hide so just one last little takeaway when it comes to making these kind of larger complex responsive layouts with tailwind and ember so that is all I have for you today be sure to check out the readme in the repo for links to the custom forms plug-in and the focus visible polyfill all of these vias code extensions that I use to make working with talen a lot easier and the docks and tailwind UI and all that stuff Taylan really is one of my favorite parts of building web development in the last few years especially I feel like I've learned so much really one of the biggest things for me with Taylan even if I were to ever work on a project that didn't use tail and there's so much that I've learned from it about choosing color working with SVG's understanding flexbox layouts thinking about composition that I would bring with me to any project that I went to so I really feel like the best way to use tailwind is to understand from the creators perspective the philosophy of the creator and the maintainer is how they approach this stuff that's going to be the best way to get the most out of tailwind and you're also probably to learn a lot of new stuff from that as well so thank you so much for joining me I hope you learned a thing or two and have fun styling your Apatow and
Info
Channel: Sam Selikoff
Views: 39,183
Rating: 4.9801698 out of 5
Keywords:
Id: nqNIy8HkEQ8
Channel Id: undefined
Length: 90min 50sec (5450 seconds)
Published: Thu Apr 02 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.