DEV Community

Paul Akinyemi
Paul Akinyemi

Posted on

How to Integrate FormKit and Bootstrap

FormKit is powerful, but for the most part, it leaves styling your forms to you. In this article, you'll learn how to style your FormKit forms with Bootstrap.

You’ll discover how to style forms individually, and how you can create an application-wide form theme that is easy to reuse in other projects.

Prerequisites and Assumptions

This guide assumes the following:

  • You have a working knowledge of FormKit, Bootstrap, and npm.
  • You understand the Vue 3 Composition API.

Setup

If you want to follow along with this guide, you'll need to do some setup work first.

Installation

Your first task is to create a Vue project with Vite. Start by navigating to the location you want your project to live in the terminal. Next, run the following command in your terminal:

npm create vite@latest
Enter fullscreen mode Exit fullscreen mode

The create-vite command will ask you a few questions. Answer them as shown in the screenshot below:
command line screenshot

Then cd into the project folder and install the necessary dependencies:

cd formkit-bootstrap
npm install
Enter fullscreen mode Exit fullscreen mode

Next, start the dev server by running: npm run dev. Visit localhost:5173 to see your application.

Now that you've set up your base Vue project, it's time to install the other dependencies you'll need: FormKit, Bootstrap, and Sass. Open another terminal window and run this code:

npm i bootstrap sass @formkit/vue @formkit/themes @formkit/utils
Enter fullscreen mode Exit fullscreen mode

Your last setup task is to clean up boilerplate you don't need. At this point, your project directory should have a structure that looks like this:

screenshot of directory structure

Delete the src/assets folder, src/components/HelloWorld.vue, and src/style.css.

Replace the content of src/App.vue with an empty template and script like so:

<script setup></script>

<template></template>
Enter fullscreen mode Exit fullscreen mode

Next, import all Bootstrap's classes by creating a file called styles.scss in src, with the following content:

// Import all of Bootstrap's CSS
@import "../node_modules/bootstrap/scss/bootstrap";
Enter fullscreen mode Exit fullscreen mode

If you only want to import some of Bootstrap's CSS, you can find the relevant import statements for the parts you want in their docs.

Then import the styling and register Formkit with your Vue app by replacing the content of src/main.js with the following:

import { createApp } from 'vue'
import { plugin, defaultConfig } from '@formkit/vue'
import './styles.scss'
import App from './App.vue'

createApp(App).use(plugin, defaultConfig).mount('#app')
Enter fullscreen mode Exit fullscreen mode

And you're done with the setup.

Styling forms individually

Next, you'll learn how to style individual forms separately.

Start by creating a basic, unstyled login form by adding the following code to the template of src/App.vue:

 <div class="row m-0">
  <FormKit
    type="form"
    submit-label="Log in"
  >
    <h2 class="mb-3"> Log In </h2>

    <FormKit type="email"
             placeholder="john@xyz.com"
             label="Email"
    ></FormKit>

    <FormKit type="password"
             placeholder="***********"
             label="Password"
    ></FormKit>

  </FormKit>
</div>
Enter fullscreen mode Exit fullscreen mode

After that, your Vue application should render a form that looks like this:

form screenshot

So, how will you style this? FormKit provides several methods for styling form inputs, from writing CSS that targets the inputs with attribute values to applying classes to inputs via props.

Before you go on, you need to understand some FormKit jargon: input sections. A section is a specific part of the rendered HTML of a FormKit input. You can find a list and description of the sections for each input in FormKit’s docs for the input.

In general, the outer section refers to an input's outermost wrapper, the input section refers to the core rendered input, and the label section targets the generated label.

The approach to styling you'll use here is to use {section}-class props to apply classes to the form inputs.

Here's what the code for the login form looks like when you style it this way:

<FormKit
    type="form"
    form-class="col-md-4 col-lg-3 mt-5 mx-auto 
                p-5 border rounded"
    :submit-attrs="{
      inputClass: 'btn btn-primary'
    }"
    submit-label="Log in"
  >
    <h2 class="mb-3"> Log In </h2>

    <FormKit type="email"
             placeholder="john@xyz.com"
             outer-class="mb-3"
             input-class="form-control"
             label="Email"
             label-class="form-label"
    ></FormKit>

    <FormKit type="password"
             placeholder="***********"
             outer-class="mb-3"
             input-class="form-control"
             label="Password"
             label-class="form-label"
    ></FormKit>

  </FormKit>
Enter fullscreen mode Exit fullscreen mode

Since you already imported Bootstrap's classes during setup, all you need to style the form is the name of the classes you want to apply to the input.

The code applies classes to sections of each input with {section}-class props that take the name of the class FormKit will apply to that section. In your login form, the outer sections get a class of mb-3, the input sections get form-control, and the label gets form-label.

Here's what the login form should look like after you style it:
styled form

And to illustrate how section classes are applied, here's what the rendered HTML for the email input might look like:

rendered input

That's the general process for styling individual forms: you apply CSS to the input sections, one input at a time.

While this works, it can become tedious and difficult to maintain if you have several forms in your app. It can also become clumsy if your app has large forms.

The solution to this is to create a theme. A theme is a baseline set of styles that FormKit applies to every form in your app.

Creating a Bootstrap theme

Before you build the theme, you'll create a new form to demo how the theme styles forms automatically.

In App.vue, replace the template for the login form with this registration form:

<FormKit
        type="form"
        submit-label="Register"
    >
      <h2 class="mb-3"> Register </h2>

      <FormKit type="text"
               placeholder="John Doe"
               label="Full Name"
      ></FormKit>

      <FormKit type="email"
               placeholder="john@xyz.com"
               label="Email"
      ></FormKit>

      <FormKit type="range"
               label="Age"
               min="0"
               max="100"
               :help="`You are ${age} years old`"
               v-model="age"
      ></FormKit>

      <FormKit type="password"
               placeholder="***********"
               label="Password"
      ></FormKit>

    </FormKit>
Enter fullscreen mode Exit fullscreen mode

Then add this code to the script section:

import {ref} from "vue";

let age = ref(18);
Enter fullscreen mode Exit fullscreen mode

At this point, your registration form should have zero styling, and should look like this:

reg form

Next, you'll create your form theme. Add a file to the root of your formkit-bootstrap directory called formkit.config.js, then put the following code in it:

import { generateClasses } from '@formkit/themes'

const config = {
  config: {
    classes: generateClasses({
      global: { // classes
        outer: '$reset mb-3',
        input: 'form-control',
        label: 'form-label',
        help: 'form-text'
      },
      form: {
        form: "col-md-4 col-lg-3 mt-5 mx-auto p-5 border rounded"
      },
      range: {
        input: '$reset form-range',
      },
      submit: {
        outer: '$reset mt-3',
        input: '$reset btn btn-primary'
      }
    })
  }
}

export default config
Enter fullscreen mode Exit fullscreen mode

This code is what's responsible for your theme, so let's break it down. The code relies on the generateClasses function from the @formkit/themes package to apply a list of classes to each section of each input type you specify.

The $reset keyword at the beginning of a class list tells FormKit to disregard any styling applied to that section before that point.

The theme you created is pretty minimal. All it does is apply Bootstrap classes to the inputs you used in your form, and define some default styling for the form container and submit buttons.

Now that you have your theme, the next step is to register it in your app. To do that, replace the code in main.js with this:

import { createApp } from 'vue'
import { plugin, defaultConfig } from '@formkit/vue'
import customConfig from '../formkit.config.js'
import './styles.scss'
import App from './App.vue'


createApp(App).use(plugin, defaultConfig({
  config: customConfig.config
})).mount('#app')
Enter fullscreen mode Exit fullscreen mode

And wait for your dev server to reload.

After your server has reloaded, check your application's page. You should see that your registration form is completely styled, and it should look like this:

styled reg form

If you feel like testing your theme a bit, you can copy the unstyled version of the login form to App.vue to see how the styling applies to it.

Here's a great thing about FormKit’s themes: all they are is a convenient baseline. Applying form-specific styling to an input will override the theme styling without conflicts. This makes it easy for you to tweak the styling of individual forms.

As an example, if you wanted to change the color of the register button to green, you could apply section styles like earlier in the article:

 <FormKit
        type="form"
        submit-label="Register"
        :submit-attrs="{
          inputClass: 'btn btn-success'
        }"
    >
Enter fullscreen mode Exit fullscreen mode

And voila.

green button reg form

Note:
Themes are framework-agnostic. As long as the classes you put in your config are part of your app's stylesheet, you can create a theme with anything from vanilla CSS to Tailwind.

Floating labels

If you want to use floating labels in your forms, you can use a plugin from this GitHub issue. Since Boostrap's floating labels are CSS-only, they won't conflict with Vue or FormKit. Just keep in mind: registering the plugin globally will give all type=text inputs floating labels.

Conclusion

At this point, you've learned how to build your forms with FormKit and style them with Bootstrap, both disparately and by creating a theme. If you need further assistance, FormKit has a Discord server where you can ask for help.

Top comments (2)

Collapse
 
andrewboyd profile image
Andrew Boyd

Excellent guide! Thank you for putting this together.

Collapse
 
morgenstern2573 profile image
Paul Akinyemi

Thank you!