GuidesCustom Themes

Custom Themes

Kavita only supports the Dark theme out of the box. However, you can find a good starting point for Light/E-Ink themes here.

A basic light theme is available but needs some polish. It has been last updated to Kavita v0.7.14.

Kavita supports reading a .css file for custom theming.

Submit your created custom themes on our Theme repo!

There are a few things to note:

  • You only need to add variables you want to override or any custom css
  • The file must be .css
  • The filename must only contain characters, numbers, and -
  • The filename must match the top-level CSS property
  • The .css file must be placed in /config/themes
  • After placing the file in the directory, you must scan for it using the Scan button on the User Settings > Themes page before you can apply it.
  • Optionally, you can set it as Default and all new accounts will have this theme auto-selected (they can override with their preference)
  • This is limited to the properties we have exposed. (See Available CSS Variables Below)

If you would like any other properties exposed, please feel free to suggest themes in our Discord server or feature request page.

So for instance, if we created /config/themes/test-theme-123.css then the CSS within the file should be structured as follows

:root .bg-test-theme-123 {
  /* CSS Variables here */
  }

Available CSS Variables

You can use color: var(--css-variable-name) to refer to a defined css variable.

Color-scheme

This refers to the scroll bar color as well as which color placeholder images to use.

--color-scheme: dark/light;

This refers to the tab color in the browser. Modifies the meta tag. (v0.6.1.27+)

--theme-color: hex/rgb;

This refers to the tile color for the windows tile view. Modifies the meta tag. (v0.6.1.28+)

--tile-color: hex/rgb;

Main Colors

These refer to base colors you can override, you can add more and use them as additional colors for hovers.

--primary-color: hex/rgb(a);  
--primary-color-dark-shade: hex/rgb(a);  
--primary-color-darker-shade: hex/rgb(a);  
--primary-color-darkest-shade: hex/rgb(a);  
--error-color: hex/rgb(a);  
--bs-body-bg: hex/rgb(a);  // Background color for pages  
--body-text-color: hex/rgb(a);   
--btn-icon-filter: invert(1) grayscale(%) brightness(%));  // Any filter chain. Useful mainly for dark themes

Elevation System

You can find more information about Elevation here.

--elevation-layer0: rgba;
--elevation-layer1: rgba;
--elevation-layer2: rgba;
--elevation-layer3: rgba;
--elevation-layer4: rgba;
--elevation-layer5: rgba;
--elevation-layer6: rgba;
--elevation-layer7: rgba;
--elevation-layer8: rgba;
--elevation-layer9: rgba;
--elevation-layer10: rgba;
 
--elevation-layer0-dark: rgba;
--elevation-layer1-dark: rgba;
--elevation-layer2-dark: rgba;
--elevation-layer3-dark: rgba;
--elevation-layer4-dark: rgba;
--elevation-layer5-dark: rgba;
--elevation-layer6-dark: rgba;
--elevation-layer7-dark: rgba;
--elevation-layer8-dark: rgba;
--elevation-layer9-dark: rgba;
--elevation-layer10-dark: rgba;
--elevation-layer11-dark: rgba;
 
--elevation-layer0-dark-solid: hex/rgb;
--elevation-layer1-dark-solid: hex/rgb;
--elevation-layer2-dark-solid: hex/rgb;
--elevation-layer3-dark-solid: hex/rgb;
--elevation-layer4-dark-solid: hex/rgb;
--elevation-layer5-dark-solid: hex/rgb;
--elevation-layer6-dark-solid: hex/rgb;
--elevation-layer7-dark-solid: hex/rgb;
--elevation-layer8-dark-solid: hex/rgb;
--elevation-layer9-dark-solid: hex/rgb;

Colorscape

Theming colors that performs a gradient for background. Can be disabled else automatically applied based on cover image colors. --colorscape-primary-color and the alpha variants will be updated in real time. the default variant is fixed and represents the default state and should match the non-default/alpha on launch.

--colorscape-enabled: true/false;
 
/* These are the default background colors for the app. These will be updated on different pages with the generated colors. Must be RGB */
--colorscape-primary-color: rgb;
--colorscape-lighter-color: rgb;
--colorscape-darker-color: rgb;
--colorscape-complementary-color: rgb;
 
/* These need to be an alpha 0 variant. */
--colorscape-primary-color: rgba;
--colorscape-lighter-color: rgba;
--colorscape-darker-color: rgba;
--colorscape-complementary-color: rgba;
 
/* These are the default background colors. They need to match and cannot be a var reference. They will not be updated. */
--colorscape-primary-default-color: rgb;
--colorscape-lighter-default-color: rgb;
--colorscape-darker-default-color: rgb;
--colorscape-complementary-default-color: rgb;

Global

--hr-color: hex/rgb(a);  
--accent-bg-color: hex/rgb(a);  
--accent-text-color: hex/rgb(a);  
--grid-breakpoints-xs: px;  
--grid-breakpoints-sm: px;  
--grid-breakpoints-md: px;  
--grid-breakpoints-lg: px;  
--grid-breakpoints-xl: px;  
--body-font-family: "Font-Family", sans-serif;  
--brand-font-family: "Font-Family", sans-serif;  
--primary-color-scrollbar: hex/rgb(a); 
--default-state-scrollbar: hex/rgb(a); 
--text-muted-color: hex/rgb(a); 
--mobile-series-img-background: true/false; // Should we render the series cover as background on mobile

Setting Item

--setting-header-text-color: hex/rgb(a);    
--setting-break-color: hex/rgb(a);  
--setting-header-font-size: px/rem;  
--setting-header-font-weight: bold/bolder;  

Table

--table-header-bg-color: hex/rgb(a);
--table-header-text-color: hex/rgb(a);
--table-body-bg-color: hex/rgb(a);
--table-body-text-color: hex/rgb(a);
--table-body-striped-bg-color: hex/rgb(a);
--table-body-border: hex/rgb(a);
--table-body-striped-bg-color: hex/rgb(a);
--navbar-bg-color: hex/rgb(a);    
--navbar-text-color: hex/rgb(a);  
--navbar-fa-icon-color: hex/rgb(a);  
--navbar-btn-hover-outline-color: hex/rgb(a);  
--navbar-header-margin: hex/rgb(a);
--navbar-header-border-radius: hex/rgb(a);
--navbar-header-mobile-x-margin: hex/rgb(a);
--navbar-header-mobile-y-margin: hex/rgb(a);
--nav-mobile-offset: px;
--nav-offset: px;

Inputs

--input-bg-color: hex/rgb(a);  
--input-bg-readonly-color: hex/rgb(a);  
--input-focused-border-color: hex/rgb(a);  
--input-text-color: hex/rgb(a);  
--input-placeholder-color: hex/rgb(a);  
--input-border-color: hex/rgb(a);  
--input-focus-boxshadow-color: hex/rgb(a);  

Buttons

--btn-primary-text-color: hex/rgb(a);  
--btn-primary-bg-color: hex/rgb(a);  
--btn-primary-border-color: hex/rgb(a);  
--btn-primary-hover-text-color: hex/rgb(a);  
--btn-primary-hover-bg-color: hex/rgb(a);  
--btn-primary-hover-border-color: hex/rgb(a);  
 
 --btn-primary-outline-text-color: hex/rgb(a);
--btn-primary-outline-bg-color: hex/rgb(a);
--btn-primary-outline-border-color: hex/rgb(a);
--btn-primary-outline-hover-text-color: hex/rgb(a);
--btn-primary-outline-hover-bg-color: hex/rgb(a);
--btn-primary-outline-hover-border-color: hex/rgb(a);
 
--btn-secondary-text-color: hex/rgb(a);
--btn-secondary-bg-color: hex/rgb(a);
--btn-secondary-border-color: hex/rgb(a);
--btn-secondary-hover-bg-color: hex/rgb(a);
--btn-secondary-hover-border-color: hex/rgb(a);
--btn-secondary-font-weight: bold/bolder;
 
--btn-secondary-outline-text-color: hex/rgb(a);
--btn-secondary-outline-bg-color: hex/rgb(a);
--btn-secondary-outline-border-color: hex/rgb(a);
--btn-secondary-outline-hover-bg-color: hex/rgb(a);
--btn-secondary-outline-hover-border-color: hex/rgb(a);
--btn-secondary-outline-font-weight: bold/bolder;
 
 
--btn-primary-text-text-color: hex/rgb(a);
--btn-secondary-text-text-color: hex/rgb(a);
--btn-danger-text-text-color: hex/rgb(a);
 
--btn-alt-bg-color: hex/rgb(a);  
--btn-alt-border-color: hex/rgb(a);  
--btn-alt-hover-bg-color: hex/rgb(a);  
--btn-alt-focus-bg-color: hex/rgb(a);  
--btn-alt-focus-boxshadow-color: hex/rgb(a);  
--btn-fa-icon-color: hex/rgb(a);  
--btn-disabled-bg-color: hex/rgb(a);  
--btn-disabled-text-color: hex/rgb(a);  
--btn-disabled-border-color: hex/rgb(a);  
--btn-focus-boxshadow-color: hex/rgb(a);  
--nav-tab-border-color: hex/rgb(a);  
--nav-tab-text-color: hex/rgb(a);  
--nav-tab-bg-color: hex/rgb(a);  
--nav-tab-hover-border-color: hex/rgb(a);  
--nav-tab-active-text-color: hex/rgb(a);  
--nav-link-bg-color: hex/rgb(a);  
--nav-link-active-text-color: hex/rgb(a);  
--nav-link-text-color: hex/rgb(a);  
--nav-tab-border-top: hex/rgb(a);  
--nav-tab-border-left: hex/rgb(a);  
--nav-tab-border-bottom: var(--bs-body-bg);  
--nav-tab-border-right: hex/rgb(a);  
--nav-tab-hover-text-color: hex/rgb(a);  
--nav-tab-hover-bg-color: hex/rgb(a);  
--nav-tab-hover-border-top: hex/rgb(a);  
--nav-tab-hover-border-left: hex/rgb(a);  
--nav-tab-hover-border-bottom: hex/rgb(a);  
--nav-tab-hover-border-right: hex/rgb(a);  
--nav-tab-active-hover-bg-color: hex/rgb(a);  
--nav-link-bg-color: hex/rgb(a);  
--nav-link-active-text-color: hex/rgb(a);  
--nav-link-text-color: hex/rgb(a);  
--modal-bg-color: hex/rgb(a);  

Alerts

--alert-text-color: hex/rgb(a);  
--alert-bg-color: hex/rgb(a);  
--nav-header-text-color: hex/rgb(a);  
--nav-header-bg-color: hex/rgb(a);  

Toasts

--toast-success-bg-color: hex/rgb(a);  
--toast-error-bg-color: hex/rgb(a);  
--toast-info-bg-color: hex/rgb(a);  
--toast-warning-bg-color: hex/rgb(a);  

Checkboxes/Switch

--checkbox-checked-bg-color: hex/rgb(a);  
--checkbox-border-color: hex/rgb(a);  
--checkbox-focus-border-color: hex/rgb(a);  
--checkbox-focus-boxshadow-color: hex/rgb(a);  

Tag Badge

--tagbadge-border-color: hex/rgb(a);  
--tagbadge-text-color: hex/rgb(a);  
--tagbadge-bg-color: vhex/rgb(a);  
--tagbadge-filled-border-color: hex/rgb(a);  
--tagbadge-filled-text-color: hex/rgb(a);  
--tagbadge-filled-bg-color: hex/rgb(a);  

Side Nav

--side-nav-width: hex/rgb(a);  
--side-nav-bg-color: hex/rgb(a);  
--side-nav-mobile-bg-color: hex/rgb(a);  
--side-nav-openclose-transition: s ease-in-out;  
--side-nav-box-shadow: hex/rgb(a);  
--side-nav-mobile-box-shadow: px/em hex/rgb(a);  
--side-nav-hover-text-color: hex/rgb(a);  
--side-nav-hover-bg-color: hex/rgb(a);  
--side-nav-text-color: hex/rgb(a);  
--side-nav-border-radius: px;  
--side-nav-border: hex/rgb(a)/none;  
--side-nav-border-closed: hex/rgb(a)/none;  
--side-nav-border-transition: s ease-in-out;  
--side-nav-companion-bar-transistion:s linear;  
--side-nav-bg-color-transition: s ease-in-out;  
--side-nav-closed-bg-color: hex/rgb(a);  
--side-nav-item-active-color: hex/rgb(a);  
--side-nav-item-active-text-color: hex/rgb(a);  
--side-nav-active-bg-color: hex/rgb(a);  
--side-nav-overlay-color: hex/rgb(a);  
--side-nav-item-closed-color: hex/rgb(a);
--side-nav-item-closed-hover-color: hex/rgb(a);

List items

--list-group-item-text-color: hex/rgb(a);  
--list-group-item-bg-color: hex/rgb(a);  
--list-group-item-border-color: hex/rgb(a);  
--list-group-hover-text-color: hex/rgb(a);  
--list-group-hover-bg-color: hex/rgb(a);  
--list-group-active-border-color: hex/rgb(a);
--list-group-item-text-color: hex/rgb(a);
--list-group-item-bg-color: hex/rgb(a);
--search-list-group-item-bg-color: hex/rgb(a);
--list-group-hover-text-color: hex/rgb(a);
--list-group-hover-bg-color: hex/rgb(a);
--list-group-active-border-color: hex/rgb(a)/none;
--list-group-item-border-top-left-radius: px;
--list-group-item-border-top-right-radius: px;
--list-group-item-border-bottom-left-radius: px;
--list-group-item-border-bottom-right-radius: px;
--list-group-item-border-width: px;
--list-group-item-border-color: rgba;
--list-group-item-border-style: solid;
--list-group-item-first-border-width: px;
--list-group-item-last-border-width: px;

Popover

--popover-body-bg-color: hex/rgb(a);  
--popover-body-text-color: hex/rgb(a);  
--popover-outerarrow-color: hex/rgb(a);  
--popover-arrow-color: hex/rgb(a);  
--popover-bg-color: hex/rgb(a);  
--popover-border-color: hex/rgb(a);  

Pagination

--pagination-active-link-border-color: hex/rgb(a);  
--pagination-active-link-bg-color: hex/rgb(a);  
--pagination-active-link-text-color: hex/rgb(a);  
--pagination-link-border-color: hex/rgb(a);  
--pagination-link-text-color: hex/rgb(a);  
--pagination-link-bg-color: hex/rgb(a);  
--pagination-focus-border-color: hex/rgb(a);  
--pagination-link-hover-color: hex/rgb(a);

Progress Bar

--progress-striped-animated-color: linear-gradient(deg, rgba %, deg, rgba %, ..., deg, rgba %));  
--progress-bg-color: hex/rgb(a);  
--progress-bar-color: hex/rgb(a);  
--dropdown-item-hover-text-color: hex/rgb(a);  
--dropdown-item-hover-bg-color: hex/rgb(a);  
--dropdown-item-text-color: hex/rgb(a);  
--dropdown-item-bg-color: hex/rgb(a);  
--dropdown-overlay-color: hex/rgb(a);  

Accordion

--accordion-header-text-color: hex/rgb(a);  
--accordion-header-bg-color: hex/rgb(a);  
--accordion-body-bg-color: hex/rgb(a);  
--accordion-body-border-color: hex/rgb(a);  
--accordion-body-text-color: hex/rgb(a);  
--accordion-header-collapsed-text-color: hex/rgb(a);  
--accordion-header-collapsed-bg-color: hex/rgb(a);  
--accordion-button-focus-border-color: hex/rgb(a);  
--accordion-button-focus-box-shadow: hex/rgb(a);  
--accordion-active-body-bg-color: hex/rgb(a);  
--accordion-body-box-shadow: hex/rgb(a);  
--breadcrumb-bg-color: hex/rgb(a);  
--breadcrumb-item-text-color: hex/rgb(a);  

Rating star

--ratingstar-color: hex/rgb(a);  
--rating-star-color: hex/rgb(a);  
--ratingstar-star-empty: hex/rgb(a);  
--ratingstar-star-filled: hex/rgb(a);  

Card

--card-bg-color: hex/rgb(a);  
--card-text-color: hex/rgb(a);  
--card-border-width: hex/rgb(a);  
--card-border-style: hex/rgb(a);  
--card-border-color: hex/rgb(a);  
--card-progress-bar-color: hex/rgb(a);  
--card-overlay-bg-color: hex/rgb(a);  
--card-overlay-hover-bg-color: hex/rgb(a);  
--card-progress-triangle-size: hex/rgb(a);  

Slider

--slider-text-color: hex/rgb(a);
--input-range-color: hex/rgb(a);
--input-range-active-color: hex/rgb(a);

Manga Reader

--manga-reader-overlay-filter: Filter(px);  
--manga-reader-overlay-bg-color: hex/rgb(a);  
--manga-reader-overlay-text-color: hex/rgb(a);  
--manga-reader-next-highlight-bg-color: hex/rgb(a);  
--manga-reader-prev-highlight-bg-color: hex/rgb(a);  

Radios

--radio-accent-color: hex/rgb(a);  
--radio-hover-accent-color: hex/rgb(a);  
--radio-focus-boxshadow-color: hex/rgb(a);  
--carousel-header-text-color: hex/rgb(a);  
--carousel-header-text-decoration: hex/rgb(a);  
--carousel-hover-header-text-decoration: hex/rgb(a);  
--carousel-btn-color: hex/rgb(a);

Drawer

--drawer-bg-color: hex/rgb(a);
--drawer-text-color: hex/rgb(a);

Event Widget

--event-widget-bg-color: hex/rgb(a);  
--event-widget-item-bg-color: hex/rgb(a);  
--event-widget-text-color: hex/rgb(a);  
--event-widget-item-border-color: hex/rgb(a);  
--event-widget-border-color: hex/rgb(a);  
--event-widget-info-bg-color: hex/rgb(a);  
--event-widget-activity-bg-color: hex/rgb(a);  
--event-widget-update-bg-color: hex/rgb(a);  
--event-widget-error-bg-color: hex/rgb(a);  

Search Results

--search-result-text-lite-color: hex/rgb(a);

Bulk Selection

--bulk-selection-highlight-text-color: hex/rgb(a);
--bulk-selection-text-color: hex/rgb(a);
--bulk-selection-bg-color: hex/rgb(a);

Card List Item

--card-list-item-bg-color: hex/rgb(a);

Review Card

--review-card-star-color: hex/rgb(a);
--review-spoiler-bg-color: hex/rgb(a);
--review-spoiler-text-color: hex/rgb(a);

Rating Star

--rating-star-color: hex/rgb(a);

Badge

--badge-text-color: hex/rgb(a);