Styling components
Learning objectives
- Knows the principles of styling components.
- Knows that styles are component specific, and knows how to and why not to use global styling.
- Knows of the existence of component libraries.
Let's continue with the example that we just worked on, shown below.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Hello world!</title>
</head>
<body>
<nav class="p-4 mb-4 shadow">
<span class="text-2xl text-gray-700 font-serif">Hello world!</span>
</nav>
<div class="container mx-auto p-2">
<p>Hello!</p>
</div>
</body>
</html>
When building user interfaces, we use components that together form the user interface. In this case, it is also meaningful to style the individual components.
Styling and using a component
Let's look into using a component in the user interface by refactoring the navigation element into a separate component. Let's create a Svelte component TopBar.svelte
and paste the navigation component into it. The TopBar.svelte
would look as follows -- we place it in the folder components
under src
.
<nav class="p-4 mb-4 shadow">
<span class="text-2xl text-gray-700 font-serif">Hello world!</span>
</nav>
Now, we can import the component into the index.astro
and use it as is.
---
import TopBar from "../components/TopBar.svelte";
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Hello world!</title>
</head>
<body>
<TopBar />
<div class="container mx-auto p-2">
<p>Hello!</p>
</div>
</body>
</html>
When we open up the application, we notice that the look of the application has not changed, as shown in Figure 1.

Apply directive
When working with Tailwind, the style definitions can seem a bit verbose. Tailwind comes with an @apply directive that can be used to define custom styles based on Tailwind styling -- in essence, with @apply
, we define CSS styles and apply Tailwind styles to them. For example, for the above TopBar.svelte
component, we could define a style
element, which is used to define the styles for the nav
element and the span
element using @apply
. This would look as follows.
<nav>
<span>Hello world!</span>
</nav>
<style>
nav {
@apply p-4 mb-4 shadow;
}
span {
@apply text-2xl text-gray-700 font-serif;
}
</style>
The component described above would yield the same look as the component where the styles were defined using classes. When defining styles using @apply
, we can use also more explicit CSS selectors -- as an example, we could define the above styles for a class nav
and a span
element within that class. In such a case, we would need to also add the class definition to the nav
element.
<nav class="nav">
<span>Hello world!</span>
</nav>
<style>
.nav {
@apply p-4 mb-4 shadow;
}
.nav > span {
@apply text-2xl text-gray-700 font-serif;
}
</style>
Scoped styles
The styles are scoped to the components and style definitions in a component do not influence other components. As an example, if we strip the styles from TopBar.svelte
.
<nav>
<span>Hello world!</span>
</nav>
And define the styles for nav
and span
in the index.astro
, the styles are not added to the TopBar
.
---
import TopBar from "../components/TopBar.svelte";
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Hello world!</title>
</head>
<body>
<TopBar />
<div class="main">
<p>Hello!</p>
</div>
</body>
</html>
<style>
nav {
@apply p-4 mb-4 shadow;
}
span {
@apply text-2xl text-gray-700 font-serif;
}
div.main {
@apply container mx-auto p-2
}
</style>
At the same time, when you try the above example out, you'll notice that the div
in index.astro
is styled, as the styles for that are defined within the same component (here, index.astro
).
Global styles
Opting out from scoped styling is also possible. With Astro, this is done with the is:global attribute that is added to the style
element. When the is:global
is used, styles defined in it are applied globally. For example, the following styling would lead to the styling being applied also to the TopBar
component.
---
import TopBar from "../components/TopBar.svelte";
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Hello world!</title>
</head>
<body>
<TopBar />
<div class="main">
<p>Hello!</p>
</div>
</body>
</html>
<style is:global>
nav {
@apply p-4 mb-4 shadow;
}
span {
@apply text-2xl text-gray-700 font-serif;
}
div.main {
@apply container mx-auto p-2
}
</style>
Avoiding global styles for components
Although it is possible to define global styles, prefer defining styles within the specific components. This way, adjusting the styles of a component is easier, as there is no need to guess where specific styles are coming from.
Example: Hero component
Let's next work on a hero component. A hero component is a component that shows up when accessing the main page of an application -- it is used as the first thing that a user sees and somehow highlights an aspect of the application. Hero components typically have a title and a caption, and may also contain some sort of an illustration and a call to action button or link.
In our case, we'll just create a component with a title and a caption. Let's create a component called Hero.svelte
and place it to the components
folder. The Hero component is a separate section in the application, so we can use the section
element to create it. Let's start with a component with no styles -- the component simply has a heading element and a paragraph placed within a section
.
<section>
<h1>Epic Web Application</h1>
<p>Like many epic web applications, this one too has a Hero element.</p>
</section>
Let's place it into the index.astro
, immediately after the TopBar
component. Here,
---
import TopBar from "../components/TopBar.svelte";
import Hero from "../components/Hero.svelte";
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Hello world!</title>
</head>
<body>
<TopBar />
<Hero />
<div class="container mx-auto p-2">
<p>Hello!</p>
</div>
</body>
</html>
With the above modification, the application looks as shown in Figure 2. Here, we assume that we have moved the styling of TopBar
back to the component.

Let's next center the contents of the section and add padding to it. For centering, we use text-center
, and for padding, we use p-12
. The p-12
padding corresponds to 3rem
.
<section class="p-12 text-center">
<h1>Epic Web Application</h1>
<p>Like many epic web applications, this one too has a Hero element.</p>
</section>
With this change in place, the Hero element has some padding and is centered on the page. The application looks presently as shown in the Figure 3.

Next, we'll increase the size of the heading element and add some padding below it. To increase the size, we use both font-extrabold
to increase the weight and text-6xl
to increase the size. For padding, we'll use pb-6
, which corresponds to 1.5rem
.
<section class="p-12 text-center">
<h1 class="font-extrabold pb-4 text-6xl">Epic Web Application</h1>
<p>Like many epic web applications, this one too has a Hero element.</p>
</section>
The outcome of the adjustment is shown in Figure 4. Now, the h1
element in the hero component has padding and increased font size and weight.

Finally, it is common to add some contrast in the colors used in the hero element. We'll adjust the color of the paragraph and increase its size a bit. We'll use a gray color text-gray-500
and use the text-lg
as font size.
<section class="p-12 text-center">
<h1 class="font-extrabold pb-4 text-6xl">Epic Web Application</h1>
<p class="text-gray-500 text-lg">
Like many epic web applications, this one too has a Hero element.
</p>
</section>
Finally, the application looks as shown in Figure 5.

Component libraries
As user interfaces are built out of components, there are also a wide variety of component liraries that one can utilize when building the applications. Tailwind comes with the Tailwind UI component library, which is a commercial library supporting the development of Tailwind. The tailwindcomponents.com site provides a similar resource, similar to tailwind-elements.com. Such sites are meaningful to explore when looking into inspiration for components to your own application.