- Lab
- Core Tech

Guided: Styling a Next.js Finance Application with Daisy UI and Tailwind CSS
In this lab, you will style pieces of an existing Next.js application using Daisy UI and Tailwind CSS. You will become familiar with the advantages of Tailwind CSS and Daisy UI as well as address one of the main concerns of Tailwind CSS, class duplication. By the end of this lab, you should feel confident when styling other applications using these design tools.

Path Info
Table of Contents
-
Challenge
Introduction
Welcome to the Guided: Daisy UI and Tailwind CSS to Style a Next.JS Finance Application lab.
Throughout this lab, you will become familiar with how to integrate
Tailwind CSS
in combination withDaisy UI
to an existing finance application.DaisyUI
significantly reduces the effort required to build modern, responsive web interfaces by providing ready-to-use components while maintaining the flexibility and customization options offered byTailwind CSS
.To start, you have been given a
Next.JS
application without any styling in a few locations. TheNext.JS
application already performs data fetching and server/client component rendering. You will have the freedom to choose some of the style options from theDaisy UI
andTailwind CSS
, and by the end of this course, you will have styled a navigation bar, table, and modal. You will also be familiar with how to tackle duplication introduced byTailwind CSS
and the basics of how to configureTailwind CSS
.You do not need any previous experience with
Next.JS
,Daisy UI
, orTailwind CSS
to complete this lab. This lab assumes you have basic experience withReact
,JavaScript
,JSX
andCSS
. Details onNext.JS
,Daisy UI
, andTailwind CSS
will be given to provide context for your implementations in each step.There is a
solution
directory that you can refer to if you are stuck or want to check your implementations at any time. Keep in mind that the solution provided in this directory is not the only solution, so it is acceptable for you to have a different solution so long as the application functions as intended.
Activity
Launch the application by entering
npm run dev
in the Terminal. The application can be seen in the Web Browser tab atlocalhost:3000
. The starting application should look like the picture below:Remember: throughout the lab, code changes will be live on the website after refreshing if the application is running. If you do however want to stop and restart the application, you can do so by typing
Ctrl+C
in the Terminal and rerunningnpm run dev
. -
Challenge
Tailwind CSS Overview
Tailwind CSS Overview
Tailwind CSS
is a utility-first CSS framework designed to enable developers to build custom user interfaces quickly and efficiently. Instead of providing pre-styled components like traditional CSS frameworks (e.g., Bootstrap),Tailwind CSS
offers low-level utility classes that can be combined to create any design directly in the HTML. Here are some key aspects ofTailwind CSS
:- Utility-First Approach:
Tailwind CSS
provides a large set of utility classes for common CSS properties like padding, margin, color, font size, and more. These classes can be combined to build complex designs without writing custom CSS. For example, the followingdiv
tag uses utility classes to style it.
<div class="p-4 bg-blue-500 text-white">Hello, Tailwind!</div>
- Customization:
Tailwind CSS
is highly customizable. Developers can extend the default theme, add custom utility classes, and configure various aspects through the configuration file (tailwind.config.js). In the future, you will configureTailwind CSS
to work hand in hand withDaisy UI
. In the example below, you can see a custom color being created for an application usingTailwind CSS
.
// tailwind.config.js module.exports = { theme: { extend: { colors: { customBlue: '#1E3A8A', }, }, }, }
- Responsive Design:
Tailwind CSS
includes built-in support for responsive design with utility classes that can be applied conditionally based on breakpoints. Thediv
tag below styles a paragraph to change sizes responsively.
<div class="p-4 sm:p-6 lg:p-8">Responsive Padding</div>
- State Variants: It supports state variants like hover, focus, active, and disabled, allowing you to style elements based on their state. The button below would change color when hovered over with a mouse.
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Hover Me</button>
- Performance:
Tailwind CSS
includes a tool calledPurgeCSS
that removes unused CSS classes from the production build, significantly reducing the file size. You will not be using purge in this application, but you would add the configuration below if you wanted to use it in the future.
// tailwind.config.js module.exports = { purge: ['./src/**/*.{js,jsx,ts,tsx,html}'], // other configurations... }
- Component-Friendly: While
Tailwind CSS
itself doesn't provide pre-styled components, it works well with component libraries and frameworks likeReact
,Vue
, andAngular
, making it easy to create reusable components. In this lab, you will also useDaisy UI
which is built on top ofTailwind CSS
to provide pre-styled components, but it is important to note thatTailwind CSS
can be quickly used on any component without the use of a design library likeDaisy UI
.Tailwind CSS
can also be used alongside aDaisy UI
component to apply custom styles on the fly.
--- ## Starting with Tailwind CSS
The finance application you are working on already has
Tailwind CSS
installed as it comes by default with mostNext.js
applications (unless you select otherwise when creating your application).When you start the application using
npm run dev
and visitlocalhost:3000
in the web browser you will see the following page:Parts of the application are already using
Tailwind CSS
utility classes, but they are being ignored since they cannot be found. In order to locateTailwind CSS
utility classes, the global CSS file needs to include a fewTailwind CSS
directives and have none of your traditional CSS classes or styling. The global CSS must include the following directives.@tailwind base; @tailwind components; @tailwind utilities;
These directives import
Tailwind CSS
in three layers. The base isTailwind CSS
’sPreflight
classes that wipe any browser CSS that may be applied to HTML elements that do not have CSS. The components layer is a small layer that containsTailwind
’s component class. Lastly, the utilities layer includes the entirety ofTailwind
’s utility classes. With these imports in global CSS, you can useTailwind CSS
utility classes in yourHTML
orJSX
files.Once
Tailwind CSS
is imported inapp/globals.css
, you can useTailwind CSS
throughout the application in any component, and it is not necessary to have these imports in other CSS files as they will be included globally.
Activity
Currently,
app/globals.css
is an empty file.Import Tailwind CSS by adding the following to the
app/globals.css
file.@tailwind base; @tailwind components; @tailwind utilities;
Refresh
localhost:3000
, you should see the app is already different asTailwind CSS
utility classes that were already being used to style existing HTML elements can be found. The application should now look like: - Utility-First Approach:
-
Challenge
Daisy UI Overview
Daisy UI Overview
Daisy UI
is a popular component library built on top ofTailwind CSS
. It provides a set of pre-designed, responsive, and customizable UI components that are easy to integrate and use in web projects.Daisy UI
simplifies the development process by offering a wide range of styled components, such as buttons, forms, cards, and more, without the need to write extensive custom CSS.Here are some key features of
Daisy UI
:-
Tailwind CSS
Integration:Daisy UI
works seamlessly withTailwind CSS
, leveraging its utility classes to provide a consistent design system. -
Customizable Components: Components can be easily customized using
Tailwind CSS
classes, allowing developers to tailor them to their specific design needs. -
Responsive Design: Components are designed to be responsive out of the box, ensuring they work well on different screen sizes.
-
Ease of Use:
Daisy UI
components are easy to use and can be quickly integrated into projects, reducing the time and effort required to build a polished user interface. -
Theme Support:
Daisy UI
includes built-in theme support, making it simple to apply different color schemes to your project.
--- ## Get Started with Daisy UI
The finance application used throughout this lab already has
Daisy UI
installed and can be found in thepackage.json
file.To use Daisy UI in the application, you must configure
Tailwind CSS
to require Daisy UI as a plugin.
Activity
Add the following to the
tailwind.config.js
file:module.exports = { … plugins: [require('daisyui')], }
Now,
Daisy UI
is available throughout the application! Parts of the application were already usingDaisy UI
classes to style and transform certain HTML elements into Daisy UI components.Refresh
localhost:3000
, and you should now see a home page that looks like: -
-
Challenge
Styling the Navigation Bar Links
Styling the Navigation Bar Links
When you start up your application, you will see a navigation bar that looks like this:
Navigate to
app/(ui)/components/nav-bar.jsx
where this navigation is being created. You will be restyling this component to be a beautiful navigation bar using Daisy UI and Tailwind CSS.To style the navigation bar, you will begin by styling the navigation links. Follow the steps below to style the navigation links using Daisy UI and Tailwind CSS.
- Transform your Next.JS
Link
elements to be Daisy UIButton
components by addingclassName="btn"
to theLink
tag. Thebtn
class is a Daisy UI class that can be applied to any HTML tag to style it like aButton
component.- Example
Link
Daisy UIButton
<Link href="/" className="btn"> Home </Link>
- Note: You can refresh the webpage and see that the navigation links should now look like buttons thanks to Daisy UI,
- Example
- Remove the
|
and spaces between eachLink
element. These were here to separate navigation elements before they were styled. - Add a color of your choice to the navigation buttons using Daisy UI button color modifications. Color modifications are added to an elements class name list.
- Example
Link
Daisy UIButton
with Color Modifier
<Link href="/" className="btn btn-primary"> Home </Link>
- Here are a few Daisy UI button color modifications to pick from with an example picture and several more can be found in Daisy UI's documentation.
btn-neutral
btn-primary
btn-secondary
btn-accent
btn-ghost
btn-link
- Example
- Increase the navigation button font size using a Tailwind CSS utility class. Style your
Link
elements with thetext-xl
Tailwind CSS utility class.- Example
Link
Daisy UIButton
with larger text
<Link href="/" className="btn btn-primary text-xl"> Home </Link>
- Note: above you were able to use both Daisy UI and Tailwind CSS classes to style an HTML element. This is a great example of how Daisy UI and Tailwind CSS can be used hand in hand to style an application.
- Example
Now, your navigation bar should look something like below except with your color of choice. This example uses
btn-primary
as the color modifier and the example in thesolution
directory usesbtn-ghost
. - Transform your Next.JS
-
Challenge
Styling the Navigation Bar
Styling the Navigation Bar
In the previous step, you styled the navigation buttons. Continue to work in
app/(ui)/components/nav-bar.jsx
and follow the steps below to transform the existing HTMLnav
element to be aNavbar
Daisy UI component with Tailwind CSS custom styling.- Transform the existing HTML
nav
element to be a Daisy UINavbar
by adding the Daisy UInavbar
class.- Example Daisy UI
Navbar
<nav className="navbar"> ... </nav>
- Note: The application navigation bar will now look something like the picture below. You can note the left padding that was introduced when the navigation bar because a Daisy UI navigation component.
- Example Daisy UI
- Use Tailwind CSS to color the background of the navigation bar so the bar stands out on the webpage. Add a Tailwind CSS background color class of your choosing to the nav element.
- Example Daisy UI
Navbar
with a blue background
<nav className="navbar bg-sky-200"> ... </nav>
- Note: Tailwind CSS is built with a lot of background color options that can be added to any HTML element using their corresponding class name. All the available background colors Tailwind offers can be found here.
- Note: Your navigation bar should look something like the picture below after completing this step. The example below uses
bg-sky-200
as its background color and the navigation bar in thesolution
directory usesbg-emerald-500
as its background color.
- Example Daisy UI
- Transform the existing HTML
-
Challenge
Styling the Expenses Table
Styling the Expenses Table
When you visit the
Expenses
page on the application, you will be greeted with a table that is not styled. It should look like:
In
app/(ui)/expenses/page.jsx
, follow the steps below to style the existing table by transforming it into a Daisy UITable
component that has a body with a white background.-
Transform the existing HTML
table
element to be a Daisy UITable
component by styling the element with Daisy UI'stable
class.- Example Daisy UI
Table
Component
<table className="table"> ... </table>
- Note: Refresh the expenses page, and the table should now look like:
- Example Daisy UI
-
Style the table body to have a white background color (use the
bg-white
class provided by Tailwind CSS).- Example Table Body with a White Background
<tbody className="bg-white"> ... </tbody>
- Note: The white background color is different than the Daisy UI
Card
component the table rests on. This is what makes the table body stand out on the card. - Note: Your expenses page should now look like:
-
-
Challenge
Add a Basic Dialog to the Expenses Page
Add a Basic Dialog to the Expenses Page
Follow the steps below to add a Daisy UI
Modal
component to theServerActionClientComponentAddTransactionForm
component available atapp/(ui)/components/server-action-client-component-add-transaction-form.jsx
.- In the top
div
element above theform
element, add a newdialog
HTML element that would display the placeholder text, "Hello".- Example Dialog Element
<dialog>Hello</dialog>
- Label the
id
attribute of this newdialog
element to be"createExpenseModal"
. Thisid
may seen robust now, but in the next step of this lab this modal be used to create a new expense and theid
will be fitting.- Example Dialog Element with an Id
<dialog id="createExpenseModal">Hello</dialog>
- Note: When you look at the Expenses page, nothing should be different because the dialog you just added has no way to appear.
- In the
ServerActionClientComponentAddTransactionForm
component, add a new Daisy UIButton
. Have the button reads "Create" since in the next step of the lab this button will serve to start the expense creation process.- Example Create Button
<button className="btn"> <p>Create</p> </button>
- Style the button with any Daisy UI color modifier like you have done in previous steps.
- Note: the
solution
directory uses thebtn-accent
color modifier.
- Note: the
- Style the button with Tailwind CSS
margin
classes andflex
classes until you are happy with the location of the button on the expenses page.- Note: the
solution
directory styles the create expenses button with the following Tailwind CSS utility classes:my-2 mr-4 flex flex-row
.my-2
adds a top and bottom margin of0.5rem
, or8px
andmr-4
applies a margin to only the right of the button. The other classes allow the button to be a part of a flexible layout and align itself horizontally.
- Note: the
- Style the button's
p
tag with Tailwind CSS utility classes until you are happy with the font and text details.- Note: The
solution
directory styles thep
tag with the following classes:font-sans text-sm text-white
.
- Note: The
- Program the button open the basic dialog.
-
Hint: You need to add an
onClick
method that callsdocument.getElementById("createExpenseModal").showModal()
. This will show the dialog when the create button is clicked. -
Note: The form on the expenses page may now look something like before clicking
Create
: -
Note: You should see a dialog that says "Hello" after clicking
Create
, and it should look something like: -
Note: You will not be able to perform any actions on the website until you close the dialog which is currently not implemented
-
- Inside the dialog, add a Daisy UI
Button
to close it.- Hint: Inside the dialog next to the "Hello" text, add a Daisy UI
Button
that callsdocument.getElementById("createExpenseModal").close();
when clicked. - Note: When the dialog is open, it should now look something like the picture below and close when you click the
Close
.
- Hint: Inside the dialog next to the "Hello" text, add a Daisy UI
Example of a Styled Create Button that Opens a Dialog
<button className="my-2 mr-4 flex flex-row btn btn-accent" onClick={() => document.getElementById("createExpenseModal").showModal() } > <p className="font-sans text-sm text-white">Create</p> </button>
Example of a Dialog with a Close Button
<dialog id="createExpenseModal"> Hello <button className="btn" onClick={() => { document.getElementById("createExpenseModal").close(); }} > Close </button> </dialog>
- In the top
-
Challenge
Transform the Basic Dialog into a Daisy UI Modal
Transform the Basic Dialog into a Daisy UI Modal Component
Now that you have a dialog that can be opened and closed, follow the steps below to transform the dialog into a Daisy UI
Modal
component.- Add Daisy UI's
modal
class to the dialog element.- Example of Daisy UI Modal Component
<dialog id="createExpenseModal" className="modal"> ... </dialog>
- Style the dialog content to look like a modal using Daisy UI's
modal-box
andmodal-action
classes.- Note: Daisy UI
Modal
s already have styling for amodal box
(the container of the content that will go in the modal) and styling formodal actions
(the buttons and forms that will perform modal actions like closing the modal and creating expenses).
- Inside the
dialog
element, wrapClose
button in adiv
tag styled with themodal-action
class. - Wrap the entire contents of the
dialog element
in anotherdiv
tag styled with themodal-box
class.
- Note: Daisy UI
If you click
Create
, your modal should now look like this:Example Daisy UI Modal
<dialog id="createExpenseModal" className="modal"> <div className="modal-box"> Hello <div className="modal-action"> <button className="btn" onClick={() => { document.getElementById("createExpenseModal").close(); }} > Close </button> </div> </div> </dialog>
- Add Daisy UI's
-
Challenge
Move the Create Expense Form into the Basic Modal
Move the Create Expense Form into the Modal
In the previous lab step you transformed the basic dialog into a Daisy UI
Modal
. Follow the steps below to move theCreate Expense
form into theModal
.- Remove the
Modal
's "Hello" text placeholder. - Copy the
form
element and and its contents into theModal
'smodal box
section.
Your modal should now look something like:
Example with Form in Modal Element
<dialog id="createExpenseModal" className="modal"> <div className="modal-box"> <form action={async (formData) => { const transactions = await createTypeTransaction(formData); if (transactionPath === "/income") { setTransactions(transactions); } }} id="createTransactionForm" > <input name="date" type="date" required /> <input name="amount" type="number" step="0.01" placeholder="10.00" required /> <input name="category" type="text" placeholder="Category" required /> <textarea name="notes" placeholder={"Notes"} /> <input name="type" type="text" placeholder={"expense"} hidden={!!transactionType} /> <button type="submit" className="btn float-right btn-accent font-sans text-sm text-white" > Create {transactionType ? transactionType : "Transaction"} </button> </form> <div className="modal-action"> <button className="btn" onClick={() => { document.getElementById("createExpenseModal").close(); }} > Close </button> </div> </div> </dialog>
Close and Reset the Modal on Form Submission
Create an expense using the
Modal
on theExpenses
page. You will notice theModal
does not close when submitting theform
. Close theModal
onform
submission by following the step below.- Add
document.getElementById("createExpenseModal").close();
to the bottom ofform
'saction
method to close theModal
upon creating an expense.
Create an expense again in the application and you will notice that the
Modal
closes uponform
submission; however, if you start to create a second expense by reopening theModal
, you will notice another problem that theform
's data does not reset onform
submission. Follow the step below to resetform
data onform
submission.- The
form
'sid
iscreateTransactionForm
, so find theform
element using theid
andreset
the data as part of theform
'saction
.- Hint: Add
document.getElementById("createTransactionForm").reset();
to the bottom ofform
'saction
method to reset theModal
upon creating an expense.
- Hint: Add
Example Form Element that Can Close and Reset the Modal
<form action={async (formData) => { const transactions = await createTypeTransaction(formData); if (transactionPath === "/income") { setTransactions(transactions); } document.getElementById("createExpenseModal").close(); document.getElementById("createTransactionForm").reset(); }} id="createTransactionForm" > ... </form>
Lastly, on the application open the
Modal
, fill out theform
, and close theModal
without submitting the form. Reopen theModal
and you will notice that theform
's data was notreset
. Follow the steps below to address this.- Move the
Close
button into theform
element underneath theform
'screate
button. - Set the
Close
button'stype
toreset
to clear theform
's data when you close theModal
without creating an expense.- Example of a
Close
Button
on aform
the resetsform
data when clicked
<button className="btn" type="reset" onClick={() => { document.getElementById("createExpenseModal").close(); }} > Close </button>
- Example of a
- Remove the
Modal
'smodal-action
section as it now is empty.
Example Create Expense Dialog After the Above Steps
<dialog id="createExpenseModal" className="modal"> <div className="modal-box"> <form action={async (formData) => { const transactions = await createTypeTransaction(formData); if (transactionPath === "/income") { setTransactions(transactions); } document.getElementById("createExpenseModal").close(); document.getElementById("createTransactionForm").reset(); }} id="createTransactionForm" > <input name="date" type="date" required /> <input name="amount" type="number" step="0.01" placeholder="10.00" required /> <input name="category" type="text" placeholder="Category" required /> <textarea name="notes" placeholder={"Notes"} /> <input name="type" type="text" placeholder={"expense"} hidden={!!transactionType} /> <button type="submit" className="btn float-right btn-accent font-sans text-sm text-white" > Create {transactionType ? transactionType : "Transaction"} </button> <button className="btn" type="reset" onClick={() => { document.getElementById("createExpenseModal").close(); }} > Close </button> </form> </div> </dialog>
You should now have a blank form whenever you create an expense or close the modal without creating an expense. Try it out in the web browser to verify.
- Remove the
-
Challenge
Tailwind CSS Forms
Configure the Application to Use Tailwind CSS Forms
In this step of the lab, you will update the create expense
form
from the previous step to be aTailwind CSS Form
.Tailwind CSS Forms
are available as aplugin
and are not brought into a Tailwind CSS application by default. TheTailwind CSS Forms
plugin
has already been installed for you, but the application is not yet configured to use them. Configure the application to useTailwind CSS Forms
by following the instruction below.-
Adding
@tailwindcss/forms
to theplugin
list intailwind.config.js
.- The application
plugin
configuration should now look something like below now as you added the Daisy UIplugin
in a previous lab step:
module.exports = { … plugins: [require('daisyui'), require("@tailwindcss/forms")], }
- The application
Update the Create Expense Form to be a Tailwind CSS Form
Transforming the create expense
form
into aTailwind CSS Form
is as simple as styling with Tailwind CSS. The table below provides some of the relevant class names based on the create expenseform
'sinput
types. Follow the instruction under the table to transform the create expenseform
intoTailwind CSS Form
and style the form.| Base | Class | | -------- | ------- | |
[type='text']
|form-input
| |[type='number']
|form-input
| |[type='date']
|form-input
| |textarea
|form-textarea
|- Add the correct class to each of the create expense
form
'sinput
s based based on theinput
's type. - Style the create expense
form
'sinput
s using Tailwind CSS utility classes until you are happy with the design. Relevant classes may changepadding
,border radius
,margin
, andwidth
. You can reference Tailwind CSS documentation for more class ideas if you need to.- For reference, the
form
in thesolution
directory applies the following classes to allform
input
s:px-4 rounded mb-5 w-full
.
- For reference, the
Your form should now look something like:
Example Tailwind CSS Form
<form action={async (formData) => { const transactions = await createTypeTransaction(formData); if (transactionPath === "/income") { setTransactions(transactions); } document.getElementById("createExpenseModal").close(); document.getElementById("createTransactionForm").reset(); }} id="createTransactionForm" className="w-full" > <input className="formInput px-4 rounded mb-5 w-full" name="date" type="date" required /> <input className="formInput px-4 rounded mb-5 w-full" name="amount" type="number" step="0.01" placeholder="10.00" required /> <input className="formInput px-4 rounded mb-5 w-full" name="category" type="text" placeholder="Category" required /> <textarea className="form-textarea px-4 pxy-3 rounded w-full" name="notes" placeholder={"Notes"} /> <input name="type" type="text" placeholder={"expense"} hidden={!!transactionType} className="formInput px-4 rounded mb-5 w-full" /> <button type="submit" className="btn float-right btn-accent font-sans text-sm text-white" > Create {transactionType ? transactionType : "Transaction"} </button> <button className="btn" type="reset" onClick={() => { document.getElementById("createExpenseModal").close(); }} > Close </button> </form>
-
-
Challenge
Duplication While Using Tailwind CSS
Duplication While Using Tailwind CSS
One of the largest concerns with Tailwind CSS is the potential for a lot of duplication. You will start this step by seeing how this issue can come to life while styling an application with Tailwind CSS. Follow the steps below to add
label
s to the create expenseform
and style the newlabel
s.- Add a label for each create expense
form
input
.- Example Label for
date
`input
<label htmlFor="date">Date</label> <input name="date" type="date" required />
- Note: The
input
'sname
and thelabel
'shtmlFor
properties match.
- Example Label for
- Style each
label
with the following set of Tailwind CSS utilitiy classes:block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2
.- Note: Your form will now look like something like:
- Note: Your form will now look like something like:
Form with Labels Example
<form action={async (formData) => { const transactions = await createTypeTransaction(formData); if (transactionPath === "/income") { setTransactions(transactions); } document.getElementById("createExpenseModal").close(); document.getElementById("createTransactionForm").reset(); }} id="createTransactionForm" className="w-full" > <label className={formLabelTailwindCSS} htmlFor="date"> Date </label> <input className="formInput" name="date" type="date" required /> <label className={formLabelTailwindCSS} htmlFor="amount"> Amount </label> <input className="formInput" name="amount" type="number" step="0.01" placeholder="10.00" required /> <label className={formLabelTailwindCSS} htmlFor="category"> Catgeory </label> <input className="formInput" name="category" type="text" placeholder="Category" required /> <label className={formLabelTailwindCSS} htmlFor="notes"> Notes </label> <textarea className="form-textarea px-4 pxy-3 rounded w-full" name="notes" placeholder={"Notes"} /> <label className={classNames(formLabelTailwindCSS(), { invisible: !!transactionType, })} htmlFor="type" > Transaction Type </label> <input name="type" type="text" placeholder={"expense"} hidden={!!transactionType} className="formInput" /> <button type="submit" className="btn float-right btn-accent font-sans text-sm text-white" > Create {transactionType ? transactionType : "Transaction"} </button> <button className="btn" type="reset" onClick={() => { document.getElementById("createExpenseModal").close(); }} > Close </button> </form>
Above, you added
form
label
s that you wanted to be styled with all the same Tailwind CSS classes for design consistency. However, it might have felt tedious typing out the same classes for eachlabel
. It is encouraged to see this duplication issue as part of your larger code setup instead of one brought to you by Tailwind CSS.
Address the Styling Duplication Introduced Above and Examine Other Ways the Solution Addresses Styling Duplication
You can address this Tailwind CSS
className
duplication in a few different ways.- You can extract a method that simply returns the class string and use that for the value of every label’s
className
attribute. - You can extract a React component called something like
CreateExpenseFormLabel
that is a form label with styling and renders children and render that component in the form for each label. - Lastly, Tailwind CSS also uses the
@apply
directive for duplication. In CSS files, you can use the@apply
directive to use Tailwind classes in the definition of other CSS selectors.
Take some time to explore each of these options to avoid the label duplication introduced above. This is a self-guided exercise in this lab environment.
The
solution
directory contains a version of theapp
directory that has an example for each way to combat duplication above. Read more about the examples below to find them in thesolution
directory if you are interested in previewing them.- The
label
class duplication introduced in this lab step is solved in thesolution
directory'sapp
using an extracted method that returns the styling class string. - The
Home
page uses aHeader
component to display its title. ThisHeader
component could be reused on theIncome
andExpenses
pages to avoid duplication in styling. Look atsolution/app/page.js
,solution/app/(ui)/components/header.jsx
,solution/app/income/page,jsx
, andsolution/app/expenses/page,jsx
. - Just like you saw class duplication on the
form
label
s in the step of the lab, in thesolution
, there was also class duplication on theform
input
s. Thesolution
directory'sapp
uses the@apply
directive on a class insolution/app/global.css
to create a CSS class that is applied allform
input
s.
- Add a label for each create expense
-
Challenge
Tailwind CSS Configuration
Tailwind CSS Configuration
The
tailwind.config.js
file is where the configuration for Tailwind CSS resides. In previous steps, you have added plugins to the configuration of Tailwind CSS. A minimal configuration file looks like this:module.exports = { future: {}, purge: [], theme: { extend: {}, }, variants: {}, plugins: [], };
Tailwind CSS considers each family of utilities to be a core plugin. Here is a list of all Tailwind CSS core plugins.
The
theme
object in Tailwind CSS configuration is helpful to define overarching design themes within your application. It can be used to customize core plugins. This can include overriding all of the core plugins options and extending those options.To override all of a core plugins options, you would provide a new set of values for it in
theme
. Below is an example of overriding thescreens
core plugin. This example could be useful if you wanted to completely replace all of the screen breakpoints with custom or reworked ones.theme: { screens: { 'phone': '600px', 'laptop': '1280px', } }
With the above theme you could start using
phone
andlaptop
as Tailwind CSS utility classes.If you did not want to override all of a core plugin's values, you can keep the existing values and extend that core plugin.
The configuration file can also be used to exclude utility classes from being generated (if you needed it for performance reasons), configure variant prefixes (things like active, checked, and hover), and so much more. Tailwind CSS even has a way to prune off all the utility classes you did not use in an application by using the purge option in the configuration.
You may reference Tailwind’s documentation for configuration for more details.
Activity
The finance application you have been working on throughout this lab already references two custom colors on the
Home
page's transaction table. The application has not been able to use these custom colors because it has been unable to find the definition to them. TheHome
page's table currently looks like:Extend the
color
core plugin to include them.In
tailwind.config.js
, add the code below to the configuration object.theme: { extend: { colors: { "light-red": "#f54248", "light-green": "#42f59b" } }, },
The home page's table should now look like:
For reference, the transaction table now highlights expense rows with a red color and income rows with a green color. You added the custom red and green colors to the configuration.
What's a lab?
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Provided environment for hands-on practice
We will provide the credentials and environment necessary for you to practice right within your browser.
Guided walkthrough
Follow along with the author’s guided walkthrough and build something new in your provided environment!
Did you know?
On average, you retain 75% more of your learning if you get time for practice.