## 原文 part 1 """ Alright, let's go back to around 2014. This is how I used to write all my CSS. The way I would approach building something is by opening an HTML file and writing all the necessary markup for the feature I was working on. Once I was satisfied with that, I would add a few class names as hooks and then switch over to the CSS file to figure out how to select all that HTML and style it. However, no matter how hard I tried to keep my CSS organized and make things maintainable, it always seemed to be a challenge. We had rules and guidelines in place within our teams to try and keep things under control, but it was still a struggle. The end result would generally look fine on the screen or match the design, but the process itself was far from ideal. The CSS in every project I worked on was always the first thing to just spiral completely out of control into this unmaintainable spider web of chaos that everyone on the team was afraid to touch. So around that time, I decided to make it my mission to figure out what I was doing wrong and what I needed to do to come up with style sheets that I could revisit later on. 5, six months later and still feeling confident about the changes I was going to make to the project because I simply didn't have that. So I began consuming every piece of content I could find on the internet about writing amazing CSS. I watched every conference talk I could find, read every book, purchased every course, and devoured every CSS trick and article on CSS architecture. And then one day I came across an article written by this guy, Nicholas Gallagher. He is the creator of Normalized CSS and was working at Twitter at the time. The article was about HTML semantics and front-end architecture. In that article, he argues that the most reusable components are those with class, which are independent of the content. Instead of writing classes that describe the specific block of HTML we are building and then hooking into our CSS to style it, he suggests writing classes that describe the visual pattern in the UI we are trying to build. For example, instead of a class that describes a user profile, we should use a class like "card" that can be used to build anything that looks like a card. When I heard this, I was intrigued. Hold on a second, I thought we had reached some sort of agreement and there was a general consensus, at least among individuals whom I considered to be more intelligent than myself, that including presentational information in your HTML was a big mistake. It was like shooting yourself in the foot. This approach only led to difficulties in maintaining and managing the code, making it extremely challenging to handle and keep in check. But Nicholas was suggesting that all the effort I was putting into trying to make my CSS maintainable was actually the very thing that was causing CSS to become unmaintainable. And he mentioned that if I wanted things to be maintainable, especially on a large scale, I should do the exact opposite of what I believed I was supposed to do. He was working at Twitter, a massive website, so his perspective held weight. If all your instincts are wrong, then the opposite must be right. So, at this point, I made the decision to completely disregard all the beliefs I had about how to write CSS and what I considered important in terms of my markup and the placement of information. I chose to sacrifice the purity of my approach and stop worrying about including presentational information in my HTML. Instead, I treated my CSS as a sacred space that needed to be protected at all costs, completely unaware of the actual site I wanted to create. In terms of content, I wanted to begin writing my CSS in a manner similar to a third-party library, without any knowledge of where it will be used or who will utilize it to create something. So, I would create classes like this, such as this chat notification class. And I would observe. Alright, so, on the screen, this appears to be a card, so I'll refer to it as a card from now on. And whenever I come across other cards, I can use this class. However, I started encountering other elements in the user interface that were very similar to this card. The only difference was that instead of having a shadow and being limited to a specific width, these elements, which were otherwise identical to a card, were full-width with no shadow. They had the same border radius, background color, and padding. Essentially, they were cards without shadows, extending to the full width of their parent element. So, with the intention of maximizing reusability, I decided to divide classes like "card" into multiple classes. Therefore, the "card MD" class is responsible for determining the maximum width of the card, while the "card Shadowed" class is responsible for indicating that the card should have a shadow. This approach allows me to use the "card" class without the modifier if I ever want to create a card without a shadow. But then, as I was going through the CSS for this kind of thing, I noticed that the "card shadowed" class only served one purpose. It simply applied a box shadow, and that box shadow wasn't specifically related to cards at all. There were other elements in my project that had the exact same box shadow, even though they weren't cards. So, in the spirit of reusability, it became clear that maybe I should just name this class "shadow". Then, whenever I want to give anything this shadow effect, I can simply apply that class and be good to go. So you can kind of imagine that things that used to look like this started to look like this. And this probably looks familiar to most of the people here. If you're not used to it, and I don't know why you're here, this is a celebration. But, you know. You probably know what happened next. At this point. I realized that when I write my CSS in this way, I can easily build various UI components without having to write CSS from scratch. I can simply use the existing pieces I have created. What's even more interesting is that I can start a new project with a different design and still use the CSS files from the previous project without needing to write any new CSS. This allows me to implement unique and customized designs effortlessly. This realization led me to consider the potential of extracting this approach into a library or framework, which eventually became Taylor CSS V. The design of MacOS at the time of its release resembled this approach. So, let's skip ahead to the present day. It's been almost six years since then. I believe it was October 31, 2017, when we were working on tail and CSS. Three, dot, 3. It has witnessed numerous changes and improvements. You know, the framework has been installed over 25 million times. This makes it the most downloaded framework, the most downloaded CSS framework on all of Mpm. Which is absolutely mind-blowing to me. The framework, in total, has been installed 300 million times. There have been over 3.3 million unique installations of our intelligence plug-in. And these are truly unique installs, like on a separate account on a computer, or if you download it again after uninstalling it, it doesn't count. So, there are literally millions of people using this tool. But it's absolutely astonishing. And it's utilized by over 5 million open source projects on GitHub. Sorry, Craig Frederick, I know you're the only one who's supposed to use that animation. But I'm trying it today. Even major companies like Shopify are using Tailwind and CSS now to build things like this new marketing site experience that they released a couple of months ago. Netflix is using Tailwind, especially for their global top 10 page. OpenAI has all their marketing sites built with Tailwind and CSS, and even Chad G. BT itself is built with HTML and CSS. And there are several elements in ChatGPT that are also built with HTML and UI. So, every time you chat, Tbt logs you out of your account because you haven't used it in a while. You see that little model that pops up? That was me. Hurry up. Mr. Beast is using Taylor with CSS for some of his brands. And what I love about this example is that the original vision for Taylor was to create a layer of abstraction that still allows you to do absolutely anything. And this is not what I had in mind. Yet, they were still able to build amazing things like this, with Taylor. So, at this point. When a new website is released, I'm often more surprised when it's not built with Tailwind than when it is. And that's just an incredibly amazing feeling to me. So, as I mentioned before, the framework has been around for almost six years now, and there has never been a single occasion where we've managed to gather a group of people who enjoy both HTML and CSS in the same place. There has never been a single local meetup or anything like that. So, this is the very first time ever that we've attempted to bring together a group of people from the Tailwind community in one location and celebrate what we've achieved here. I just want to express my heartfelt gratitude to everyone who made it here. Some people flew in from Germany to attend this event. Thank you very much for being a part of this. Thank you so much for being a part of the Tamil community and helping us develop this into what it is today. So, with that being said, you know, we have developed this highly capable tool that is utilized by millions of individuals to create some of the largest websites in the world. Where do we proceed from this point? What are our main priorities? That's essentially what I would like to discuss extensively tonight. So one of the things that we've always invested in, that's always been really important to us, is ensuring that Taylor always allows you to fully utilize all the latest and greatest features in CSS and the web platform. We always stay updated on what's new in CSS and what new features have been released. We also keep an eye on the experimental features being tested in different browsers, so that we can find ways to expose those features to you. This way, you can build amazing things with them. So, let's go over some of the latest and greatest features in CSS and how you can make the most of them in Toland. Joining us today is the up-and-coming YouTube star, Sim S Aliko. Thanks for being here, buddy. Alright, let's get started. First up, we have a fantastic new addition. Get ready for some collaborative coding. Sounds exciting, right? Let's dive in. In 2018, we find ourselves in 2023. Now, we will delve a bit deeper into fendering, a div here. So, yeah, I'm just going to quickly demonstrate five examples and showcase some impressive features that you can achieve with Tailwind. Perhaps you are already familiar with it, or maybe you are not. Either way, I am here to discuss some exciting aspects. So, let's get started with this small demo website. It's like a trendy brand that has this refreshing lime green touch to the icon here. And we also have this settings page. It probably looks similar to many other pages that you all have created before. One downside of these native HTML controls is the default blue appearance. It's a bit disappointing, considering how accustomed we are to customizing things as web developers. It's frustrating that we can't modify these native controls. Well, one thing I recently learned about Taiwan is this new little class called "accent". So, if we locate this shower player and control the checkbox right here, you might not be aware of this, but we have a utility called "Accent". And this utility provides all the colors in Taiwan, so we can easily find our lime color by selecting 400. And, if I mention this, come on, I said we're mob programming here. I'm not going to assist. Oh, we probably need to refresh. Okay, there we go. So, we can simply add this "accent" class to any of these utilities. This utility class can be applied to any of these controls here. Take a look at all the cool stuff we get. We have the focused and active states. We also have the when we hold it down state, which is slightly different for both of those states. But we don't have to do this for every single one of these, right? We can remove this and go to the root div here. Then we can simply add accent lime, with a value of 400, just like that. And we will have that for all of these controls, just like that. If we hover over this class in the HTML, we will see that it's setting the accent color CSS property. Just something that I had never heard about before. But I saw this in a release from Tailwind. So this is. I thought it was just like a nice, easy little example. How Tailwind helps me stay up to date with what's going on in CSS. At this point. I've been using it for about five years, and I feel like I've basically outsourced that entire job of staying up to date with when browsers are ready for things. Taiwan does a great job of educating us about property readiness and usefulness. It also provides us with tools to be more daring and experimental if we choose to. Now, let's move on to this second demonstration. This is where the majority of the excitement lies, which is another Seinfeld reference that clearly shows Adam's fondness for the show. This is a fun little demo of an online newspaper. Let's go ahead and locate this page. It has a cool appearance, but it would be nice if we could make the title the main heading, filling up the entire page, similar to what you would see in a traditional newspaper. The usual way to achieve this is by using responsive prefixes and standard text size utilities. So maybe when we're down small, 7x is okay. Maybe actually down to here. We want to start it off at 5x. And that looks alright. But maybe when we get to a small screen, we go to 7XL. You probably all know this. So once we get to a certain size, the tech should jump up. And maybe instead of 7, we can go to 9, something like that. But there's a new technique or approach that I hadn't really considered before, which is Fluid. It involves setting the font size to adjust dynamically based on the width or height of the viewport. Unfortunately, Taylor doesn't provide a dedicated API for this. There are no built-in utilities, but you can achieve it using arbitrary value syntax, which is represented by square brackets and can be applied to any property in Taiwan. We have complete freedom to do whatever we want here. So, I could set this to be 60 pixels, and we will have a width of 60 pixels. However, I can also set it to be 10 VW, and now it will be 10% of the total width of the viewport. And if I start making changes, it will adjust accordingly. We can observe that it sort of reduces and expands. So perhaps let's increase this to 20, something along those lines. It appears quite satisfactory here. Now, when it becomes too small, it tends to collapse. So maybe we'll go with 19, something like that. That seems quite suitable. And then, when it becomes too large. We can observe that it also expands excessively. So why do we utilize another feature from CSS, known as the min function? This will ensure that it never exceeds a certain size, let's say 100 pixels. Let's see how it appears, maybe around 120 or 130 pixels. Now we can see that if our viewport enlarges, the text remains limited. This is just another illustration of the initial example we witnessed earlier, demonstrating the usefulness of a top-notch API utility when it is fully developed and ready for practical use. But any CSS feature that you're excited about that you hear about on Twitter or you read a blog post about. I love that you can experiment with it, right, and tell when without having to wait for them to add or a new release to come out to support that feature. So that was a fun little. Demo, I thought. And let's go back and go to our third demo. And this is a problem a lot of you have probably run into before. This is kind of, you know, a hero treatment, something you maybe see on the homepage of a product or a website. And this H1 here usually receives a lot of deliberate attention to how it is laid out and ensuring that the words wrap in a certain way. And we can see here, when you start with this, maybe this was the intention, you know, for this design. But as we made changes, it doesn't have a pleasing distribution anymore, right? We have some orphan words here at the end. One way I have solved this in the past is to say, well, we like the way this looks when it breaks right after noon. So let's make it small again. Come find new. And maybe we can just use a good old break tag right here. Just like that, right? That works. And as we grow larger, it seems to function well. In fact, it appears to work exceptionally well. However, if we become too small, we encounter these peculiar situations where the space is no longer evenly distributed. The brake isn't functioning. So, you start trying different things. Maybe you add a class name here. You hide it, and then you show it on small screens. But this is quite messy. Wouldn't it be great if there was a CSS feature that took care of this for us? And it turns out there is. So, let's go ahead and remove it. I'll go to age 2 and type in "balance". And I'll see this text balance utility. And just like that, we have three lines. Now we only have 2, and that's it. It's finished. Hey, check this out! This is a new feature that will be included in the next version of Tailwind. It utilizes a CSS feature called text wrap balance, which already has some support and will have even more in the future. The really awesome thing about this property is that it's progressive and supports progressive enhancement. So, if you're using a browser that doesn't support it, it will gracefully fall back to the previous behavior without the class. I don't know if you've ever worked with this before, but it's really cool. Just take a look at this example. See that word hanging there all by itself? Apply this feature and it will intelligently wrap all three words together. Pretty cool, right? So, I thought it would be fun to show this off as well. Man, Adam even installed the Vim extension on here for me. This is really cool. What a great friend. Alright, let's move on to demo 4. This is another cool feature. And this is another new feature that will be supported by Taylor in CSS. We have this small selector right here, just a simple radio button with native input type radios. And we can see that we are making some custom modifications to give this style a more dynamic look. We have added a border, a ring, and a background color here. However, the CEO has requested that these elements stand out a bit more. So, we want the active class to be more noticeable. If we examine the HTML code here, we can see that we are using the hover effect to change the background color to zinc. 100, this is the general label element. So if we were to set this to Indigo, 600. Then maybe this is more like what we want the active state to look like. But obviously, we only want to set this class if the input is checked, right. Well, if I undo that. That had some old history in it. If I get rid of this class. It would be really nice if I could do something like checked background indigo. However, the label itself is not checked. It is the input that is checked. And until now, we have never had a way to style a parent element in an HTML tree based on the state of a child. The Utility and Tailwind group allows us to do the opposite. We can assign a group to a parent element and then style a child element based on whether the group is hovered, for example. So we have been able to move in that direction. But we have not been able to move in the other direction. Back in the day, if you used jQuery, they actually had a property that allowed you to do this. It was really cool. Well, CSS is now adding this feature as well, and Tailwind has support for it through. This feature includes a useful dash and square brackets. We have observed this previously. We can input anything we desire to hear and it will be spoken. If I have a child that fulfills this requirement, it becomes a relational collector. And if it fulfills the condition within the brackets, then this class is applied. We are aware that inputs have a condition that can be checked, particularly for radio elements. Therefore, if we state that it has been checked, let's change the background color to Indigo. 600, I'm going to remove this old class, right. Check that out. Normally, at this point, to actually pull off a design like this, I'd be reaching for something like react state or something, pulling that in, and then figuring out which of these options as a mapping over them are checked and then conditionally adding classes. But we don't have to do that, just like we don't have to do it down here. We can style the input with a checked pseudo class and how we can style this label with this new has relational selector, which we can see right here. Just create this CSS rule. This is the new CSS feature that we can use just like this. But our text is a little off right here. This is a little too flashy, and I believe we can improve its appearance a bit. This is the label right here, public access. And once again, it would be nice if we could achieve something similar, right? Has checked. And let's make this white. However, this div doesn't have anything that is checked. This is actually outside of the tree that contains input. It's in a sibling tree. Well, the label is the lowest common ancestor of both of those siblings, right? So just like we used to do a group for the other case that we talked about, if we put a group on the lowest common ancestor of both these things that need it, and then we use group paths just like this. Now we can apply that. So this is like a really cool kind of compositional point where we get to use these new features. But the arbitrary syntax let us do things that normally we would have to do a lot more work to do. We can handle everything internally. It will function on both the server and the client side, regardless of the technology being used. We can also apply the same approach here to make this text more approachable. Let's assume the group has checked it, and we will modify this text to go with it. 200. Now it looks much improved. Quite impressive. I was really impressed when I first saw this. Once again, I discovered it through Tailwind. I had no idea that this was the future that was rapidly approaching. However, I believe that many people will start using Sass and CSS. And in Tailwind, once it becomes completely stable. So, it's really cool stuff. Okay, this is the final demonstration. We will discuss container queries. Has anyone actually used container queries in a production environment? Has anyone experimented with them at all? Have you tried playing around with container queries and CSS? Oh, container queries are really awesome. Okay, so we all know about responsive media queries. We can apply a specific class when the screen reaches a certain size. Currently, we have a grid with a single column. Once we reach a certain size, we transform it into a two-column grid using responsive media queries, which we implement through the responsive utilities in Tailwind. If we look down here, we can observe that at the small screen size, which is 640 pixels, we switch our grid to a two-column layout. And let's say we're working on this design. It looks pretty cool, but we want to make the first testimonial stand out a little bit more. We want it to have a featured treatment. Okay, well, one way we could achieve that is by making it take up two columns on the larger screen. We want to keep it single on the smaller screen, in the smallest column. But once we have the two columns, let's make it stand out. So we could come to this div and make some adjustments. Well, we could try adding a class name in this loop that indicates if we are the first element, and then apply a span with a width of two. However, we don't actually need the index for this. We can simply call the span with a width of two. Let's test it out first. So if I refresh the page... My mom, on the other hand. Let me check. Oh, oh. Let me confirm that I'm on the right thing. Page, yes. Container query. Yeah, that doesn't look good. Let me go back here. Wow. I think I did something. Let me grab the beginning here. This is a useful technique for live coding demonstrations. Actually. We'll see if this works. Whoa. What in the world. Oh, this thing is really annoying. Look at this. Alright, you know what, I actually just remembered I was planning to switch to Firefox anyway. So let's just uninstall Chrome and give it another try. We'll forget everything that just happened. Alright, here we go, Firefox, there we go. Alright, I appreciate the support. Thank you, Mob. Alright, this thing isn't freaking out, oh. Something's happening here. How do you open the terminal? Restart the bill. How do you access the terminal? I know how to open my terminal, but as Adam's computer control. Fast refresh. Wohoo. That's a strange one to come across. Let's see. Okay, I think we're good. Look at that. Look at that, perfect. Alright, so let's try this again. That was fun. I enjoyed it. Let's remove that. I never use Firefox, but I can hide toolbars like that. There we go, cool animation. So, in a single column, we want to display it in two columns. We want to give the first testimonial a special treatment. One way to do this is to ensure that it still functions properly. Let's try not to disrupt the actual process. Let's use a span of two. This should work. Okay, I'm relieved. I was a bit worried there. Thank you, thank you, thank you. So now every testimonial will span both columns in the grid. Right, and if we only wanted it for the first one. Maybe we would do something like grab the index here and then say, if I have zero, we apply it right. But you can actually do it even better. With just the first prefix in tailwind. Check that out. Pretty cool, right? And if I hover over this, you'll see this uses the first child pseudo selector, so that's pretty neat. I can't even do something as simple as odd. And I end up with every odd one, which is quite amusing. However, this is a simple method to provide the first testimonial with more prominence. Now we actually want to change the treatment because it looks a little unappealing when it takes up so much space. The text is a bit small and needs a little more room to breathe. We need to make it stand out a bit more. So at this point, typically, I would solve this problem by highlighting a featured element. We would label it as "featured" and then perhaps we would retrieve the index again and designate it as the featured item. If it were the first item in the array, then we could proceed to the testimony section and use the new element to give it the updated treatment. However, this is not necessary, right? This is what makes container queries really cool. So, let me show you how this works. We're going to dive into the code. I'll add a class to the root element right here and label it as "container". And now, we can define new adjustments depending on the size that the element occupies, similar to how we respond to utilities. Let's adjust our user interface based on the size of the screen that contains the queries. Let's adjust the UI based on the actual size of the element. For example, if I go to this block where we display the body of the testimonial, I can specify that at LG, this is a container query and it indicates a minimum width of 32 rem. Let's increase the text size to XXL. What's happening here is that this card is occupying more than 32 rems, so it's receiving the new treatment. But once we make it smaller... Then we have another issue in our code because we only want this to occur when we are viewing the website on smaller screens. So when we return to the first column, the first testimonial occupies the same amount of space as the rest of the testimonials. Therefore, it receives the same treatment. However, when we switch to two columns, the first testimonial occupies enough space for the container query to take effect. Pretty cool, right? We didn't modify anything regarding this testimonial invocation. The person making the call didn't need to have any knowledge about it or how to invoke it to transform it into a prominent card. They simply had to display it in a sufficiently spacious area. So, let's proceed and continue from here. Text large, let's make it, font semibold. And at large. Let's make the. Tracking a little bit tighter. And we'll come up to here to P 6, where we have our padding. And let's just say, when we're large. Let's go ahead and make P palling. It's looking better. We have six units of spacing here. So maybe we should allocate 8 units for larger space. And yes, that's starting to look quite nice. And again, if we scroll down to where we're rendering this. If I switch back to "odd" instead of just "first", it gives a somewhat funny result. But you get the idea. We have created the testimonial to render the appropriate version of itself based on the available space. And so, the caller doesn't know, the car doesn't care. However, this card is rendered whether it's on a small screen or a big screen; the overall screen size doesn't matter. What matters is how much space the container has. So, it's a pretty awesome feature. Let's do one more thing. Actually, I'm going to come and just grab this image. And we'll come back up here. And these all have an image for the actual company where the author works so we can drop an image right there, which I think looks good on this featured one. But these, it doesn't have enough space. So let's actually start this out as hidden. And then if we're in a large enough container, we'll go ahead and bring it back to. So pretty cool. I believe that container queries, you know. Once people understand how to use them, they will become more widely known. I think they will replace a significant portion of the work we currently do with media queries, due to all the advancements we are witnessing here. Once again, we always receive the appropriate treatment based on the size, which I find particularly useful if you are unsure how your components will be displayed. For example, let's say you have a newsletter sign-up form that you want your team members to be able to place anywhere. Perhaps they want to place it in the footer, where it spans the full width of the screen and includes additional information. Or maybe they want to place it in a smaller version when the page is resized, or even in a sidebar on a larger screen. In this case, container queries are the perfect solution because they allow the newsletter component to adapt to the available space without the need for the color to be pre-determined. There is a really cool technique in CSS that is now available with the official container queries plugin from Tailwind. That's what we'll be using today. And there's one more interesting thing I'd like to show you. If we zoom out here and focus on just the first column, the featured one, we'll notice something at this X and XL breakpoint. Oops, so close. We'll see it at this XL breakpoint. Let me zoom out a bit so we can see the code. We understand the concept of this four-column grid. We can observe that in Excel, when we have 1280 pixels, we have four columns, and now our treatment appears a bit odd. Let's actually shift it over first. And in XL, we will begin this column at 2. So that's a clever technique we can employ with the call function, starting it at the second column. A second column in the grid. And this appears quite impressive. It's not terrible, but you can notice some awkward gaps in this design, and it would be really great if we could eliminate them. Well. There's another amazing feature coming to CSS. Let me demonstrate how it works. I'll go right ahead and talk about grid rows. These are the grid row utilities included in Tailwind. They set the grid template row property. However, as with anything in Tailwind, we can set our own using the arbitrary value syntax. Take a look at this, Mason. I think I misspelled it. Mason, Reed, grid rows. There we go. Alright, let's try that again just so you can see what happened. Delete that. We have these spaces. I'm going to apply this to masonry. And this is another new feature that will be added to CSS. If you have ever tried to build this before, especially in a way that is adaptable to a responsive layout like this, you know how challenging it can be. It is much more difficult than simply adding a single class. But now, with this layout, all the spaces in between are evenly distributed, even though we have cards of different heights in the columns. These are some really impressive things that you can achieve with modern Tailwind. I really enjoy everything I've learned about CSS since I started using Tailwind. I also appreciate the fact that you can experiment with it using this flexible syntax. That's what I wanted to demonstrate to you today. Thank you very much. And now, here's Adam. Great work, dude. I'm pretty impressive. I believe I've reached my maximum potential. Do you have it all memorized? Yeah, that was fantastic. Thanks, Tim, I truly value going through some of that information. I'm really enthusiastic about many of these features. So next, I suppose I would like to discuss some of the things that we are doing with Tailwind, the tool. You know, Sam talked extensively about the developer experience improvements we are working on, in terms of making these new CSS features more accessible to you. However, Tailwind as a framework has two distinct aspects. There is what we allow you to build, and then there is the experience of configuring, working with, setting up, and using it as part of your tool chain. So I would like to discuss some of the improvements that we are currently working on in that regard. Before I delve into any of these details, I must mention that it is quite fascinating, and some aspects of it may be slightly unconventional. I want to discuss the concept of "like". It is a value that we highly prioritize in terms of retaining talent and something that we deeply care about. When we consider any changes we make to the tool, we always keep in mind the importance of backwards compatibility and stability. We understand that nobody wants to waste time upgrading and migrating to a new version of something when everything was working perfectly fine before. So, I have some new features that I would like to showcase here, but... All the things we're discussing here are not groundbreaking like the paradigm shifts in Taylor CSS V 4.0. This is more like Taylor CSS v 3.4. Use it in the next version if you want this type of functionality. So let's see if this is working. Cool. So, Taiwan, the Black album, you know. So we've been working on an internal project that we're calling Taylor and CSS oxide, which is sort of our vision for the next evolution of Tail in CSS, as has sort of an engine for generating. And I want to talk about some of the improvements that we're trying to make there and then walk you through a demo of how some of it works. So you can sort of see what it looks like to apply this stuff in a real project. So the first thing we focused on was consolidating the tool chain, whatever the heck that means. If you've spent any time working with Taylor, you've probably realized that tone isn't the only thing you need to set up in order to process your CSS on a project you're working on. Even in our own documentation, we recommend installing Tailwind. After using CSS, install auto prefixer if you want to handle imports during the build process. If you want to transpile modern CSS syntax features, you need to address something like post CSS preset end. In the early days of Tailwind, this made a lot of sense. It felt like a big deal to ask people to fully commit to a new tool like this. However, as we discussed earlier, I showed you some of the impressive projects and teams that have adopted Tailwind. I believe there is a significant number of people out there who simply want to install Tailwind and not worry about anything else. It takes care of all your CSS needs, allowing you to focus on other aspects. This is one of the things we have been working on. So the oxide engine that we've been working on has built-in support for import. So anytime that you have some CSS stuff that you want to reorganize and move into a different file. You don't have to install POC SS import anymore. You just do it. And it just works. Same with vendor prefixing. So in the past, we've always asked you to install auto prefixer, add it to your prosthesis. Can fig file, otherwise you might be missing necessary vendor prefixes for browsers that you need to support going forward. While we're still probably going to make it possible for you to disable that if you want by default. We're just going to handle that for you so you don't have to think about it. Syntax transformation. So I briefly mentioned the CSS preset env. There are many modern CSS features that can be translated into a syntax supported by current CSS. One classic feature that will resonate with everyone is CSS nesting. We have had support for compiling nesting through tools like SaaS and Less for a long time. You can also achieve nesting with PostCSS, using plugins like PostCSS Nested or the built-in PostCSS Preset Env. Additionally, we have the Tailwind CSS Nesting plugin, which makes it easier to use nesting with Tailwind in a way that is compatible with other tools like PurgeCSS. Our CSS nesting feature has been officially implemented in several browsers. However, not everyone can utilize it as it is not supported in browsers like Safari 15, which is still widely used. But don't worry, we can take care of that for you. Instead of having to install a plugin, you can simply use nesting in your custom CSS and we will handle the transpilation process for you. Another one that people are currently getting excited about is the concept of modern. Wide gamut and color space are topics that some people may be familiar with. These include Lab or LC, H color spaces, which are known for their vibrant and intense colors that can only be displayed properly on high-quality screens. While most smartphones are capable of rendering these colors, many desktop monitors cannot. Additionally, these color spaces are only supported by relatively recent web browsers, making it difficult to ensure consistent color display across different platforms. However, there are mathematical calculations that can be performed to determine the closest RGB color that is supported by older browsers, allowing for a fallback option. This is just one example of how we will handle such situations for you in the future. So you can simply utilize modern space technology. And individuals whose devices do not support it will simply see the nearest fallback color. No configuration is necessary, Taylor, just follow these instructions. So how does this all work under the hood? All these things are powered by this new tool called lightning CSS, which is developed by Devin Gubbitt in the parcel team, which is this really modern rust-based CSS transformation platform. That's just incredible. You know, in the past, we used to recommend using auto prefixer if you needed to add vendor prefixes. Now, we can say use lightning CSS if you want to add vendor prefixes because it does the same thing and it does it faster. Or if you want to add import support, install post CSS import. Now we can just say use lightning CSS. Lightning CSS is actually the answer for basically every single feature that you might install a plugin to handle with post CSS. So instead of just trying to tell people to integrate this themselves, we just decided, let's just integrate it and take advantage of all the benefits that we get from that. And the better developer experience. Once again, I will guide you through a demonstration that illustrates how this process actually functions. Okay, so the next topic I'd like to discuss before we proceed to the demonstration is improved performance. Blinding CSS, as I mentioned earlier, is a native library written in Rust. This means it can take advantage of features like multithreading and parallelization, which are not easily achievable in Node.js. This provides us with ample opportunities to make things faster than ever before in Node.js. By utilizing Blinding CSS, we can achieve significant performance improvements in vendor prefixing and code generation. We can leverage these improvements right out of the box, following the lead of tools like Lightning CSS and other developer tools that have been seeking ways to optimize performance by incorporating native languages into their coding process. We have even rewritten some core components of Tailwind in Rust to take advantage of this approach. One of these components is the parsing layer of Tailwind, which scans all your HTML or React files to extract the necessary classes and generate the corresponding CSS.This is similar to a task that can be parallelized perfectly because it is essentially a pure function that receives input and returns an array of classrooms. Therefore, we can divide this task among all the cores of your computer and complete it much faster than we could with node. Here's an example of how their performance has improved. In television S3.3, I have a realistic project that I'll use for this demonstration. When I measure the performance of doing a production build with minification and other optimizations in Towel and Three, we're getting compile times of about 330 milliseconds using the new Oxide engine. But when we do the exact same thing, the whole composition, it only takes about 130 milliseconds. So it's more than twice as fast, which is really exciting. And there's still a lot of room for improvement. We're still doing things that we could optimize, like cleaning up unused CSS. I'll show you all of this, but it's really exciting, cool, and fun. Plus, it's a good excuse to learn a new language, which is always fun too, selfishly. So, the third component of this type of oxide engine is a simplified configuration, which may not sound very exciting at first. But a simplified configuration can be quite effective. But here's an example of something that people frequently encounter and often complain about on Heart, Discord, and GitHub. Essentially, every day, someone creates a new file and adds some classes to a newly created component. When they open it up in the browser, they notice that certain elements are missing. The border radius, for instance, is incorrect, even though the class is correctly specified in the corner. It leaves them wondering what is happening. Like, why isn't this working? And inevitably, the answer is always that they forgot to go into their tail and get the fake file, update their content array to include this new folder where they've added this component or whatever. And when they do that and restart to build, everything works. But it's just like an annoying little paper cut that makes the experience worse for everybody. So, one thing we have been working on is what we have been calling automatic content detection. By taking advantage of the fact that we have rewritten a lot of code in both toe and rust, we are able to accomplish more work in less time compared to our previous engine. We have developed heuristics and algorithms to make educated guesses about the location of files in your project based on the files you already have, their locations, and the file extensions being used. This has been a result of our collective efforts. Like a very, what feels like very bulletproof. You know, a feature that allows you to not configure content at all, that whole content thing, and you're telling can fix disappears. And Taylor just knows where everything is, and it just works. And it works perfectly. And I have a couple of other configuration things that I want to talk about, but I'm going to save that for the demo. So I want to look at some actual code back at my comfort zone, you know. So what do we have here? Okay, so I have this demo project here, and as you can see, it has a large components folder with many historical components that you would typically find in a traditional and complex application. Let me know if the configuration file is clear enough. By the way, the sponsor is significant. Yeah, it's fine. So, you know. We are currently installing Post CSS import. We have already installed the nesting tendencies. And of course, Taylor and auto prefixer are included in our app's CSS file. You know, I'm importing all the tailwinds, a few players. I'm also importing some custom fonts into the base layer, and those are located in this file. So that's why I'm concerned about the posts. We import things. You know, I have some custom typography styles, and then the typography styles, there's like some nesting and stuff like that. So I want to process this nesting too. So that's why I've got all the stuff sort of installed. So, let's go ahead and run the build. Run. Build. The latest version. That's basically the performance times I was talking about, right? Like 338 milliseconds. 241 milliseconds. 253 milliseconds. They just keep getting slower and slower the longer you go, you know. So, let's switch over to the oxide engine. I'll just run NPM run build oxide, which will run our experimental insider version of Tailwind. It's basically doing the exact same thing. Oh, it only takes 136 milliseconds. 136 milliseconds. You may believe that there is a console log in the code base. Even if it says "console log done in 136 milliseconds". But I can assure you, that's not the case, no. Oh. There we go, you see. It's simply very, very stable, alright. So now that we've switched over to this new oxide engine, let me demonstrate how we can simplify the configuration and still ensure everything functions properly. First, let's address the CSS issue. I'll open the output CSS file here... Oh, it seems that I need to open the main one to figure this out. Why isn't it displaying all the tabs? Are you an animal? Alright. Okay, we'll reach our destination. We'll ensure everything is in its proper place. App, dot CSS S out, dot CSS. Alright, so let's examine the inputs and outputs here. This is manified, so I'll compile with the Unminified 1. So with the NPM run, I've got like a dev script that does the same thing. But without minification. 136 milliseconds. Who would have guessed. So, let's just take a look here for like typography class. You can see that it's processing the nesting, you know? So all of those 9% symbols are gone. So let's just go to the post CSS and fig and just get rid of the post. He says import. I run it again. Oh, cuts lower. Oh, still. But still, all of that stuff, the import is handled because the typography was in the separate file. Nesting is still being managed. Alright, let's remove the nesting. Oh, the nesting is still present. So, it turns out we didn't need to remove it. Let's search for some Webkit prefixes or something. I believe Webkit appearance is kind of the classic one, and. Let's remove the auto prefixer. Do we need it? Nope, all vendor preferences are still being added. """ 生成20个问题 Here are 20 important questions for developers based on the provided content, along with their corresponding answers in Chinese: 1. 如何描述作者最初写CSS时的方法和遇到的挑战?(答:作者最初通过在HTML文件中编写所需的标记来构建功能,但是CSS的组织和维护始终是一个挑战。) 2. 作者在读到Nicholas Gallagher的文章后,对CSS的维护有什么新的认识?(答:作者认识到之前试图使CSS易于维护的努力实际上正是导致CSS难以维护的根源。) 3. 作者对传统HTML中包含表现信息的看法是什么?(答:作者曾认为在HTML中包含表现信息是一个大错误,但是Nicholas Gallagher的观点改变了他的看法。) 4. 作者如何改变了自己写CSS的方式?(答:作者放弃了之前要在CSS中保持纯净和避免在HTML中包含表现信息的观念,转而将CSS视为需要保护的空间。) 5. 在作者改变CSS写作方式后,他发现了什么好处?(答:作者发现他能够轻松构建各种UI组件,而无需从头开始编写CSS。) 6. 作者将CSS类命名为哪种方式以实现高度的可重用性?(答:作者将CSS类命名为可以描述UI中视觉模式的方式,而不是具体描述正在构建的HTML块。) 7. 作者如何逐步将"card"类分割为更多具体的类?(答:作者通过添加修饰符类,例如"card MD"和"card Shadowed",来实现高度的可重用性。 8. 作者为什么将"card shadowed"类改名为"shadow"类?(答:作者发现"card shadowed"类只是应用了一个特定的盒子阴影效果,并不特定于卡片。为了提高可重用性,作者决定将其改名为"shadow"类,以便在任何需要盒子阴影效果的元素上使用。) 9. 作者使用Tailwind CSS的哪些功能来构建UI组件?(答:作者使用Tailwind CSS的类来快速构建UI组件,例如卡片、标题等,并通过组合不同的类来定制组件的外观和样式。) 10. 作者在使用Tailwind CSS时遇到了哪些困难?(答:文中未提及作者在使用Tailwind CSS时遇到的困难。) 11. 文章中提到的Tailwind CSS版本是哪个?(答:文章中未明确提到Tailwind CSS的版本。) 12. Tailwind CSS在生产中被哪些公司和项目使用?(答:根据文章提到的内容,像Shopify、Netflix、OpenAI、Mr. Beast等公司都使用Tailwind CSS来构建其网站或界面。) 13. 作者提到Tailwind CSS的下载量和使用情况吗?(答:文章中提到Tailwind CSS是Mpm上下载次数最多的CSS框架,在GitHub上有超过500万个开源项目使用它。) 14. 作者提到了Tailwind CSS的未来发展方向吗?(答:文章中提到作者将讨论一些关于Tailwind的未来优先事项,但具体内容并未提及。) 15. Tailwind的新版将支持哪些CSS新特性?(答:新版的Tailwind将支持import、vendor prefixing、syntax transformation和container queries等CSS新特性。) 16. Tailwind团队致力于改进什么方面的开发者体验?(答:Tailwind团队致力于改进配置、性能和工具链等方面的开发者体验。) 17. Tailwind团队如何提高工具链的性能?(答:Tailwind团队借助Rust编写的新引擎和native库来提高工具链的性能,如并行处理、代码生成和文件解析部分等。) 18. Tailwind在处理配置方面有什么改进?(答:Tailwind团队正在努力简化配置,并通过自动内容检测、性能优化和更好的开发者体验来实现配置的简化。) 19. 作者提到了使用Tailwind的某个功能时经常遇到的问题是什么?(答:作者提到了开发者在忘记更新Tailwind配置文件中的内容数组以包含新文件时,常常会遇到某些样式无法应用的问题。) 20. 新的oxide引擎是如何帮助解决Tailwind的一些问题的?(答:新的oxide引擎通过整合多个工具,如lightning CSS、css import等,以提高性能、简化配置和改进开发者体验,从而解决了Tailwind在历史上的一些问题。) 画图 Certainly! Here's a Mermaid chart depicting the process of how the author's CSS writing approach evolved over time: ```mermaid graph LR A[初始CSS写作方式] --> B[遇到挑战] B --> C[消化大量CSS知识] C --> D[阅读大量资料] D --> E[Nicholas Gallagher的文章] E --> F[重新思考CSS维护性问题] F --> G[改变写作CSS的方式] G --> H[以可重用组件视觉模式为中心] H --> I[拆分类名以最大化可重用性] I --> J[重新命名类名以提高可重用性] J --> K[更多的实践和观察] K --> L[发现CSS构建不同UI组件的能力] L --> M[实现设计定制化] M --> N[考虑将这种方法提取为库或框架] N --> O[创建Taylor CSS V] O --> P[长时间的发展与改善] ``` This chart represents the iterative process the author went through in changing their CSS writing approach over time. 根据作者的观点,之前的CSS存在以下问题: 组织困难:以前的CSS写作方式通常是在HTML文件中添加所需的类名和样式,但随着项目规模的增长,CSS的组织和维护变得困难。尽管有一些规则和指南来尝试保持CSS的可维护性,但依然难以有效控制。 不可重用的样式:之前的CSS写作方式更倾向于为特定的HTML块编写类名和样式,这导致样式很难复用。与其为每个具体的HTML块编写类名和样式,作者认为应该使用描述UI视觉模式的类名,提高样式的可重用性。 HTML和CSS的耦合:传统的HTML/CSS分离原则认为在HTML中包含表现信息是错误的,应该保持两者的分离。然而,作者通过采用相反的思路,将CSS视为可重用的空间,并在HTML中包含一些表现信息,达到更好的可维护性和样式复用性。 可维护性问题:尽管之前有一些规则和指南来尝试保持CSS的可维护性,但作者认为这些努力反而使CSS变得更难以维护。作者发现,通过采用一种以UI视觉模式为基础的CSS编写方式,可以提高可维护性,尤其是对于大型项目。 性能问题:文章中没有明确提到之前的CSS存在性能问题,但可以推断在较大规模的项目中,由于组织困难和样式冗余等原因,可能会降低性能。 Tailwind CSS通过优化工具链和引入新的性能优化技术来解决这些问题。 总的来说,传统的CSS写作方式存在组织困难、复用性差、耦合性高以及难以维护等问题,而Tailwind CSS试图通过改变写作方式和提供更好的工具链来解决这些问题。 # part 2 Answer my question base on following content: """ So now what took like configuring four plugins, putting them in the right order and making sure everything was wired up correctly? You just don't have to think about it with what we're working on now. You just install the newest part of town, and it just does all that stuff. It's pretty, pretty cool. And we're, we're hoping to find ways to even make this like posts S can fake unnecessary. And I don't have any official news on that yet, but we're collaborating with maintainers as a popular tools and frameworks to see what we can do to just get toe and detected, kind of like sass or less. The project knows you're using Taylor and you have it installed. It just runs it for you because this ends up being like the only really remaining piece of pot. SS configuration. Okay, so next thing is like the content can fix, right. So we've got the path, all of our content here. Normally, if I was going to like delete that, and then if I run like the other old build of tailwind, it's going to complain at me. Now, it's going to be like, no utility classes. We're detecting your source files, you jackass. Make sure that you have the content. But the newest version of talent that we're working on merely just warns you that the feature is experimental and may change, but it does work. And all the CSS is generated. So that's pretty cool. So on top of that, I mentioned like the. Modern color space stuff, you can see in the config here that I have got these. OK, Lch colors for these like really neon colors. If we go over here and take a look at the compiled CSS and we'll do the unmagnified 1. Let's, we can read that more easily. You can see that it's like, compile it down to lab instead of, okay, Lch. Because lab has better browser support, I guess. Than OK, Lch. But can represent all of the exact same stuff. And it's also found like the nearest Hex code that will work in any browser and added that as a fallback. So if the browser sees this declaration and can't parse it. It will fall back to this one and everyone will just get something pretty close. And I didn't have to do any configuration for this. This is just something that Taylor is gonna do for you. Thanks to all the awesome work that the parcel team has done on lightning CSS. So that's pretty exciting. So a couple other things that I want to show you. So one is like a really minor paper cut thing, but I'm like unreasonably excited about it. So I'm going to share it anyways. And maybe you'll be excited about it too, You're probably used to doing like at to one base, you know, putting all that stuff in all your files, or if you're using imports in the past, you have to switch to our imports in tax because I have a bunch of weird rules about how post CSS import cares about the order of things. In oxide, we've set things up so that you simply just import Taiwan CSS, and that's it. And you're good. And even doing that, all of the. All of the layers stuff still works because this just kind of inlines the exact same thing that you would have typed by hand. And hindsight super obvious thing. It should have been tailwind for a long time. But I really just love how it feels. It just kind of feels like I'm pulling up My CSS file. I've installed Taylor. Import talent, SS tailwinds in my project. Feels like the right experience. So that's pretty exciting to me. I'm reasonably exciting. The last thing I want to show you, and this is something I didn't talk about when I was just going through the slides, because this is the one where I'm curious to see what people actually think about it, because I think it's kind of cool. But you don't want to see everybody, thanks. You'll notice that in like our config file, now that we don't have like the content stuff, the only thing that's left in here is just like design token configuration stuff. I look at this and I kind of see it as like, this is like a CSS value. But because I'm in JavaScript to have to wrap it, that's kind of weird. Or what this list of fonts is in an array. And if I don't want to put it in an array. Because you often have to quote fonts. I have to use like different types of quotes to make sure they still have quotes in there. It just, it's always kind of felt like this clunky, not native thing. And I have this vision in my head of trying to make anyone feel like a more holistic. Native and sort of platform ish tool, even though, of course. It's always going to be a build tool that has to do all sorts of crazy stuff. So let me show you like an idea that I have that we've prototyped that. I don't know. I think it's kind of neat. I'm going to copy these colors. And go over to the CSS file. And I'm going to create a new selector called theme, which is kind of like the root selector in CSS, but it's targeting what we're calling like your theme. I'm going to paste in this stuff. We'll do a little bit of clean up here. Get rid of these quotes at our semi colon. So looks like CSS. And we're going to turn these into just vanilla CSS variable declarations. So we're just declaring a color called neon pink, a color called neon lime, a color called neon Siam. It's trying to build again, the deaf one so we can actually read it. And of course, like, we haven't changed the config. All right, so you'd expect these colors to still be there. But if I go back to the config, are you delete the colors, corona. What do you know, The clothes are still there, and that's kind of cool. And we could do the same thing with the fonts. So let's paste these in font. And get rid of the array. Just make it feel like CSS. You know it even like it's, you know, prettier, understands it. It formats it when I save because it just looks like CSS. Go back and delete this stuff from the config. Run the belt. What did we call those fonts like Satoshi, So there's our display fonts there, it's quirking, and then you look at this config file and it's like, that's weird. Why the **** does this file exist. And then you delete the file, and then you run the belt. And everything still works. And now, the only place that you're even thinking about talent is in a CSS file instead of in a JavaScript configuration. So there's still some weird stuff to figure out here. And there's like a lot of complex things that I've been wrestling with. How the hell I can represent them in CSS. Like one of the weird things is like, if I want to override all the colors, the best I've been able to come up with so far as like colors on set. And in theory. If we, I think this is, that doesn't work, so. That's just an idea. But those are the sorts of things that I'm still trying to figure out out how we can support all the things that till and currently supports with the JavaScript configuration. But like, I look at this file and it just kind of feels like, oh. This speaks to me in this hard to explain. So this is a path, and I'm really interested in exploring. And I think what excites me about it the most is that something that we hear about a lot from Tailwind users is. They almost feel like dirty writing CSS sometimes, even though there's a lot of good reasons to write custom CSS in your projects. People are always looking for ways to do it in their config file or something, instead, to keep everything in JavaScript. And I feel like if we can push a lot of the configuration to CSS. People won't be looking for, how do I add my custom font face stuff to my config file, Shouldn't that be in the config file. Well, no, just put it in your CSS. Don't add this weird, unnecessary layer in between everything. So I think if we can nail this from an API perspective, that, it's going to. Make people a lot more comfortable just using CSS for the stuff that you can just use CSS for, like keyframes and font. Face, and all that sort of stuff. So very early, very sort of experimental. But yeah, I'm excited about that. So hope you guys think that's kind of cool, too. So there's one other thing that I want to talk about, And. One of the things that we've always cared about, a lava tailwind and sort of the goal of the whole project has been to help you build custom designs. You know, that's like where we've sort of put our flag down. Like, sure, it's nice if you can just help people move faster. But if it's ever at the expense of people being able to build totally custom stuff, I'm not really interested in working on this project anymore. To me, Tailwind was meant to be an alternative to opening up a vanilla CSS file and doing everything from scratch and needs to have all that flexibility for it to still be something that I really believe in. At the same time, I really want to find ways to give people higher, jumping off points when they're building stuff so they can move a little bit faster. And that's something that we aim to solve with products like Taylor, Dui, where if you want to grab a pricing section for your website, you can find something that's pretty close to what you want. Grab the HTML. Paste it into your project, tweak it however you want, and you're moving a lot. We've got a new thing that we're working on that's sort of in that same vein that's taken a little while to really figure out how to get right. And it's still very, very, very early. But because this is the first time we've ever got anyone together in the same room to talk about Taylor and stuff. I thought I better show off some of the exciting early stuff before it's ready and give everyone sneak and make it a little more special. So we're working on this thing that we're calling Catalyst, which is our very first sort of fully componentized react application UI kit. I'm going to show you an example of a demo project that we've been working on that is built with Catalyst. So I can sort of explain a little bit more about what it is and then show you some code to. So this is sort of a demo kind of SaaS dashboard application for a ticket tool. Think of it kind of like an event, parade, alternative or something. And this is built with a bunch of predesigned, pre implemented components that are part of this package that we're calling catalyst. So the side bar layout comes from Catalyst, this date picker, date picker. The thing that everybody has won us to build forever comes from Catalyst. These dropdowns, part of cows, table dropdowns. Over here, you can click into orders. There's like a dialogue. You know. There's all the kind of form elements that you'd ever be looking for in any of the projects that you just, all the sort of building blocks that you need to build, like an application UI. We're trying to design them and build them with react and put them together in a way that you can get these into your project and move really, really fast. Now, I think a lot of people might be looking at this and thinking like. Well, this kind of looks a lot like what you get with telling you. I already with sort of like the application you, I kid. I can copy and paste different things. And that's mostly true. But what we've tried to do here is double down on sort of like a different part of the tradeoff curve. And the best way to sort of demonstrate that, I think. Is to is to jump into sort of some code and show you kind of what we imagine the developer experience to be like. So remember, this is, this is just an early preview. And there's, there's a lot more that we want to do. But I'm excited to still show you kind of where we are at with this so far. So first things first, I've got this empty next JS app that I've created. And I think it's important to that. What we're building here, although it is a react sort of component kit, it's not next.js specific. You can use this with a remix, You can use it with a vet based react app, or you can use it with an inertia app, for example. And all I've done here is just create a new app. Install Tailwind, and installed a couple of libraries that we're using as part of Catalyst. So I've installed React Aria components, which is another great project that's built by the same people who work on a parcel. Devin at Adobe, which is a really great, accessible sort of headless UI library, that's really battle tested with tons and tons of components. I've got framework motion for animations and stuff. I've got heroic ones, which is our own icon library. And I've got CLS X, which is just a great little utility for conditionally adding classes to elements. Everything else is just stock. Vanilla stuff comes with the next JS. So imagine you've downloaded Catalyst, whatever that means, right. So let's go back a folder here. You've downloaded Catalyst to be 0, dot zero, dot 0, dot 0, dot 0, dot 0, dot. Unzipped it. I pull it open. There's a components folder. I can just copy this components folder into my app. Ooh, that was a lot. And now the mental model here is you've just basically scaffolded all of the solar boilerplate and generic pieces. Building blocks, you need to build these sorts of applications. So what it's not is it's not a library that you install from NPM and consume like material UI or something like that. Those libraries are awesome for the right use case, but it doesn't really align with my vision for what I want to help people do with Tailwind. Which is build custom stuff. And I think if you're constrained to whatever Apis and configuration options and stuff that are exposed by the sorts of libraries they are using, it never really feels like your own code. And I always want to make sure that the things people are building with Taiwan feel like their own code. So I'm just going to pull open like a, a little page example that I've got here and, restart the server because God knows what port it's running on. 3000. The defaults. So we've got this beautiful white screen here. Let me. Yeah, we'll just kind of tie. I'll do a split screen. See if we can make them work. So where was that here. So, again, really early, but I'm going to show you a couple of little pieces. So say we wanted to build like a little create account form or something. We give you building blocks, like page heading. And we could say, like, create your account. And now we've got a page heading here with some thoughtfully chosen typographic styles and a thoughtfully chosen font size and line height and all that sort of thing. Now. So if you wanted to create like the fields, you know. I can pull in text field after the import tab from our components. These are all coming from this components folio that we just jumped in. And say, that's like, got a label of email. You know, okay. Maybe let's add some space between these elements. So I'd like a class name of space Y, 8, or whatever. Maybe we want to add another field, like for your password. And maybe we'll make this a type email. You know, all these props just kind of proxy through down to the root input that we're rendering. So you want to add like some descriptive text or something. You know, we can add a description. Like must be at least 12 characters. You know, so. The thing I think is interesting is, like, well, it doesn't look like much on the surface. The opportunity that this creates for us to think through kind of like thoughtfully designed Apis that match this sort of thing that you'd be building in your app if you're building your own UI kid is really interesting. And it's not something that we've had the opportunity to really do before with the sort of delivery mechanism that we use for tail and July, where it's just copy and paste the snippet, do whatever you want with it. I think really powerful. And I'm glad we have a product that fills that need. But a lot of people want something that's more batteries included. Where different components have different relationships with each other and stuff like that. A good example of that, like something that we can't just do when the delivery mechanism, just static HTML is like validation errors. You know. So say you submitted this form and an error came back from the server and you kind of grabbed it out of the response and populated this. But this is the worst password I've ever seen in my life. You know, okay. That's just going to automatically render a red. We've got like a red validation state now. And if we get rid of that. Everything kind of goes back to how it was cool, right? And then like, you've got the stuff everybody needs all the time. Like your classic button component, you know. So, create counts. And you can. Of course, mix and match all this stuff with all the sort of compositional tools you use in talent already. So like, I want this to be on the right. So I'm gonna use text, right, to move it off to the right. It's not meant to be like this abstraction layer where you never think about tailwind. In fact, if you want to customize these components, and that's sort of one of the main reasons that you'd use this thing, you'd open up the components directory, you'd find something like that text field component. And remember, this isn't in node modules or anything, right, Like. This is you've scaffolded this into your app. It's your code. So one of the challenges for us because of that, and it's something that has proved to be an interesting challenge and something we're continuing to work hard on is making sure that the code that we give you feels like code that you would write in your own project. It doesn't feel like really clever confiscated library code or anything like that. So we're using TypeScript currently on this stuff because I know everyone's, but begging us for TypeScript support things. And I'm pretty sure we're going to be able to find a way to distribute it with TypeScript and without TypeScript. For people who just want to stick with vanilla JavaScript, but yeah, say I wanted to tweak. The gap between the description and the. Label, I can just come and hear it and change it. And you're not. Yeah, you're not editing code. That's gonna get overrated. Next time you run NPM installed, like this is your code. We just generated a starting point for you that is like thoughtfully designed and lets you sort of hit the ground running. So there's a lot more to this, of course, than just these sort of simple. Basic components that I'm showing you here. But I thought kind of focusing on these was a good way to sort of try to set up the mental model for what we want the developer experience to be like. He got the package you dumped into a project. It's yours. You can do whatever you want with it, but it's built. Hopefully, you know, our hope is that we're building it the exact same way that you would build it yourself so that once you've been using it for a while and building your app with it and customizing it and tweaking things like six months into the project, you almost forget that you used our things as a starting point, that it's just your code. And I think that's the only way that we can build something like this that lives up to sort of that sort of value that I have for the framework where a team like Shopify could use this to build a product and not feel like they were relying on a third party thing. They just feel like they got to. Like, skip the first six levels of the game, of the game, you know, So to talk more about some of the design details that have gone into this and dig deeper into a lot of these things that we're designing and including here, I'm going to bring out my business partner. Who is a former YouTube sensation? But I think he wants to get back into the game, Steve Shoga. Cool, how's it going, everybody, have a good day. So Adam just gave you a sneak peak of this. This is the application you like that we've been working on. This is sort of the main dashboard screen. And it, it sort of captures the journal look and feel we're going for, for this thing. So what I want to do is kind of get into some of the design details from the design thinking and sort of the taking on the journey of where, how we got to where. How we got to this page. So just before getting to that, I want to talk about a few of the goals. We already wanted, something that a look that was very flexible. Like if you could put any logo in the top corner. It would still work for your brand. But we didn't want it too generic either. We wanted something that, you know, had a little bit more personality to it. And this is really tricky at first. Like, here are some of our earlier concepts that we were exploring. So, you know, we tried incorporating color into it. You can see how we have this little gradient style selected option in the sidebar here. Here's a great way to sort of like one thing I like to do when I design application, you guys is sort of incorporated visual gimmick into it. So because like, you know, internal app screens, they always tend to have, you know. They're just tables and forms. And, and it's just a lot of boring text, right? There's not a lot of opportunities like you would get on. Like a marketing site to incorporate that, like marketing flare, that visual flare into it. And this is like, what, what you can say here at the top, Is this like a nice way to kind of bring your brand's visual identity into. Your internal screen. So here we kind of have this like these warp circles grazing the top of the page here. So like the stripe, for example, I got a screenshot stripe here. They kind of do that. Like, they like these colored stripes is a really important part of their visual identity. And they kind of brought it into some of their select dashboard screen. So it's a nice little way to bring like a game. Bring that visual flare into the app screens. And we explored like, you know, a few of our eyed variations of that. You're sort of this rainbow thing in the sidebar. Here's another variation of that. But to us, it felt a little too opinionated. It, it felt like almost, you know. Unless your brand is like this visual. Like, nicely represents your specific, but your visual identity, It, it felt like a cheap gimmick to us. So we kept exploring from. And, and another air we started exploring is, is like the sidebar area, Like we saw more opportunities there. You can kind of see like, just a subtle way to introduce like, some of these visual gimmicks that I'm talking about. So here you can see kind of the sidebar hugging the launching area. Here's another version where the cyber is kind of offset from the edges of the viewport, which is kind of a. Here's another one where it's kind of similar with our content areas, kind of offset from the edges of the viewport. And, you know, I felt a little bit too busy for us, but it was kind of cool. And nonetheless. And, you know, we even tried some simple ideas where I think it's kind of fought in the background. But they just thought just a little too vanilla. But so where we landed with something sort of a combination of a few of these ideas. Where the sidebar is kind of in the background, it's sort of hugging the, the content area, in the background kind of gets extended across the top here. We like this because it was like a nice visual gimmick. It wasn't overly painted. You can still put any logo up in that top corner. It would still work. And we have like a, we wanted to provide a darker version as well. Just to, you know, if you want something a bit more bold, you can, you can try that as well. And what I really liked about this sort of treatment is you can carry it over to other areas of the UI. So, you know, we may be slide over is in this mobile nav. It's, you know, normally I go like edge to edge on the on these components. But here, you kind of, it's a nice way to carry that visual gimmick over to these components as well. So that's a, it's always nice. We can like find something that you can just carry out throughout a, A variety of different components on your app. So yeah, now one thing you might be thinking when you're looking at this, it looks very gray. It was like, you know, black, white and gray. And that was very intentional because we like, again, we wanted to be very flexible. And they pretty much looked at anything. So we still want to provide you with, Components for like all of the colors that talent offers. We want to, we wanted to provide you with all of these button options because. You know, like tail and colors are not necessarily interchangeable because colors like blue, indigo. And red there, they're inherently much darker than colors like yellow and lime. And the Scion we have here. So you can't just use that like white text that we use on the darker buttons. On these lighter buttons, you have to kind of do an inverted treatment. So we wanted to provide all of these components for you as well. And we got the dark mode versions as well. And we want to provide some badges as well. And, you know, if you incorporate this interior, here's a forms page that we kind of have going on. And if you wanted to kind of incorporate those colors into it, you can do that this way. You can change the black color. And if you feel like going ahead and going up further. You can, you can customize the, you can customize like the toggle component in the checkbox. Like a lot of the form elements. Maybe if you wanted to add some color to the sidebar. You can go ahead and do that. He was an orange version as well. I played with. And it's kind of coolly, I guess. So, yeah. So that's like a, you know, a way you can be really aggressive with the coloring. You can bring it in, but, you know, I like to introduce the colors in a more subtle way too. Like I like using these badges a lot. Like so, for example, we have these sort of status badges on our dashboard screen. And you usually use these to a, These colors to sort of highlight the severity of these values. So often you use like green for something that's positive and red for something negative and yellow for something maybe that's like neutral or pending. But what I like to do, just like out of my own flavor, is just sort of rotate that hue a little bit so I can, I can select these, I can do some Figma with these selection colors. So, you know, instead of a green, I can try sort of a nice lime. You know, I'm going to do that. I'm going to change the text color that you're instead of red. And I want to maybe try a pink. And they can change the text color for that, as well. And then maybe instead of yellow, I can go to like an amberg and it still does the job of, of communicating, what those values represent. But it just kind of adds a different vibe to it. So it's, it's another cool way to use color. Like everyone just kind of defaults to a, you know, the very vanilla colors. And so this is a nice way to add your own flavor to it. So another thing I want to talk about is form design. Forms are one of my. Favorite things to design When I am making a designing an application UI it just. It's all the components. They kind of, there's a lot more opportunities for like fine little details. Like, I love trying to perfect, like getting the perfect shadow on those inputs. And now, my co-worker James McDonald, who's here from Scotland today, he's really got these details. And that's he's really inspired me in this stuff, and. With his permission. I'm gonna share some of his secrets on how he gets that perfectly looking shadow. So I have AI have a tell and play here. What one is it. So, this one. Do we close my tail and play here. Is there more. Maybe just re-open the link that I sent you. Yep. I'm sure he's going to add a background, and. Make sure I need duplicate. That gets put on her knees, kind of. So it was a great 300. So many. Browser when. So there we have a input. And this is how I used to design inputs. I have to have a border on there and make it gray. 300. And I just make it like a vertically offset shot on earth. They give it that depth, and it does a pretty good job. But when I started working with James and Constantine, what he did, he, he works in fig man. What he always did is he created an outer stroke on it. On the input. Like a really dark 1, and reducing the capacity to about 10%. Now, we can't create a stroke per se in the same way. You kind of figure in, in CSS, but, you can do that with tailwinds. Ring utility. So, I'm gonna first duplicate this. And have an ordering so we can kind of compare it after the fact. And then I'm going to remove this border. Someone is going to make it border. Need rid of that. And I'm gonna add 1 pixel ring to it. And then, like I said, I'm going to make it really dark, calling to make it a ring gray. Nine 50. And then so you have a dark border on there now. And I'm going to reduce the capacity to about 10%. So what do you kind of see. There is what's what's happening there now is like, that shadow is kind of getting exposed underneath it because you have the opacity on there. But you can't do that with the border because the border is kind of the on the inside of the input. So you can't really expose the shadow underneath it it, and it just looks much more crisp. And like the top 1 here is looking a little bit muddy. Are you guys seeing the same thing. Looks very like muddy on my screen here. Compared to the bottom one. Now, it especially becomes noticeable when I change the background color here to like something. Pretty always like gray. 200. Now it's going to look, you know, that you can still maintain that contrast ratio on the bottom one because it has the opacity on it. But this top 1 is looking super muddy. Now. He's hard to see that border now. It's kind of clashes with the shadow a little bit. So that's a nice way to get like a really crisp looking shadow. Incredibly nerdy stuff and. T weird. My Figma file. Is that it. There is. So. So we apply that same treatment to some of the other form elements like the. The checkboxes and the toggles in the select menus. We really wanted to deviate from, like, native OS. Components and, and really have something that's really custom and polished and consistent with everything else. But we don't deviate entirely from of West stuff. We really like to lean into some of the native OS patterns and conventions for like animations and interactive elements. A good example of that, like on dropdown. So I'm gonna show you kind of like where we mimic A, A native OS thing. And I'm gonna, when we got here for a. Browsers. So like, if I look, you see it. Yep, you can. If I show you what we can do on, if. If I go on like the. On the desktop here, if I show like a dropdown on Mac OS, you can see that it appears instantly, right, And the animation is sort of saved for when you click away. Does this little quick fade out there. And that's nice because it's like a, it doesn't interfere with your user experience. It's very instant when you're trying to find what you're looking for. But the, the delightful little animation is saved for after the fact. It's, and we like that. We like, like about that is that it's super subtle. It's like, you almost don't even notice it, but it's just a nice, but you. You kind of do little details like that. They all add up after a while. So we apply that same treatment to our, To our application. What are we using or using Chrome to show the. Brave, brave, brave, brave. So we apply that same kind of thinking to our dropdowns here. Where we have a drop down on. We have a little here, you know, the same kind of thing. It's instant on click, but then when you click away, does that little subtle fade out, right. Now, another area that we borrowed from, from NATO, SOS, is on. On the mobile experience. So, you know. As like designers and developers are always designing and creating these things on desktop computers and oftentimes. We like some mobile patterns kind of get overlooked as a result of that. So a good example of that is in dialogues, right? So I'm going to go to this orders page. I'm going to go to an order. Here, we. So on desktop. We often have like a we retreat dialogues. We set them in the middle of the viewport, right? And naturally, as we resize our bows. We need to kind of keep it in that same. But we, what we wanted to do if you actually spent time, like looking on your device and experience like dialogues, they usually like kind of animate up from the bottom. Right, And that's a nice little detail that people don't consider when they're designing on desktop. So now when you're holding your device with one hand, you can reach those actions at the barn. So we probably have that same kind of thinking here. So when you get to the, Yeah, when I click that now, it kind of animates up from the bottom here. Not recent refund. Here we go. So that's a just a good example of where we kind of borrowed and we mimic the native of the last style. So the last thing I want to talk about is, is dark mode. You know, it's 2023 now. So it's like, you know, there's. I just hit this. And will. I put my arm down, and I hit the button, and I don't know what just happened there. Oof, what. I just hit Command Z, and that solved that problem. What was this saying, Darko, you know, it is not, you're most required to ship your apps with dark 1 nowadays. Of course, we wanted to include that as well. And, you know, I was going to tweet about, Tailing colors. Everyone's always asking if there's like some magical solution we could provide where, you know, we, if you make your light version at the flip of a switch, you can get your dark mode version. And, you know, that's obviously that would be awesome, but it's not coming anytime in the foreseeable future. And I kind of kind of explain why that might happen, you know. Designing such a dark mode for the past few years, like one thing I've kind of learned, it's very hard to do dark mode as an afterthought. And we kind of and are embracing that now. And entreating dark mode as. Like completely separate artwork. So a good example to kind of explain why we need to do that. So take these buttons, for example. So the buttons on the left here. They all have a, A subtle shadow being cast off them. And it's kind of hard to see, but it's, it's there. But, but so the cigarettes, some depth. Right, But that shadow would essentially be invisible on dark 1. Because you have the dark on dark. So in order to get that same depth treatment, you know. You can't rely on the opposite side. If you use like the, the surface of the buttoning to create that like reflective to create a reflective surface from the light source, right, So instead on dark mode, you know, because we don't have the light background, Casa cattle on to instead of doing a gray blurred shape underneath the shadow, casting up from the shower. We, we do this sort of inner glow on top of the the button to kind of give that same. Give it that same depth. So here's an example of where we have to sort of great new artwork. And there's many more things that you have to consider like that when you're making dark mode. Now, we don't deviate completely from. You know, we do keep some things consistent when we do Darkmoon and sort of explain. That is, you know, we try to maintain our depth cues. So to explain that, you can kind of see what I mean by that is like on the sidebar here. It's kind of like this off white because it's in the background. It looks like it's further away, and the content area is very white. So it looks like it's closer to you. And we apply that same thinking when we do dark. It's so the, the sidebar, it's like the darker element, it's like further back. So we, we're using a gray 9 50 for that. And to make that look like the content area is a little closer to you. We make it the lighter color as well. Like many people think, you simply need to invert the to kind of get the dark mode effect. But we kind of think about it in the opposite way when we're doing these background elements. So, yeah, So that pretty much covered. That's like kind of a sneak peak at some of the design details you put into. And Adam is going to take it back, and he's going to kind of show you how we built some of these details. And I share with you, plus, a few more. Thanks. Good job, right. Cool, so yeah. Like Steve mentioned. I do have just like 1 cool trick that I want to show you guys, That was, is a really neat tailwind trick related to how we kind of had to do one of these things. So let me navigate the and halaka. Stuff that we got here and see what I can do. So let's, we're gonna start this server. But the, the 3002. And we'll just keep it simple here. Okay, so the one that I want to show you guys that I think, I get really excited about is the, the dialogue thing, so. You might think that this is like kind of easy. Like, it's just like responsive design or whatever, right? Like the dialogues here and on mobile or whatever, you know it, it slides up from the bottom. And I actually, I kind of removed the code that made it slide up from the bottom so I can show you how to do it. But because we're using frame or motion out of the hood to do all this, it really isn't that simple. And I think a lot of people's tendency is because you have to kind of configure these transition animations in JavaScript. You end up reaching for JavaScript to try and like measure the viewport, know which things you should add. And stuff like that. And there's a way to do it with just like totally vanilla CSS with Tailwind that I think is extremely clever that I want to show off. So let's think about what we need to do here if we want to actually have this thing slide up from the bottom, why don't we just implement it statically first? So I'm going to have to just like. Guess on some of these values, and we'll kind of figure it out as we go here. So by something like A Y offset, we can sort of say like. What should be happening to this dialogue as it sort of animates in, So here I'm saying, if I've got this right wall to test, I might have to add some negative signs or something here. But my goal here is to say, like, start the dialogue. Like shifted down 20 pixels from where it's sort of supposed to be, and then animate it back to the zero position. So you can see that is. Kind of scaling up a little bit. Now let's like move it to the bottom. So I'm going to get rid of this M, Y auto and just make an MT auto. And then maybe on non mobile screens. So maybe we'll do it at like SM. We'll add MB out of us. Will also goes back to the, to the middle. So let's make it slide up a little bit more. Maybe we'll do like 80 pixels or something. And I think we'll, we'll play with the scale to get kind of get rid of that, just so you can see. Okay, so that's like sliding up now. But we don't want to do to scale it. Similarly, on desktop, like we don't want to do the sliding. So how do we do this, How do we say only do one or the other, depending on like some sort of breakpoint e type of thing, So the trick that I came up with for this is to do it with CSS variables and create those CSS variables using tailwinds, arbitrary properties, which is kind of some. You know, the nuttiest stuff that you can do with tower. And basically. So let's start with the mobile 1. So on mobile, we wanted to scale from sort of 0%. So watch this in square brackets. I'm just going to say like scale from, and I'm just going to say 0%, No scale from 100%. We want to stay at a 100% of the whole time. And I wanted to scale to 100%. So here we're basically just saying the scale shouldn't change. So remember, 95%, please. That is your job. So we're gonna set this to scale from, We're going to set this to scale to. We probably don't really need the scale to, I guess 100 is going to be the same for both, but whatever. And let's just see, do we get, do we do this right. So in theory, this should still or this should not scale now, right, So that's not scaling, just kind of sliding up. But that means on desktop, it's also not scaling. But we want it to scale. So rather than trying to sort of change these values based on the breakpoints, we can just redefine the variables based on the breakpoints, because we can combine arbitrary properties with modifiers in towing. So let's redefine scale from to be 95% here. And now it's scaling, It's sliding up also, though, right? So how do we get rid of that, So on desktop. We don't want it to scale. So we're going to have to do the same sort of things. So let's like define some variables. So we're gonna say slide from say, 80 pixels, and this one will just leave it at 0 pixels. Whatever. So let's replace these like 80 pixels with far slide from. And let's just go back to the mobile 1. Just make sure that still that didn't work. Let's try making it. Not a pixel life. Sometimes frame of motion is picky. Anyone see what I might be doing wrong. What do I need to do in here, do you think. Aside. 80%, no. 80 pixels. Any syntax errors. Do we see any syntax error. Yeah. I don't think, I don't think that one should be a big deal. Not sliding. Oh, it slid down at the end. So that's interesting. So let's, I don't know. I don't know why that didn't work. But let's just try it. The Excel. Let's try. Dude, every time I try to do this, I feel like I don't know exactly what I'm doing. And it ends up, I feel like it. It just changes the code and node modules just changes. So sliding down on clothes, but it's not sliding. I, yeah, yeah, yeah. Yeah, yeah. But I, so, I don't think that's gonna be. Yes, to you. Oh yeah. Okay, so we got these very well for everything. Obviously. I, I knew that. But you know, now on desktop, it's still going to be sliding, which you don't want to do. So we do the same sort of thing. So. Slide from, we'll just not slide from anything and whatever. It just to be super ultra clear. Slide to 0 pixels to it in theory. Now, now it's just scaling on like desktop screens and just sliding on like mobile screens. So that is like a pretty clever, you know, I think that's a really interesting way. A really interesting way of using some of these, these features until and to do something that you might have like reached for like a resize observer and a bunch of like complex stuff for it is always really satisfying to me when I could find like a way to do something with. With just CSS and not be responsible for any of the things that are broken with it. Instead, I complain the people who work at Google for that. So anyways, that's all I wanted to show you guys. I thought that was kind of a cool, kind of advanced tailwind trick to sort of finish off some of the stuff we've been sharing with. Again, I just kind of say, you know, thank you to everyone for coming. This is like really cool. I'm super excited to meet everyone and get a chance to hang out. And, you know, we got bunch of free pizza and free drinks and stuff. So it's like. Hang out and enjoy and get to know all the cool people who traveled from all over the world to be here and be with other people who are super excited about Tailwind at the very end of the night. On your way out, we've got like swag bags at the back table with like t-shirt sizes labeled on all of them for you to do it that way. So you don't have to carry him around the whole night. So you can just grab one on your way out. Also, there's beer glasses, and every single one of them, so don't just grab the t-shirt out or we're going to have a big broken glass problem. But yeah, feel free to grab that on the way out and, you know, hang out as long as you like. And if you have any questions you want to chat about anything. Just find me, find me after. And I, I'm looking forward to connecting with everyone. I mean, everyone. So thank you again to everyone for coming out. This has been awesome. Really appreciate you being here. """ 以下是对开发重要的20个问题及答案: 问题1:与基于插件的开发相比,当前的开发环境有什么优势? 答案:当前的开发环境可以更简单地配置和使用,不需要考虑插件的顺序和连接问题。 问题2:关于最新版本的Tailwind CSS,有哪些改进和优化? 答案:最新版本的Tailwind CSS具有更好的性能和扩展性,并提供了更多的自定义选项。 问题3:是否有计划减少对JavaScript配置的依赖,更多地将配置转移到CSS中? 答案:是的,Tailwind CSS团队正在研究如何通过CSS文件来实现更多的配置,以减少对JavaScript配置的依赖。 问题4:Tailwind CSS是否支持现代颜色空间,如OKLCH和LAB? 答案:是的,Tailwind CSS可以编译为OKLCH或LAB,并提供了适用于不同浏览器的回退颜色。 问题5:Tailwind CSS是否支持自定义字体和字体样式? 答案:是的,可以通过CSS文件中的字体相关代码来自定义字体和字体样式。 问题6:在Tailwind CSS中,如何处理表单元素和验证错误? 答案:Tailwind CSS提供了丰富的表单元素样式和验证错误样式,可以轻松地应用到表单中。 问题7:Tailwind CSS是否提供了现成的UI组件库? 答案:是的,Tailwind CSS团队正在开发名为Catalyst的React应用UI组件库。 问题8:Catalyst是什么?它在开发中有什么作用? 答案:Catalyst是Tailwind CSS的React应用UI组件库,旨在提供预设计的组件和样式,加快开发速度。 问题9:在Catalyst中,如何自定义组件和样式? 答案:在Catalyst中,可以直接修改组件库中的组件来自定义样式。 问题10:如何在Tailwind CSS中实现暗黑模式? 答案:可以使用自定义CSS变量和Tailwind CSS的功能来定义暗黑模式的样式,从而实现暗黑模式的切换。 问题11:在设计和开发中,有哪些考虑因素影响了Catalyst的外观和功能? 答案:Catalyst的设计考虑了灵活性、品牌定制、颜色搭配等因素,旨在提供出色的用户体验。 问题12:在表单设计中,有哪些细节需要特别关注? 答案:表单设计需要关注细节,如输入框的阴影效果、复选框和选择框的样式等,以及与原生操作系统的一致性。 问题13:在暗黑模式设计中,如何处理不同元素的样式和对比度? 答案:在暗黑模式设计中,需要通过适当的颜色对比度和近似效果来确保元素的可读性和美观性。 问题14:如何使用CSS变量和Tailwind CSS在暗黑模式和亮模式之间切换样式? 答案:可以使用媒体查询和CSS变量,根据用户的主题偏好切换样式。通过定义不同的CSS变量值,可以根据主题切换不同的背景颜色、文本颜色等样式属性。 问题15:在设计对话框或下拉菜单时,如何借鉴原生操作系统的设计模式? 答案:可以观察原生操作系统中对话框或下拉菜单的交互和动画效果,尽量保持一致性,以提高用户体验和熟悉感。 问题16:在Tailwind CSS中,有没有一些特殊的技巧可以实现动画效果? 答案:是的,Tailwind CSS提供了一些类似transition和animation的CSS类名,可以轻松地为元素添加过渡效果和动画效果。 问题17:在暗黑模式下,如何处理文本颜色和背景颜色之间的对比度? 答案:在暗黑模式下,可以使用较亮的文本颜色和较暗的背景颜色,以确保良好的对比度,保证文本的可读性。 问题18:尽管Tailwind CSS已经提供了许多现成的样式和组件,我是否可以自定义和扩展它? 答案:是的,Tailwind CSS提供了大量的自定义选项,可以通过配置文件来定制和扩展样式和组件。 问题19:在实际项目中,Tailwind CSS的性能如何? 答案:Tailwind CSS经过优化,性能表现出色。它使用原子类和PurgeCSS等技术来减小文件大小,同时提供最佳的加载性能。 问题20:在设计和开发过程中,有哪些原则和指导方针可以帮助我使用Tailwind CSS? 答案:一些原则和指导方针包括遵循设计系统,保持一致性,利用Tailwind CSS的强大功能,以及关注用户体验和可访问性等方面的最佳实践。此外,阅读官方文档和参考实践经验也是很有帮助的。