Building beautiful Blazor apps with Tailwind CSS - Chris Sainty - NDC Porto 2022

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
um so the talk today i'm going to be talking about two of my favorite things at the moment uh blazer and tailwind css just to give you a bit of an idea of of kind of where this talk is aimed at i'm going to assume you know a bit about blazer i'm not going to go into sort of real fundamentals about blaze or anything like that the focus of this talk is kind of you're interested in tower wind and how do i put tailwind and blazer together because tailwinders we're going to discover is slightly different to something like bootstrap so um just before we go any further just a quick slide about me so my name is chris i'm a principal software engineer for a startup in london called deployed um i'm also a microsoft mvp i've been one for about three years now um i do or i have done a lot of blogging on blazer but i haven't been doing much for about a year and a half because i decided to write a book because i thought that would be a good idea and that was a year and a half of my life gone um so so yeah but that that's done now and hopefully that will that should be going to print in the next sort of few weeks so so that that's uh yeah that's that's good and finally i do do quite a lot of open source work so i have an organization on github called blazid um got some of the most downloaded packages of their type for blazer applications at the moment which is quite nice so the biggest one is blazer local storage but we have modals and toasts and things like that and we've just hit a really big milestone recently we've just gone past four million downloads which um is is scary because that means four million people are relying on my code which is uh yeah that's interesting um but it's also nice to see that blaze is growing in popularity with that sort of um uptake so so yeah anyway that's enough about me let's get into the actual main topic here so let's talk about tailwind csf to start off with and what tell when css actually is so tailwind css is a utility-based css framework so what does it mean to be a utility-based css framework well let's draw a comparison with uh a sort of another well-established framework bootstrap arbor class bootstrap is a component-based css framework now what i mean by that is that with bootstrap you're going to you know you're going to want to create a certain button and you're going to in order to do that with bootstrap you're going to apply a class that's called button or button primary or button secondary or something like that and that's going to have a pre-made style for that type of button there's also more advanced things like cards and things where they have set layouts and again you apply a class of card and certain markup in a certain structure and you get that look as well utility frameworks are very different to that with utility frameworks there are hundreds or thousands of very atomic css classes what they usually do is is target one specific css property and you compose these together to create the look you want now what this means is that you get a much more customized ui we've probably all uh can tell a bootstrap website from a mile away it's it was kind of a meme at one point that doesn't really happen with tailwind because there aren't any pre-made styles that's also possibly a trade-off for you depending on how much you're into ui design or whether you work with a design team okay one thing that's also really interesting about utility frameworks and tailwind specifically is that you pretty much never write css which is an interesting concept in fact i'll make you a promise at this point in this talk i'm going to do a load of demos and i'm not going to write any css okay everything you're going to see in this talk is going to be using pre-made classes that are part of tailwind slightly i'm i'm running the line slightly on that but i'll call that out when i get there but it's technically true so let's have a look at what i mean by this anyway and let's have a look at a concrete example so this is uh the card component from bootstrap's website okay so this is what i mean by it being like a component um so you apply this class of card on the on the main outer div then you've got these uh sub elements with various classes on them to style that card in a particular way and this is a bit customizable you can do the card without the image you can uh miss out the the card text if you want to and just have the title it it's up to you there's a version as well where you can have a button on there and what have you but the point is you're constrained by what bootstrap's provided for you you have to use that markup and you have to use those classes so what would this look like when we were doing this with tailwind well this is the same card it looks the same but the classes are different so what we've got on that that outer div now are very focused classes designed to create the look that we want so flex is saying that we're going to use flexbox for the layout here flex coal is about the directions that's the flex direction property that's saying him we want this to be a column which means the image and the div are going to get stacked horizontally there's a shadow you can just see there on the bottom of that card so we put shadow lg large shadow okay the image you probably can't quite make it out on hex is a bit small but there's slightly rounded corners on the top of that so that's what rounded t is rounded top h40 is saying there's a height of 40. now 40 isn't actually 40 pixels or 40 rems it actually maps to a value in a design system so i'm going to talk a bit about that in a second p4 again padding four that's going all the way around again four maps to a number in the design system and tex grey 800 that maps to a particular shade in a color palette then for the heading we've got text lg text large font semi bold and mv margin bottom two so you can kind of hopefully start to see that these classes are quite readable once you kind of understand what tailwind's naming conventions look like and this is kind of one of the cool things i like about taowin because i don't have to jump between a css file and my markup file to understand how things are styled i can just see it straight here in my markup so as i mentioned a second ago there about those classes they mapped to a design system while tailwind is essentially a big design system and this is quite an important thing and the reason this is important is because the time using the design system puts us in a certain constraint which means you can keep things looking consistent and what have you but you get a centralized way of configuring it so tailwind ships with a load of defaults that are really good and you can build really good stuff with them but if you do want to customize them specifically to your company design language or anything like that you can do so if you're working with a design team they can actually provide you sort of your design language specifics you can code them into towel wins configuration and then the devs don't really have to worry about the styling as such because they just use the various classes and they map to the right things in the design system so let's just cover a few of these off so the color palette for example okay so tailwind ships with a color palette with about 22 different colors in by default they range for various different things and they all look like this they all have a starting value of 50 and an upper value of 900 and that's 50 being the lightest shade 900 being the darkest shade you can then use these then get mapped into utility classes and you can use them for various things where colors are appropriate so text purple 700 for example or bg gray 100 for background has the same thing for spacing again i appreciate that's kind of slightly tiny but as i was mentioned a second ago about that h40 not meaning 40 pixels or 40 rem um it maps to a number in this design system which is the first column and then in the configuration file that is then mapped to an actual value so these are the values that come by default so for example four is one rem or 16 pixels and it's a proportionate system so that means that eight is double the size of four essentially so it's a really good sensible default and the nice thing is here what you kind of get away from is just random arbitrary values um if anyone's sort of built large scale apps with custom css you probably have seen what's happened where you end up with classes that are named very similarly because different people have done it at different points in time and not realized that a class already exists and then you've got say two cards this one's got padding of 16 and this one's got padding of 15 because 15 and 16 are almost indistinguishable and no one knew it was there before and you get these kind of slight differences all over the place but with tailwinds you'd just use four and that would map to like say one rem or whatever and if we ever wanted to change that like say we wanted more spacing by default you could just up the value in the design system you haven't got to go and change all your classes in your markup code you just do it centrally and boom everything goes goes up so again this can be used for various things padding width height all that kind of stuff the other thing that is really cool about tailwind is it's support for variants so variants are things like uh pseudo classes or media queries and stuff like that um so again tailwind has a whole heap of these that ship out of the box um and then you can use them to do stuff like hover effects or dark mode styling or odd and even color variations on a table or styling first elements or whatever you you know happen to want to do and i think this is a really strong selling point of tailwind because this stuff is is a bit of a pain to do with regular css you know if you want to create a hover effect for a button you know you're you're back in your css file you're creating a duplicate of the class with a hover sudo class on it and then you're changing your styling and things like that well to do the same thing in tailwind we just say we want bg red 500 by default and when i hover over it hover colon i want red bg red 800 applied and that's it i've now got a hover effect i just want to really stress this all this stuff is configurable there is nothing in tailwind that is fixed everything that's there you can change you can modify you can adjust and you can make it work the way that you want to make it work but it's all optional technically speaking you need to provide no configuration to tailwind by default okay you only need to provide configurations for the things that you want to change or that you you know you want to tweak and personalize so a good way to think about utility frameworks like towerwind is is lego blocks for ui design what you do is you compose these classes together to create these looks and if you don't like a particular element of that cool you just take out that particular utility class apply a different one and you can tweak that look and customize it it's also a very rapid process like i say once you learn the the naming conventions for tailwind you can very quickly iterate through this and because you're not jumping between uh css files and markup files it's just a very rapid process one of the main uses i think for taowan when it first came out it got talked around a lot being sort of being used as a prototyping framework for ui design because you could just very quickly iterate on the design in a real app just by quickly applying these utility glasses cool so let's get that little drink here have a laugh at that while we're here this is usually where people knew to tell when start having a little twitch if you're as old as me um and when you when we started doing web design in in the 90s and things like this you'll know about inline styles and you know we're all very much encouraged to understand that inline styles are evil and we shouldn't be using them and tailwind does have a lot of similarities with inline styles it does look that way um so let's deal with this head-on what are the limitations of inline styles why are they evil why shouldn't you use them it's not like everything it's not like you ever shouldn't ever use them they have their place but generally speaking well firstly inline styles are just magic numbers or magic strings depending on what properties that you're putting in there you're going to declare them directly on an element by putting a style attribute in there and they're fixed to that element and if you want to you know repeat those styles somewhere else you copy and paste them over to somewhere else if you want to change them you're also going to go in and you're going to have to change them everywhere you've put them okay there's no real way of centralizing values and things like that to make sure you're using consistent numbers or what have you um colour codes things like this so it makes maintenance very very hard pseudo states like hover and focus they don't work with inline style so goodbye any kind of nice interactive uis with hover effects and what have you you're not going to be able to do that with with with inline styles and probably one of the biggest ones in modern web development is that you can't use media queries so if you have an app that needs to work on mobile devices and tablets and desktops well you're going to use inline styles then you'll you're really out of luck that's not going to work so darwin uses classes it's not inline styles they're just really focused okay and that's the only difference and that's where that kind of similarity with with inline styles comes from but that's it it just looks a bit similar but all of the functionality that you get with regular css you get with tailwind so now we've kind of learned a little bit about the basics of tailwind let's talk about how we would actually start to use tailwind with blazer there's two options we're gonna we're gonna look at the first one we're gonna look at is tailwinds play cdn so this is a new uh a new thing that came out with tailwind v3 which came out sort of tail end of last year um and it's really quite impressive so in order to use this um it's really really quick and simple uh we add in a script tag um to the tailwind cdn and then we just start writing our our utility classes and it just works okay so really quick and easy to get going um the thing i'd like to make clear at this point is that the tailwind guys are very very clear about this this is for non-production use okay so that's something to just be aware of it's kind of designed for people who want to try out tailwind see what it's like to use it maybe do prototyping that kind of stuff but it's not something you want to use for production apps okay so that's why we're going to talk about the second option in a second but what's i think some of the coolest bits about the tailwind cdn is that you still get all the features that you would have if you actually were running this locally so you want to customize the styles yeah that's cool that's not a problem you can do that we add a script tag we add a towel in configuration object and we can just configure this okay and that's going to do all of the same configuration that you could do as if you're running tailwind locally so that's that's pretty impressive stuff so in this uh in this little code sample i'm adding in a blazer purple color here um and then i can just go and use that so i can just go bg blazer purple and that's just gonna work okay that's just gonna build that on the fly now just in case you're wondering how it does this um that script tag is basically going to process this and what it does is it creates a style tag and and basically puts all these styles and injects them dynamically into the into the host page what's another cool feature of tailwind is plugins so this there's various diff well there's quite a lot of plugins actually to tell when talwin has official plugins and it also has community plugins and they cover lots and lots of different scenarios um and you can even use some of these plugins with the taowin cdn as well okay you just put the plugins query string on there and then you just say whichever ones you want to use now you are limited to the official taowin plugins to do this but you know the fact it does this at all i think is is still pretty cool um so that's the cdn um but i want to talk to you about a different option which is the tailwind cli so this is uh what i would suggest you use if you're actually going to build real apps with tailwind okay and up to version three this was a an mpm only thing you know you had to install npm you used npm packages um which sometimes in the dot net community especially that that doesn't sit well with people um there's actually now a new uh option here so the telling guys have created a standalone cli now so it's a standalone executable doesn't need node or anything you can just download that from their github releases page and you can just yeah just reference it use it and it just works you don't need to have node or npm or any of that stuff um personally it's not the option i would choose um because then you've got to deal with getting that executable somehow into your say if you're using a ci pipeline you've got to get it in there somehow and then run it and what have you it becomes a bit of a faff personally i do think the npm option is the better option and i'm going to show you uh using that today and frankly i don't think it's too a particularly bad option if you've got any other need for npm if you need to do i know say you need to do some javascript bundling or something like that for whatever reason because your app might rely on it for for for something um you can plug that into that pipeline as well so um you'll be glad to know that's the end of the slides now so um we're going to go over to visual studio and we're going to start having a look at how we can actually build this stuff so that's not changing to do aha there we go um so what we're going to do is we're going to work on a blazer webassembly app for the rest of the session so the first thing that we need to do here is we actually need to get a tailwind working with it so how do we actually go about setting this stuff up well the first thing we're going to do is i've got my terminal here and i'm going to run this command npx so i've got node installed i've gone and got the installer from node.js.org um this mpx command a lot of people are still unfamiliar with it it's it's quite a cool thing i don't need a package.json file or anything like that i'm just going to say run this tailwind css package run the init command on it if i don't have that in my in my node cache it's going to go off and get it for me and download it and run it if i've got it it will just run it but it doesn't create a node modules folder i don't need a package.json file or anything like that so i can hit go on that that's going to go off and create this tailwind configuration file so that's now sitting at the root of my project here and this is all that it creates okay now as i said technically speaking you you kind of don't need to change anything but you kind of really do the one thing you need to do is actually add something into this content area here so we need to basically pass into it where what files are going to use our tailwind utility classes okay so we're putting in the path here and this bit is just saying find any uh files inside of our application that have a razer or an html extension so our blazer components and the host page for our app now the reason we're doing that is because with tailwind v3 they move to the jit engine by default now um what happened previously is that taowin used to generate a load of css classes when you first ran it now they had to be quite selective about what classes they generated because if you turn on all of the features of tailwind v2 you would get about a 20 meg css file and if you then try and load that in a browser browsers get slow the dev tools get slow it's not a very good development experience so they gave you some sensible defaults and then you just turned on the other features that you needed but this wasn't really a great option so they worked on this jit engine and what this gt engine does is you basically feed it the files that contain are going to contain your your tailwind utility classes it will monitor them and every time you add a new class it will dynamically recompile the tailwind css for you so the tailwind css will only ever contain the classes that you're actually using but the cool thing about this is that all of the options that tailwind has available with all of its pseudo classes and variants and all this kind of stuff are all turned on by default you just use the class and it gets applied so that's why we have to put this path in here so that the jit engine knows where to go off and look for these these these classes so that's our configuration file done the next thing we're going to do is just uh add in an initial input css file so i'm going to create a styles folder here and inside of that i'm going to add in a new style sheet uh there we go so we'll call this app css and inside of here we're gonna put in these three tailwind directives so towerwind is going to process this file for us and it's going to create an output css file that's going to contain all of those utility classes um and basically these three directives get processed and they generate various different things so in the base layer it generates a css reset okay so you get a nice level base before it starts applying all of the various things it's going to do then it generates component classes and utility classes and this is it's not really particularly important to worry about what these mean but essentially it's just kind of making sure that the right styles can override the right things and they're all in the right order so that's our our input file so now we've got that so we've always we've added that tailwind configuration file and we've added that input css file so in order to get going we then can run mpx and then we say tailwind css and then we say we're going to pass in an input file that one that we just created oh that's wrong and then we're going to say we want to output a file into our wwe root folder and we're going to call that app.css as well and then at the end of it i'm going to do this additional tag minus minus watch so what's going to happen here is the the tailwind cli is just going to keep watching both that input file that styles app.css and it's going to watch all of those files we told it to watch all the razer files and html files for changes all right and every time one we modify anything it's going to rebuild that output file for us okay so we hit go so that's now generated that that initial file for us you can see there 146 milliseconds pretty pretty fast and we can go and see that in here so there's all the reset stuff that it's generated and if we go down it will start showing us so now we can start seeing utility classes okay and these are ones that i've already got applied because i've already done some work here because watching me apply all these across a whole site is going to be a little bit boring for you so i've already done some stuff uh to do this so the final thing i'm just going to do is quickly add a reference to that output style onto the index page here and now let's see if we can have a look what we've got cool so this is my reimagining of the the default blazer template um i've been working with blazer since pretty much it it was first kind of conceived as a experiment and i don't know about any of you but i'm getting kind of quite tired of the regular template and that purple that purple gradient down the side so i thought i'd have a little bit of a play around and try and create something a little bit more interesting so this is what our starting point is going to be but there's a few bits here that need a bit more styling so i thought we'll work through these together just so you can get a little bit of a feel of what it's like you know to apply these these tailwind classes so uh we're going to start by going over to the index page so it's my index component now i've got an h1 tag and a p class here they haven't got any styles at the moment so let's uh just go through and add some of these in so in order to do this uh the initial styling for this i'm going to say uh i want a style on here of extra bowl because i want my h1s to stand out a bit more so i just uh hot reload go over so you now see that that hello world has gone has gone bold right i've just applied that that first bit the next thing i'm going to say is well i want it to be quite big because you know this is a heading after all so let's bump that up as well so i want uh 7xl i want it to be like really big text and boom i've got really big text um i'm also going to say i want tracking to be wider because you know space things out a little bit more make everything look a little bit less compressed cool so i've got a little bit of spacing now between the letters in my in my words and finally i'm going to say i want a margin bottom of six because it's pretty close to that p tag so i can pop that in as well and well i've now started my h1 tag now that's taken me sort of 20 or 30 seconds while i'm talking to you if you can imagine if i'm actually coding this up on my own i'm just going to be tap tap tap tap tap done and we can do the same thing for the p tag here so the p tag here um i'm going to say i want text xl and i want a margin bottom of 20 on these because that's how the styling is going to work okay and now i've got like this really huge massive text for my p tag okay so you can kind of see the process here as developer you're just going to apply these things you're going to refresh and you get your styles and you're just going to see very quickly what things look like especially with tailwind's hot reload and with blazers hot reload system okay it's a very quick iterative process cool um 7x though it shouldn't have been quite that big sorry my bad um there we go that's what it should look like sorry i thought i was looking a bit big nice so that's kind of just regular styling okay which is pretty bland and boring right that's pretty bad bread and butter stuff um so how about something a little bit more interesting um so this panel on the right hand side is looking pretty dull i want it to be kind of a big feature of this it's kind of taking up a lot of space and what have you um so it'd be pretty cool does it tell when logo's got a gradient how about we put a gradient on the background right now this is something that i always find a bit of a pain in css i would consider myself pretty confident with css but i can never remember the syntax for background gradients i always end up googling this it's just one of those things that won't stick in my head so let's have a look at how we do this with tailwind so this div down here is the is the is the outer div for that so i'm going to apply three classes these three classes here bg gradient to br that's background gradient to bottom right it's going to start in the top left and we'll say from green 400 to blue 500 okay so three classes save that do reload and boom i've got a background gradient okay so pretty quick pretty rapid and i haven't got i haven't had to open google which is always a good thing so that's a gradient but um let's have a look at something else we could do with this really rapidly so we've got our background gradient stuff but how about we just add a hover effect so we'll use one of those pseudo classes hover and we're going to say this time when we're hovering we're just going to reverse the gradient so we're going to say from blue 500 to green 400 instead okay same thing but just the opposite way around let's reload that go back over and boom now i've got a hover effect on my gradient as well so these things are just pretty trivial to do with something like tailwind okay i'm not going off to separate files to do this i'm not going to google to check syntax okay all i've got to know is the naming conventions that taowin has the other thing that we'll just look at as well uh just for for completeness is the survey prompt here i've i've got as an unstyled thing at the moment so let's just quickly add some some base styles in so this now stands out a bit better this looks a bit more interesting um but we can even do sort of uh what i would call more advanced things with css with tailwind pretty trivially so everything's really square on this page and this is meant to be like a bit like a banner thing so it'd be cool if it was a bit skewed so it looked more like it was kind of uh pasted on the page as it were so how do we rotate elements and transform them well even stuff like that in town wind is is is fairly trivial stuff i'm going to reply two new css classes to to create this effect i'm going to reply transform which just says i'm going to transform something about this element's position and then i'm going to apply the rotate 3 utility class and this one if you'll notice has a minus in front of it which means i'm going to want to rotate counterclockwise rather than clockwise okay so i'll pop that on there we'll reload our app again and then we get a bit of skewing so the reason i've showed you a few bits like this is just kind of to show you that sort of some things that are not quite so trivial in regular css are pretty trivial when you're using something like tailwind you can create some more advanced effects with with not a lot of effort at all so at this point some of you may be thinking about repetition okay so those classes we've got on this h1 and this p tag right usually these are the sorts of things you want to be consistent across your app you want all your h1s to be the same you want all your anchor tags to be the same right am i going to have to go and copy and paste this everywhere because that doesn't sound like a lot of fun and i agree so even though tailwind kind of does uh encourage you to put your styles directly into your markup you can still centralize styles for this kind of thing okay so let's have a look at how we can do that so what we're going to do is if we go to that input css file that we created earlier um we can uh use a pretty cool feature of towerwind called the apply directive now this is where i said i was skirting the line a little bit where i said i wasn't going to write any css so technically i am defining a class here i'm defining the styles for the h1 type but i'm not actually writing any css properties out i'm just applying those same utility classes using the apply directive so what's really cool about this is i can centralize my styling for common elements inside of here but i can still leverage all the power of that design system all right so if i go and change the weighting of what extra bold is for example on my on on the font that we're using again i just do it centrally in my design system i'm not coming here and modifying it okay so i can do that for the h1 and i can do that for the p tag okay we can save that that's all good and if we go back over to our markup we'll get rid of the uh styles that we added before we're just going to have our regular hth1 and p tags we'll do a hot reload and everything looks the same as it did before because we've just done the same styles were applied you can see this in the dev tools we've got no class element but there are those various properties that have been created by tailwind for us okay so this is a very powerful feature when you want to deal with these repeated styles so that's one way of dealing with with repetition and that one i would very much say is like keep that to things like uh that h1 example there where you're just repeating the styles it's nothing to do with repeated markup all right as we're using blader if we do want to deal with repeated markup there's a different technique we can use for that it's where components come in okay blazer like other spar frameworks nowadays is all component based and these are very powerful tools so that tailwind panel that's on the right hand side there that is actually on all of the various pages so what that means is we'd have the same html structure repeated across all the pages we'd have the same uh utility classes applied to those and repeated across all the pages so if we uh go and look at uh back into visual studio we can deal with this as i said just using a component so if i create a tailwind uh component to represent that that markup and then inside of there i can just paste in the markup that's repeated across the those three pages so i can i can do that save that i can get rid of the markup that's that's there i can reference the component i can do that on the index page uh come down here we'll get rid of it on the fetch layer page as well and finally we'll do on the counter page as well get rid of that so i'm just referencing that component across my my three pages new components that's gonna do a new little rebuild cool and now i've got that markup centralized i've got all those styles centralized and i'm just referencing that component across my app okay so with these two techniques you can pretty much remove all of the duplication that you need to inside of your app because there's not really many other scenarios we're going to see duplication you're either going to be duplicating classes on an element or you're going to be duplicating markup with classes okay and you can either use the the apply directive or components to deal with those scenarios cool right so so far we've kind of been dealing with the kind of run-of-the-mill uh stuff that we need to need to get our heads around in order to start using tailwind so now we're going to start delving into some more interesting stuff so what we're going to look at next is animations okay animations are usually a bit painful if you're writing blazer apps if they're usually going to involve doing javascript interop of some form or another no that wouldn't be any good would it so what i'm going to do is i'm going to show you how we can create a reusable animated component that doesn't use any javascript whatsoever we're going to do this entirely with c sharp and tailwind okay so what we're going to do is on the home page just to add a little bit more pop to it we're going to have that panel slide in from the right hand side okay as the page loads it so i'm going to do it once we're not going to like want to give people headaches with this going over and over and over here but it's just going to add a little bit of pop okay so let's go into visual studio and let's have a look at how we're going to do that so first off we're going to start off by creating a new component so i'm going to imagine we call this the sliding component and then let's have a look at the initial code so in order to make this work we're going to use a.net timer all right and what we're also doing here is creating what's known in blazer as a templated component now what this means is we're going to wrap markup and then we're going to use we're going to take that markup that we've wrapped and we're going to output it somewhere inside of this component so that we can do what we need to do um in blazer how we do that is we create a parameter with a name of child content it has to have the name child content it also has the type has that has to have the type of render fragment that's a convention for this to work and what we're saying is whatever content we wrapped capture it in this property and then we're going to output it inside of this div that we're we've got here in this component okay um and also i'm being i i realize this is just a demo and a talk but i'm being responsible here i do need to dispose of my timer afterwards and someone very kindly pointing this out on youtube that i didn't do this previously so i've done it now so there's eye disposable on there and i'm disposing of my timer um so how is this actually going to work how's the magic going to happen well first of all we're going to add in some base styles onto this this div here in this particular case i'm going to want the this div to be full height of whatever element it's in so that's what h fuller is doing for us and then we get the fun stuff so transition okay the transition property what this is saying is whenever i change a value of a css property i want it to be transitioned over a period of time i don't just want it to flip from one value to another instantly and i'm saying in the next class i'm saying i want that duration to be 500 milliseconds so over half a second and then i'm also using the transform class which we saw earlier okay when we skewed that element and that's because i want to move whatever elements we're wrapping around a bit because i want to create this slide effect and then the last thing there is i'm outputting whatever the value is of that animated animation styles field that i've got in my component and this is really where the the sort of secret source is we're going to dynamically change the value of what's in that animation styles and that's actually going to help create this effect for us so we now need to add in the default styles for so this is what the animation styles field is going to output when the component first runs so the first one is translate x full now what this means is it's going to move whatever markup we've wrapped on the x-axis so horizontal axis it's going to move at 100 of its width to the right so if we just quickly go back to our page what that's going to do is push that panel off to the right of the screen the other one is opacity zero this is just gonna make it transparent all right it's still gonna take up physical space in the dom it's not like i'm hiding it or anything like that i'm just making it invisible so that's how it's going to start when this component whatever it's wrapping it's going to make it invisible and push it off to the side or make it transparent and push it off to the side of the screen so a little bit of housekeeping here so we're going to new up the timer i'm going to give it a value of 300 milliseconds and then we're saying when it elapses call this trigger animation method okay which we haven't added in so let's add that in now and this method is the thing that's going to alter that animation styles what it's going to do is it's going to get rid of the two classes that we've added and replace them with translate x0 and opacity 100. now it's quite important here to understand that these are manipulating the same css properties and this is where having that transition class is going to come into play and 500 milliseconds because what's going to happen when this trigger animation method runs and blazer re-renders and we get those new classes applied because they're manipulating the same css properties it's going to go right translate x0 means render basically render where you are rendering your default position but we've pushed it off to the left or off to the right sorry so it's going to move it back over 500 milliseconds that's our slide effect and also just to make it a little bit more whizzy we're also going to then turn up the opacity to 100 and again it's going to happen over 500 milliseconds so it's going to fade in so this is going to create a slide and a fade effect for us the final thing that we need to do here is actually put in some code to start the timer so we're going to do that using the on after render lifecycle method um it's important to use this method because we're going to make want to actually make sure that everything's rendered before we actually start anything going we start the timer ahead of time it can do some funky stuff um we're ensuring this only runs once by putting it behind this first render check okay so once we've done that we can uh go and see if our work is going to bear any fruit so let's wrap this component let's rebuild that voila sliding component no javascript done um so we'll just run that a couple more times just so you can see in action it's only happening once it's coming through it's definitely sliding um so that's pretty cool we've now got a reusable component that can slide stuff in which we can use we could also extend this if we wanted to you know you could have additional parameters that controlled where it slides from so you can have it slide from the right or the left or top or bottom or whatever you want it to do but the point here is i just want to show you that you can do this stuff by marrying these two technologies together and you can obviously take this away and make it do even more funky stuff the only thing here uh to point out though is there's kind of one little thing that niggles me at the bottom here you can just see for a second or two there is a scroll bar and that's because the browser's being very helpful for us it's going well you've got this thing that's outside of the viewport on the right hand side so you probably want to see it so i'll get you a scroll bar so you can get over there and we don't really want that to happen so we can quickly fix this as well inside of the host page what i'm going to do is on the body tag here i'm just going to say uh overflow x hidden so it just doesn't show that scroll bar so i'm going to save that uh we'll do a hot reload it doesn't work i have to refresh this i've done this enough now that it kind of usually comes out still not doing it i don't know why it never picks that one up initially anyway there we go so we're now not seeing that scroll bar at the bottom okay and we've now just got a nice smooth animation effect and you could do lots of other types of effects with this you know manipulating other things as you see fit whatever your use case happens to be so we'll move on to the last little big one and that is dark mode dart mode's kind of becoming almost a staple of applications nowadays um as you can see from my ui i'm i'm a fan of dark mode it's kind of really been paining me that my browser's in light mode at the moment but there is a good reason for that which we'll look at in a second um so dart mode is something that historically had to be turned on in tailwind um with this new jit compiler and the jit engine that's not the case anymore it's there by default and this is why my browser has been in light mode because if we go into my browser settings i go to appearance and i put it back to my system default we now have a dark mode website now this is not magic i have actually applied a load of classes to do this don't think that wind is just suddenly working this out for me um i've already added them but um the point being here is dark mode the dart mode feature of tower wind is on by default and it's based on whatever your system preference is okay so because my system preference is dark mode it will apply dark mode classes if they exist okay you can see here at the top um that navbar hasn't actually got any styles at the moment so i thought we'll just go through that one quickly together so we can see what these look like uh if we open up this so um the key bits here are like uh the main header element here has got a background of white these nav links have text purple 700 is their color there's various other elements that we're going to manipulate here um so if we just paste in the updated code in order to get dark mode all we do is create um similar to a hover effect we just use the dark variant and we say when it's dark apply this class instead so i'm saying when i'm in dark mode apply bg gray 700 instead of bg white and you can see that just repeated across the other elements so text purple 800 but when it's dark mode it's text purple 400 right so if we save that we'll do a reload and now we've got our dark mode working on all of the bits and that goes across all the rest of the site and and all of this kind of stuff so that's all working which is cool um the only thing that's probably not possibly as great as it could be about this is what happens if you know you're just having a light mode day you're having one of those weird days where you just want to burn your retinas and what have you it'd be much better if you could toggle this manually okay and you can decide as a user whether you want to see light mode or dart mode on a particular day so we're going to build a component that's going to let us to do that let's do this um now we do need to change the default dart mode configuration in tailwind in order to make this work okay so that's the first thing we're going to do uh if we go into our tailwind config what we do here is pop in for the dartmouth property we just basically set it to class so that overrides just detecting whatever the system uh preferences are now if we uh go and look back at our site now it's gone back to light mode and the reason for that is when we use the class mode we have to have a class somewhere in the html tree called dark and then any child elements from that element will have dark mode classes applied to them so just to give you a practical example of that if i go to the html element here and i add dark like so all the dark elements all the dark variants now get applied okay so that's going to be what our component is going to need to do it's going to need to add and remove that class of dark from the from the html element now in order to do this we are going to use a little bit of javascript because blazer can't actually get to that element and manipulate it on its own so we are going to use a little bit of javascript in order to do that so let's uh go in and have a look at how we can do this so we're going to create a new component and this is going to be called dark mode toggle and let's pop in our class for that so so up here in this block of markup this is is what's going to actually create the toggle component for us the look of it what we'll do is before we go any further we'll just add this into the nav menu and then we can just see what it looks like first and i'll talk talk you through it so i will say dark mode toggle like so save that we'll do a reload cool so this is basically what we've created we've got this uh probably it's quite common you've probably seen on quite a lot of sites um so how does this actually work or how is it going to work so we're using a kind of a usual trick for creating sort of nicer looking html controls here we've got a label that wraps a div and that's using a four attribute and then that is going to toggle a hidden checkbox that we've got okay now what we're going to do is we're going to hook on to that that checkbox in our our blazer code in order to extract the value and and do whatever we need to do with it so we're going to hook on to the on change event so every time that that value changes we're going to call this toggle theme method and then we've also got there's also a dark mode uh private boolean here and that's going to be used to set the value of a checkbox all right so if we've already got dart mode selected we can reset it cool so the first thing uh we'll do quickly is we'll just get the javascript bit out of the way so i'm going to use a feature from blazer that came in in net six which is called co-located javascript so i'm gonna call this javascript file dart mode toggle dot razer dot js so it's the same name as the component but just for the js extension now if you're using visual studio you get this like nice nested effect going on over there and what's really what i really like about it is it means that my javascript lives with the component that uses it which is i think much better from a maintenance perspective so blazer supports javascript modules this is javascript module um so we're just exporting this one function called set theme which takes a theme string and if the theme is dark then we apply the dark class and if it's not then we remove the dark class okay that's that's all it's doing and it's just doing it on that html element that i showed you from the dev tools all right so nothing overly complex there we can kind of save that often and kind of forget about that now um so let's actually uh see how we can use this module in our in our razor component so the first thing we're going to do is we need to import it into our razor component all right so in order to do that we need to create a field to store a reference we can store references to javascript objects in blazer by using the ijs object reference type and then in on after render on the first render we're going to go and we're going to use the js igs runtime which is our interface into javascript from from c sharp code and we're going to use that to go and get that that module in order to do that we use a certain syntax we use the invoke async method we set whatever the return type's going to be so that igs object reference and then the first argument is a special keyword called import and then the second argument is the path to that file that we want to go and import from okay so that's going to get us our reference to our module again because we're you know being a responsible developer again we're going to dispose of that correctly because we've now got this reference into javascript which we do need to handle so i'm going to use iasync disposable for this one because it supports icing disposable and called dispose async if i need to so i've set that up the next thing that we can do is update this toggle theme method so inside of here this is the method that's going to get called by that hidden checkbox okay every time that we we change the value so what we're going to do is in that first line we're going to uh extract uh whatever the value is whether it's true or false if it's true dartmouth becomes true otherwise false and then i've got this theme variable which is going to if dartmouth is true then i set it to dark otherwise i set it to light and then i'm going to call that set theme function in javascript and i'm going to pass in that variable okay so it's going to pass down the string of either light or dark depending on on what i've got set cool so let's say that we'll give a reload let's have a look what happens now cool so we have got a switch that's loud let's go between light and dark mode okay if you're curious about that little slide effect that's happening on the toggle that's very similar to what we did on the slide in component we built earlier it's basically saying what happens here is it says when it's dark mode uh transition it to the right by three which is what it does to create that slide effect okay so similar technique to what we use what we used before so this is looking pretty good the only downside here is if i if i refresh the page it doesn't actually save my my preference so i think that's the last thing we can do to kind of make this a little bit better now shameless plug here i'm using one of my packages blazer local storage in order to to interface with the browser's uh storage apis um so i've injected that i've installed the nuget package and then injected the service and then what we can do is after we we set the theme um we can just um add that call to local storage and what we're going to say is set uh a theme key and then save whatever the theme value is that we've got so we can do that we can refresh cool so we're in light mode if i go to dart mode now and i hit refresh okay it doesn't work better play of course it doesn't work i'm saving the value but i'm not reading it out yet so we'll deal with that so after we load that module on the first render we'll go off into local storage and we'll try and get that theme key okay once we get that back we'll determine whether we're going to be applying light or dark mode and then we'll call into that set theme function in the same way passing in whatever whatever uh theme that we want so with that done let's go and have a look at our app voila so it's remembered or it set dart mode previously okay so that's why when it's refreshed it's remembered it for me so i can toggle back to light mode and if i hit refresh it stays in light mode and if i go to dart mode and i hit refresh it stays in dark mode if we go into the browser tools we can see here that theme key being stored here in local storage cool so so everything's looking pretty good um so we've gone through quite a few different techniques here and how we can use blazer and tailwind to create some cool effects um the last thing i kind of really want to quickly show is about how you can now go to production with this how do you make this work when you've got a ci pipeline because obviously i'm running a i'm running the cli using my terminal and that's generating all these classes as i go but because that app css file it's it's generating and putting in the in the wwe root folder is dynamic you wouldn't want to check that into your source control okay so you're going to want your ci pipeline to be generating that file when it's doing a build of your application now you've got you've got options here one of one of the options is that you could just add in a step into your build pipeline to run that mpx command for you um that's definitely one way of doing it um the other way you can do um that we're gonna look at now is to actually leverage a bit of ms build so i'm gonna open the project file here and i'm gonna add in a couple of targets into uh into here so the first one is kind of just a bit of kind of belt and braces stuff um what that's going to do is it's going to execute the npm minus v command and if it if it basically doesn't get a success code it's going to it's going to fail the build and this is just to make sure that npm is available wherever this is being built okay the second one is the it's kind of the the interesting one so um firstly it's going to run before the application is compiled so this is going to happen first then the main build of the application will happen so this is going to ensure that our css file is available in order to be packaged up with the rest of our app um and we're going to execute that same mpx command that we we did in the terminal we're going to pass in the input file that style app.css and we're going to have the output file um going into the wwe root folder as it was before um the cool thing though is we're going to pass in this other flag this time instead of doing minus minus watch we're going to do minus minus minify and that's because tailwind cli supports minification out of the box okay we haven't got to go and do any other funky stuff in order to get that work we can just pass in this extra flag um the other thing that we're doing here um is setting the environment variable though so we need this node m production um environment variable um how we need that in order for the minify stuff to work and finally we've got um some uh a check here which is a dot net check and it's saying that if we're it's only gonna execute this if we're in release mode so when we're running in debug mode um during development time this isn't going to run this isn't going to affect things we'd just be letting our terminal deal with that okay so that's what we're going to do uh so we've added that in so if we just uh what i'll do is i'll close all of these and then we'll open out that output css file if i change this to release mode and i rebuild the app in a second hopefully if all's gone well voila so it's really really tiny i apologize i haven't zoomed this up but first of all you can see npm versions being output there it says 8.7.0 so that's that first target running and then you can see that we've now only got one line of css um and that's because all of the minification processes happened and all of our scale all of our stuff has been minified nicely so we've now got a css file that only contains utility classes that we use and it's all be all been minified so we're using um the least space that we uh we possibly can cool so um yeah with that i think that kind of brings us to a bit of a close so um if you do want any of the code or the slides for this you can go to that url at the top there and you can download that from the git repo um and yeah i think yeah everything um thanks very much and yeah if you want to ask questions whatever please feel free to grab me outside and thanks for coming enjoy the rest of the conference everyone
Info
Channel: NDC Conferences
Views: 5,340
Rating: undefined out of 5
Keywords: Chris Sainty, CSS, Tailwind, Blazor, Apps, App, Framework, NDC, Conferences, 2022, Live, Porto
Id: uQsT3n1NTkE
Channel Id: undefined
Length: 58min 57sec (3537 seconds)
Published: Thu Jul 14 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.