Published on

How to Change CSS in PrimeVue: A Comprehensive Guide

Authors

Introduction

PrimeVue offers a powerful feature called Pass Through props, which allows developers to access and modify the internal DOM structure of components. This guide will walk you through various methods to customize CSS in PrimeVue, from basic usage to advanced techniques.

Basic Usage(Pass Through)

Each component has a special pt property to define an object with keys corresponding to the available DOM elements. Each value can either be a string, an object or a function that returns a string or an object to define the arbitrary properties to apply to the element such as styling, aria, data-* or custom attributes. If the value is a string or a function that returns a string, it is considered as a class definition and added to the class attribute of the element. Every component documentation has a dedicated section to document the available section names exposed via PT.

Most common usage of pt is styling and customization. The class and style properties support the exact syntax of the corresponding Vue bindings like arrays, objects and conditionals. Example below styles a Panel component with PrimeFlex CSS library.

Here's a basic example of styling a Panel component:


<template>
    <div class="card">
        <Panel header="Header" toggleable
            :pt="{
                header: (options) => ({
                    id: 'myPanelHeader',
                    style: {
                        'user-select': 'none'
                    },
                    class: [
                        'border-primary',
                        {
                            'bg-primary text-primary-contrast': options.state.d_collapsed,
                            'text-primary bg-primary-contrast': !options.state.d_collapsed
                        }
                    ]
                }),
                content: { class: 'border-primary text-lg text-primary-700' },
                title: 'text-xl',                                     // OR { class: 'text-xl' }
                toggler: () => 'bg-primary text-primary-contrast hover:text-primary hover:bg-primary-contrast'  // OR { class: 'bg-primary text-primary-contrast hover:text-primary hover:bg-primary-contrast' }
            }">
            <p class="m-0">
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
                Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
            </p>
        </Panel>
    </div>
</template>

<script setup>
</script>

Declarative Syntax

The declarative syntax is useful for simple cases where you want to apply static styles to components. It's easy to read and understand, making it ideal for quick customizations.

Here's an example of using the declarative syntax to style a Button component:

<Panel
    pt:root:class="border border-solid"
    pt:header:id="headerId"
    pt:header:data-test-id="testId"
    pt:header:class="bg-blue-500"
    :pt:header:onClick="onHeaderClick"
>
    <Button
        label="Click Me"
        :pt="{
            root: 'bg-blue-500 text-white',
            icon: 'text-white',
            label: 'text-white'
        }"
    />
</Panel>

The declarative syntax provides an alternative to the programmatic syntax. The attributes that start with pt are interpreted differently by the component based on the format below.


<ComponentTag pt:[passthrough_key]:[attribute]="value" />

This syntax provides an alternative to the programmatic approach, making it easier to read and maintain in some cases.

Lifecycle Hooks

PrimeVue components provide lifecycle hooks that allow you to customize the behavior of components at different stages of their lifecycle. You can use these hooks to apply custom styles to components based on their state or user interactions.

You can access component lifecycle hooks through the hooks property:

<Panel header="Header" :pt="panelPT">
    Content
</Panel>

Available hooks include onBeforeCreate, onCreated, onBeforeUpdate, onUpdated, onBeforeMount, onMounted, onBeforeUnmount, and onUnmounted.

Global Configuration

PrimeVue allows for global Pass Through configurations:

import PrimeVue from 'primevue/config';
import { createApp } from "vue";

const app = createApp(App);

app.use(PrimeVue, {
    pt: {
        panel: {
            header: {
                class: 'bg-primary text-primary-contrast'
            }
        },
        autocomplete: {
            input: {
                root: 'w-64'
            }
        }
    }
});

app.mount('#app');

This sets default styles for all Panel and Autocomplete components, which can be overridden by individual component pt props.

Custom CSS

The global configuration also supports custom CSS:

import PrimeVue from 'primevue/config';
import { createApp } from "vue";

const app = createApp(App);

app.use(PrimeVue, {
    pt: {
        global: {
            css: `
                button {
                    padding: 2rem;
                }
                .p-ink {
                    display: block;
                    position: absolute;
                    background: rgba(255, 255, 255, 0.5);
                    border-radius: 100%;
                    transform: scale(0);
                    pointer-events: none;
                }
                .p-ink-active {
                    animation: ripple 0.4s linear;
                }
                @keyframes ripple {
                    100% {
                        opacity: 0;
                        transform: scale(2.5);
                    }
                }
            `
        }
    }
});

app.mount('#app');

UsePassThrough Utility

PrimeVue provides a usePassThrough utility function to simplify the process of defining Pass Through props. This function takes a component name and an object with keys corresponding to the available DOM elements and returns a function that can be used to define the pt prop for the component.

Here's an example of using the usePassThrough utility function to define Pass Through props for a Panel component:

import { usePassThrough } from "primevue/passthrough";
import BasePreset from "./basepreset";

const CustomPreset = usePassThrough(
    BasePreset,
    {
        panel: {
            title: {
                class: ['leading-none font-light text-2xl']
            }
        }
    },
    {
        mergeSections: true,
        mergeProps: false
    }
);

app.use(PrimeVue, { unstyled: true, pt: CustomPreset });

This utility provides fine-grained control over how custom configurations are merged with base presets.

Conclusion

Customizing CSS in PrimeVue components is a powerful feature that allows you to create unique and visually appealing user interfaces. By using Pass Through props, lifecycle hooks, global configurations, and custom CSS, you can easily style components to match your design requirements. Experiment with different techniques to find the best approach for your project and create stunning UIs with PrimeVue.

PrimeVue's Pass Through props offer a flexible and powerful way to customize component styles. Whether you prefer programmatic or declarative syntax, global or component-specific styling, PrimeVue provides the tools to create unique and consistent user interfaces.

I hope this guide has been helpful in understanding how to change CSS in PrimeVue components. If you have any questions or feedback, feel free to leave a comment below. Happy coding!

References