Pages, Layouts, and Styles

Tailwind CSS and Skeleton


Learning Objectives

  • You know of the existence of CSS frameworks and component libraries.
  • You can set up Tailwind CSS and Skeleton in a Svelte project.

In contemporary web development, it is becoming increasingly rare to create styles from scratch — most developers rely on CSS libraries and frameworks.

A CSS framework is a collection of CSS files that contain predefined CSS rules and styling for common elements. There are many CSS frameworks available. One of the more popular ones is Tailwind CSS, which provides utility classes for styling elements. CSS frameworks can be used jointly with component libraries and UI toolkits, which come with collections of components (or styles for defining components) that are used when building the website. One such component library is Skeleton, which builds on top of Tailwind CSS.

The following two sections describe setting up Tailwind CSS and Skeleton. Addng Tailwind CSS has been adapted from Tailwind CSS SvelteKit guide, while the part on adding Skeleton has been adapted from Skeleton SvelteKit guide.

Adding Tailwind CSS

To install Tailwind CSS to the walking skeleton, go to the folder client and run the following command.

deno install --dev npm:tailwindcss npm:@tailwindcss/vite

This installs Tailwind CSS and a Vite preprocessor for Tailwind to the project. Next, modify the vite.config.js file in the client folder to match the following.

import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
	plugins: [
		tailwindcss(),
		sveltekit(),
	],
});

This change adds the Tailwind CSS plugin to the Vite configuration.

Almost ready! Now, create a file called app.css to the client/src folder. Place the following content to the file.

@import "tailwindcss";

Then, create (or modify) the +layout.svelte file in the client/src/routes folder to import the app.css file. After the change, the +layout.svelte should look as follows.

<script>
  import "../app.css";
  let { children } = $props();
</script>

{@render children()}

Finally, create (or modify) the file +page.svelte in the client/src/routes folder to match the following.

<script>
  let count = $state(0);
</script>

<h1>Hello world!</h1>
<p>Count: {count}</p>
<button onclick={() => count++}>increment</button>

Now, when you restart the application with docker compose up --build, or alternatively run the command deno run dev in the client folder, the application should look somewhat similar to the one shown in Figure 1.

Fig 1. Tailwind CSS removes styling, making e.g. level one heading look similar to normal text.

Fig 1. Tailwind CSS removes styling, making e.g. level one heading look similar to normal text.

In Figure 1, even through we have a heading element, a paragraph, and a button, they all look like normal text. This is because Tailwind CSS removes the default styling of the elements.

Tailwind forms plugin

Tailwind has a forms plugin, which we want to have in the project as well. To add it, run the following command in the client folder.

deno install --dev npm:@tailwindcss/forms

Then, modify the client/src/app.css to match the following (i.e., importing the plugin).

@import "tailwindcss";
@plugin "@tailwindcss/forms";

Now, modify the +page.svelte file to match the following.

<form class="max-w-sm mx-auto mt-6">
  <h2 class="text-2xl mb-4">Create a todo</h2>
  <div class="mb-4">
    <label for="name">Name</label>
    <input
      type="text"
      id="name"
      name="name"
      class="w-full"
      placeholder="Enter name"
    />
  </div>

  <div class="mb-4 items-center">
    <input type="checkbox" id="completed" name="completed" />
    <label for="completed" class="ml-2">Completed</label>
  </div>

  <input
    type="submit"
    class="w-full bg-blue-600 text-white p-2 rounded-lg hover:bg-blue-700"
    value="Create"
  />
</form>

Once the changes are in place, save the files, and restart the application. The page should look similar to the one shown in Figure 2.

Fig 2. A form styled with Tailwind CSS and Tailwind Forms plugin.

Fig 2. A form styled with Tailwind CSS and Tailwind Forms plugin.

The above example demonstrates the use of utility classes from Tailwind CSS. We’ll look into them in more detail in a bit, but let’s first add Skeleton to the project.

Adding Skeleton

To add Skeleton to the project, go to the client folder again, and run the following command.

deno install --dev npm:@skeletonlabs/skeleton@next npm:@skeletonlabs/skeleton-svelte@next

The command adds Skeleton 3 (release candidate or newer) dependencies to the project. Next, modify the client/src/app.css file to match the following.

@import "tailwindcss";
@plugin "@tailwindcss/forms";

@import "@skeletonlabs/skeleton";
@import "@skeletonlabs/skeleton/optional/presets";
@import "@skeletonlabs/skeleton/themes/cerberus";

@source "../node_modules/@skeletonlabs/skeleton-svelte/dist";

This brings in Skeleton and its themes to the project. Above, we have imported a theme called “cerberus” from Skeleton.

Themes are listed at https://next.skeleton.dev/docs/design/themes.

Then, modify the app.html file in the client/src folder to match the following.

<!doctype html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<link rel="icon" href="%sveltekit.assets%/favicon.png" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		%sveltekit.head%
	</head>
	<body data-sveltekit-preload-data="hover" data-theme="cerberus">
		<div style="display: contents">%sveltekit.body%</div>
	</body>
</html>

The above change adds the data-theme attribute with the value “cerberus” to the body element, setting the theme of the application to the “cerberus” theme from Skeleton.

Now, modify the client/src/routes/+page.svelte file to match the following.

<form class="mx-auto w-full max-w-md space-y-4">
  <h2 class="h2">Create a todo</h2>

  <label for="name" class="label">
    <span class="label-text">Name</span>
    <input class="input" type="text" id="name" name="name" />
  </label>

  <label class="flex items-center space-x-2">
    <input class="checkbox" type="checkbox" id="completed" name="completed" />
    <p>Completed</p>
  </label>

  <button type="submit" class="w-full btn preset-filled-primary-500">
    Create
  </button>
</form>

After restarting the application, the form should look similar to the one shown in Figure 3.

Fig 3. Form styled with Skeleton and Tailwind CSS

Fig 3. Form styled with Skeleton and Tailwind CSS
Loading Exercise...