Mix.install(
[
{:jason, "~> 1.4"},
{:kino, "~> 0.9", override: true},
{:youtube, github: "brooklinjazz/youtube"},
{:hidden_cell, github: "brooklinjazz/hidden_cell"},
{:kino_tailwind_playground, github: "BrooklinJazz/kino_tailwind_playground"}
],
force: true
)
Upon completing this lesson, a student should be able to answer the following questions.
- Why use Tailwind vs pure CSS?
- How do you find Tailwind utility classes?
Tailwind CSS is a CSS utility framework. It allows us to use utility classes defined by Tailwind to conveniently apply CSS styles.
For example, we can use the underline
class to apply an underline to an HTML element.
<h1 class="underline">
Hello world!
</h1>
This applies the following CSS to the heading 3 element.
text-decoration-line: underline;
Keep in mind, there is nothing we can do in Tailwind that we cannot do with pure CSS. Tailwind is purely for convenience. In general, you'll want to learn CSS styles, then learn the appropriate CSS class on Tailwind. Knowledge of pure CSS will always be more generally applicable than knowledge of Tailwind.
However, Tailwind is a very popular and important CSS framework in the Elixir ecosystem. Many projects use Tailwind, and it's become part of the standard PETAL (Phoenix, Elixir Tailwind, AlpineJS and LiveView) stack, which is a set of common tools used to create Elixir web applications.
To experiment with Tailwind, we can use the Tailwind CDN (Content Delivery Network) in an HTML file. This CDN provides the JavaScript necessary to run Tailwind.
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<h1 class="text-3xl font-bold underline">
Hello world!
</h1>
</body>
</html>
We've also created a Livebook Tailwind Playground for the purposes of demonstration. All tailwind examples are editable and render live.
Kino.nothing()
Tailwind provides the Tailwind Play playground to experiment with Tailwind classes.
Go to Tailwind Play and enter the following HTML to create an HTML heading 3 element with bold font, an underline, and a triple extra large font size.
<h1 class="font-bold underline text-3xl">
Hello world!
</h1>
This is the same as applying the following CSS styles.
h1 {
// underline
text-decoration-line: underline;
// font-bold
font-weight: 700;
// text-3xl
font-size: 1.875rem; /* 30px */
line-height: 2.25rem; /* 36px */
}
We can find all available Tailwind utility classes from the Tailwind Documentation. They have a handy Quick Search for finding Tailwind classes.
Use the Tailwind Documentation to create the following button.
Kino.nothing()
Tailwind comes with a default color palette. Each color has a base name such as red
then a number to indicate the shade of color.
The default colors are slate
, gray
, zinc
, neutral
, stone
, red
, orange
, amber
, yellow
, lime
, green
, emerald
, teal
, cyan
, sky
, blue
, indigo
, violet
, purple
, fuchsia
, pink
, and rose
.
The default shades are 50
, 100
, 200
, 300
, 400
, 500
, 600
, 700
, 800
, and 900
.
This color pallet works with a variety of utility classes such as text-color and background-color.
So we can apply a background color and text color to an HTML element like so.
Kino.nothing()
We can change font size using text-{size}
utilities.
<p class="text-3xl">
We have access to the following sizes: xs
, sm
, base
, lg
, xl
, 2xl
, 3xl
, 4xl
, 5xl
, 6xl
, 7xl
, 8xl
, and 9xl
.
With Tailwind, <p>
, h1
, h2
, h3
, h4
, h5
, and h6
are purely semantic and do not apply any styles by default.
Kino.nothing()
font-{weight}
sets the font weight of text. The weight
can be thin
, extralight
, light
, normal
, medium
, semibold
, bold
, extrabold
, and black
.
Kino.nothing()
We can use text-left
, text-center
, and text-right
as well as other text-align classes to align text inside its container.
Kino.nothing()
We can set height and width using the h-{size}
and w-{size}
classes. Refer to the Height and Width documentation for more.
We can provide a fixed-size for the height and width of 0
, 0.5
, 1
, 1.5
, 2
, 2.5
, 3
, 3.5
, 4
, 5
, 6
, 7
, 8
, 9
, 10
, 11
, 12
, 14
, 16
, 20
, 24
, 28
, 32
, 36
, 40
, 44
, 48
, 52
, 56
, 60
, 64
, 72
, 80
, or 96
. These correspond to certain rem
/px
values.
<!-- Height -->
<h1 class="h-64">The height of this element is 16rem or 256px</h1>
<!-- Width -->
<h1 class="w-64">The width of this element is 16rem or 256px</h1>
The size
can also be provided as a fraction of halves, thirds, fourths, fifths, sixths, or twelfths. For example: 1/2
, 2/3
, 3/4
, 2/5
, 4/6
, and 7/12
. This size will be relative to the parent container.
<!-- Height -->
<div class="h-64">
<h1 class="h-1/2">This height will be 8rem or 128px because it is half the height of `h-64`</h1>
</div>
<!-- Width -->
<div class="w-64">
<h1 class="w-1/2">This width will be 8rem or 128px because it is half the width of `w-64`</h1>
</div>
We can use -screen
to use the full height or width of the screen.
<h1 class="h-screen">This will be the full height of the screen regardless of parent container</h1>
<h1 class="w-screen">This will be the full width of the screen regardless of parent container</h1>
We can use -full
to set the height or width to the full size of the parent container. This has the same effect as -screen
if the parent container is already the size of the screen.
<!-- Height -->
<div class="h-64">
<h1 class="h-full">This height will be 16rem or 256px because it is the full the height of `h-64`</h1>
</div>
<!-- Width -->
<div class="w-64">
<h1 class="w-full">This width will be 16rem or 256px because it is the full the width of `w-64`</h1>
</div>
We can set the max/min or height/width using the max-h-{size}
, min-h-{size}
, max-w-{size}
. The acceptable size
values are specific for each. Refer to the Max-Height, Max-Width, Min-Height, and Min-Width documentation for more.
<p class="max-h-12">The max height of this paragraph will be 2rem or 48px</p>
Combining w-fit
Kino.nothing()
Create a paragraph tag that will wrap text on a new line when wider than 10rem.
For example, this paragraph will wrap words when the text is wider than 10rem.
Kino.nothing()
Tailwind has display utility classes for controlling the display type of an element. Here are a few examples:
block
inline-block
inline
flex
See basic-usage for an explanation of these properties.
Apply the inline-block
on all of these span tags so that they can have height apply to them, and display on the same line.
Then change inline-block
to block
to see each span tag rendered on their own line.
Kino.nothing()
We can use p-{size}
and m-{size}
to set padding and margin.
The acceptable size values are the same integers as height and width: 0
, 0.5
, 1
, 1.5
, 2
, 2.5
, 3
, 3.5
, 4
, 5
, 6
, 7
, 8
, 9
, 10
, 11
, 12
, 14
, 16
, 20
, 24
, 28
, 32
, 36
, 40
, 44
, 48
, 52
, 56
, 60
, 64
, 72
, 80
, and 96
.
<p class="p-10">This paragraph has 2.5 rem or 40px of padding on each side.</p>
<p class="m-12">This paragraph has 3 rem or 48px of margin on each side.</p>
We can also set the horizontal padding/margin using py
, px
, my
, and mx
.
<p class="px-10">This paragraph has 2.5 rem or 40px of padding on the left and right side.</p>
<p class="my-12">This paragraph has 3 rem or 48px of margin on the top and bottom side.</p>
We can set padding/margin on a specific side using pt
, pr
, pb
, pl
, mt
, mr
, mb
, or ml
.
<p class="pl-10">This paragraph has 2.5 rem or 40px of padding on the left side.</p>
<p class="mt-12">This paragraph has 3 rem or 48px of margin on the top side.</p>
We're also able to set margin and padding to automatically fill the available space using -auto
. For example, we can center content using mx-auto
. Note that the content must have some width. We can sent the width of an element to be the size of its child content using w-fit
.
<p class="mx-auto w-fit">centered paragraph</p>
Create a series of rainbow boxes in the center of the page. Each box should be 3/4
of the page width.
Example Solution
<div class="bg-red-400 p-6 w-3/4 mx-auto mt-10"></div>
<div class="bg-orange-400 p-6 w-3/4 mx-auto mt-10"></div>
<div class="bg-yellow-400 p-6 w-3/4 mx-auto mt-10"></div>
<div class="bg-green-400 p-6 w-3/4 mx-auto mt-10"></div>
<div class="bg-blue-400 p-6 w-3/4 mx-auto mt-10"></div>
<div class="bg-purple-400 p-6 w-3/4 mx-auto mt-10"></div>
Kino.nothing()
We have several Tailwind classes for modifying the border of an HTML element.
We can set the border-width to 1px
using border
or provide a size using border-{size}
where size
is a valid integer of 0
, 2
, 4
, or 8
.
<!-- 1px -->
<p class="border">bordered paragraph</p>
<!-- 2px -->
<p class="border-2">bordered paragraph</p>
<!-- 4px -->
<p class="border-4">bordered paragraph</p>
<!-- 8px -->
<p class="border-8">bordered paragraph</p>
We can also set the vertical border using border-y
or the horizontal border using border-x
.
<p class="border-y-2">This paragraph has a 2px border on top and bottom side</p>
<p class="border-x-2">This paragraph has a 2px border on left and right side</p>
Finally, we can set the border width on a specific side using border-t
, border-r
, border-b
, and border-l
.
<p class="border-t-2">This paragraph has a 2px border on top side</p>
<p class="border-l-2">This paragraph has a 2px border on left side</p>
We can set the border-color using any colors from the default color palette using border-{color}
in combination with border-{size}
.
<p class="border-2 border-red-500">bordered paragraph</p>
We can round the corners of our border using rounded
.
<p class="rounded">This paragraph has a border-radius of 0.25rem or 4px </p>
We can set the border radius size using rounded-{size}
. The size
may be none
, sm
, md
, lg
, xl
, 2xl
, 3xl
, or full
.
<p class="rounded-lg">This paragraph has a border-radius of 0.5 rem or 8px</p>
We can also set the radius of a specific border corner using t
, r
, b
, l
, tl
, tr
, br
, and bl
.
<p class="rounded-r-lg">This paragraph has a top and bottom right border-radius of 0.5 rem or 8px</p>
<p class="rounded-br-lg">This paragraph has a bottom right border-radius of 0.5 rem or 8px</p>
Create a rounded rainbow using border
styles and padding
.
Example Solution
<div class="border-4 border-red-400 rounded-full p-2 mt-10 m-2">
<div class="p-2 border-4 border-orange-400 rounded-full">
<div class="p-2 border-4 border-yellow-400 rounded-full">
<div class="p-2 border-4 border-green-400 rounded-full">
<div class="p-2 border-4 border-blue-400 rounded-full">
<div class="p-2 border-4 border-purple-400 rounded-full">
</div>
</div>
</div>
</div>
</div>
</div>
Kino.nothing()
We can set the position value of an HTML element using static
(default), fixed
, absolute
, relative
, and sticky
. We often use position together with top-{size}
, right-{size}
, left-{size}
, and bottom-{size}
to adjust their positioning on the web page.
<!-- positions an element at the bottom of the screen regardless of scroll position -->
<p class="fixed bottom-0">
<!-- positions an element at the top of their parent container -->
<p class="absolute top-0">
<!-- An element will stick to the top of the current scroll position -->
<p class="sticky top-0">
<!-- positions an element 3rem or 48px downwards of where it would normally be -->
<p class="sticky bottom-12">
Use absolute
positioning to play a paragraph tag on the bottom-right corner of the display.
Kino.nothing()
We can apply styles based on the state of the element.
For example, we can use hover:
with any style to only apply that style on hover.
<button class="hover:bg-red-300 bg-red-500">hover button</button>
We can also use focus:
with any style to apply that style on focusing an element. (outline-none
removes the default outline on a text input.)
<input class="border-4 focus:border-blue-200 outline-none"></input>
See the Hover, Focus, and Other States documentation for more.
Make a button that changes styles on hover.
Kino.nothing()
We can apply styles based on the screen size using sm:
, md:
, lg:
, xl:
, and 2xl:
.
Omitting the screen size applies the style on all screens (including those smaller than sm
.)
<div class="bg-red-400 md:bg-orange-400">
Change the text size of a paragraph tag based on the screen size. Use the xs
, sm
, and md
buttons in the playground to see the styles applied.
Kino.nothing()
There's plenty more to learn! Here's a curated list of some optional reading you may find interesting and useful.
- Utility-First Fundamentals Tailwind has written an excellent overview of the benefits of using utility classes rather than an alternative approach.
- Tailwind Phoenix Guide. Tailwind includes an installation guide for using Tailwind in a Phoenix project. We'll learn more about Tailwind with Phoenix in a future lesson.
- Dark Mode Tailwind includes a
dark:
class you can use to apply styles only in dark mode. - Reusing Styles A guide on how to avoid repeating yourself with Tailwind.
- Adding Custom Styles how to add custom styles to Tailwind.
Refer to the Tailwind Documentation for more!
DockYard Academy now recommends you use the latest Release rather than forking or cloning our repository.
Run git status
to ensure there are no undesirable changes.
Then run the following in your command line from the curriculum
folder to commit your progress.
$ git add .
$ git commit -m "finish Tailwind reading"
$ git push
We're proud to offer our open-source curriculum free of charge for anyone to learn from at their own pace.
We also offer a paid course where you can learn from an instructor alongside a cohort of your peers. We will accept applications for the June-August 2023 cohort soon.