5. Styles, Layout, and Navigation

Decorative crown molding

An actual photo of the custom extras that were added to JAMStart

Styles

Tailwind CSS

In a .vue file you can use tailwind CSS classes directly in the elements within the <template></template> section, or you can create CSS rules in the <style></style> section. To add tailwind classes in the style section use the @apply line, for example, the class link has the tailwind CSS class p-1 and hover:bg-gray-200 applied to it.

@apply Tailwind in

<style scoped>
.link {
  @apply p-1 hover:bg-gray-200
}
</style>

Tailwind in

or the same classes used in the <template></template> section

<template>
  <a class="p-1 hover:bg-gray-200" src="">Link</a>
</template>

Deep() Bind() selectors

Two useful vue functions I found helpful with tailwind css are the :deep() and v-bind() functions. :deep() is useful to select descendent HTML elements and even ones that are dynamically placed. v-bind() allows you to feed your style section with variables from the <script></script> section

For example:

<style>
.monk-inset :deep(p) {
  font-size: v-bind('pFontSizeClass');
  line-height: v-bind('pLineHeightClass');
  height: v-bind('pLineHeightClass');
  margin: -0.2ch 0 0 0;
  @apply p-0
}
</style>

This :deep(p) selects all p sections within the element of class .monk-inset. The v-bind({variable}) brings the variables pFontSizeClass, pLineHeightClass, pLineHeightClass to set those css styles programmatically. The @apply includes tailwind classes.

Layout

The JAMStart pages belong to the Nuxt Layout system. A default layout is applied to all pages that don't contain a custom layout. This gives all the pages a common structure.

The NuxtLayout system is established in the app/app.vue file in the <template></template> section

  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>

The default page layout is specified in app/layouts/default.vue file inside its <template></template> section. The <slot /> element is where the html from the page is injected.

For example:

<template>
  <div class="mt-2 mb-2 container mx-auto max-w-4xl">
    <header class="flex justify-between items-start sm:items-center">
      <div class="flex items-center sm:space-x-12">
        <div class="hidden sm:block">
          <NuxtLink to="/" class="text-xl font-semibold p-2 hover:bg-gray-200 dark:hover:bg-gray-800">JAMStart</NuxtLink>
        </div>
        <TopMenu />
      </div>
      
      <ClientOnly>
        <ColorModeSelector />
      </ClientOnly>
    </header>
    <main class="p-1 md:p-2 mt-2 md:mt-10 mx-auto">
      <slot />
    </main>
    <Footer />
  </div>
</template>

Custom Layouts

To create a custom layout create a new layout file, i.e. another.vue in the app/layouts/ directory. Then use one of the following three ways:

  1. <NuxtLayout> element. Wherever the <NuxtLayout> element is invoked (for JAMStart it is in app/app.vue) you can add a property to choose a different layout other than default.vue. For example, <NuxtLayout :name="another"></NuxtLayout> would use the another.vue instead of default.vue.
  2. definePageMeta() macro. definePageMeta() is a compiler macro that you can use to set metadata for any page components located in the app/pages/ directory, the key layout can be used to select a custom layout. For example, to use another.vue layout
definePageMeta({
  layout: 'another'
})
  1. setPageLayout() composable. You can dynamically update the layout by using setPageLayout() composable. For example, when enableCustomLayout() is invoked, the another.vue layout is applied to the page.
function enableCustomLayout () {
  setPageLayout('another')
}