V7 Custom CSS Migration Guide
Table of Contents
If you customized the look of your calendar by targeting the built-in fc-* class-names, this document will help you migrate to the future-proof settings-based approach.
Before You Begin
Start from Scratch?
If you have a lot of custom CSS, rewriting it will be a lot of work. Just look at the length of this guide! As a first step, see if your design more closely matches some of the themes on themes.fullcalendar.io, moreso than the “Classic” theme from v6. If that’s the case, it might be worth writing your styles from scratch, using one of the newer themes as a base. The index of styling hooks will be a valuable reference.
clsx
Many migrations in this document show the merging of multiple class-names with the clsx utility. It’s especially important for conditional class-names. Installation:
npm install --save clsx In the JS:
import clsx from 'clsx'
const bool = true
clsx('you', 'can', 'merge', bool && 'okay?') // "you can merge okay?" Tailwind
In this document, all migrations start as vanilla CSS and end as vanilla CSS. Most of the migration is simply wiring up existing CSS to newly exposed settings. If you prefer to use Tailwind, you can bypass the CSS altogether. Example:
/* instead of vanilla CSS... */
- .fc-toolbar {
+ .my-toolbar {
background: red;
}
// in JS settings
+ toolbarClass: 'my-toolbar'// ...just use Tailwind
+ toolbarClass: 'bg-red-500'Top-Level
The .fc className was on the root of each calendar and the selector was often used to increase precedence. It no longer exists.
- .fc .some-selector { /* custom CSS */ }
+ .some-selector { /* custom CSS */ } Direction:
- .fc-direction-ltr { /* LRT CSS */ }
- .fc-direction-rtl { /* RTL CSS */ }
+ :root { /* general CSS */ }
+ [dir=rtl] { /* RTL overrides */ } Media (print or screen):
- .fc-media-print { /* print-only CSS */ }
- .fc-media-screen { /* screen-only CSS */ }
+ @media print { /* print-only CSS */ }
+ @media screen { /* screen-only CSS */} Page background color (for Classic Theme only):
:root {
/* page background color */
- --fc-page-bg-color: grey;
+ --fc-classic-background: grey;
} Removing the outer border was difficult before. It required messy CSS overrides. There are now settings for this:
- .fc-scrollgrid,
- .fc-scrollgrid-section > *,
- .fc-list,
- .fc-multimonth {
- border: none !important;
- }
// in JS settings
+ borderless: true // ALSO: borderlessTop, borderlessBottom, borderlessX Theme-system specific class-names have been removed:
- .fc-theme-standard {}
- .fc-theme-bootstrap {}
- .fc-theme-bootstrap5 {}
- .fc-theme-bootstrap5-shaded {} Toolbar
Header toolbar specifically:
- .fc-header-toolbar {
+ .my-header-toolbar {
/* custom css */
}
// in JS settings
+ headerToolbarClass: 'my-header-toolbar' Footer toolbar specifically:
- .fc-footer-toolbar {
+ .my-footer-toolbar {
/* custom css */
}
// in JS settings
+ footerToolbarClass: 'my-footer-toolbar' Any toolbar:
- .fc-toolbar {
+ .my-toolbar {
/* custom css */
}
// in JS settings
+ toolbarClass: 'my-toolbar' Toolbar Section
A subsection of the toolbar, like left/center/right.
- .fc-toolbar-chunk {
+ .my-toolbar-section {
/* custom css */
}
// in JS settings
+ toolbarSectionClass: 'my-toolbar-section' Title
The title text element within toolbar:
- .fc-toolbar-title {
+ .my-toolbar-title {
/* custom css */
}
// in JS settings
+ toolbarTitleClass: 'my-toolbar-title' Button Group
/* css */
- .fc-button-group {
+ .my-button-group {
/* custom css */
}
// in JS settings
+ buttonGroupClass: 'my-button-group' Buttons
All buttons:
- .fc-button { /* OR .fc-button-primary */
+ .my-button {
/* custom css */
}
// in JS settings
+ buttonClass: 'my-button' Specific button:
- .fc-next-button {
+ .my-next-button {
/* custom css */
}
- .fc-icon-chevron-right {} /* usually "next" button */
- .fc-icon-chevrons-right {} /* usually "nextYear" button */
- .fc-icon-chevron-left {} /* usually "prev" button */
- .fc-icon-chevrons-left {} /* usually "prevYear" button */
// in JS settings
+ buttons: {
+ next: {
+ className: 'my-next-button'
+ }
+ // prev/prevYear/etc...
+ } Currently-selected button in button-group:
- .fc-button-active {
+ .my-button-active {
/* custom css */
}
// in JS settings
+ buttonClass: (data) => clsx(data.isSelected && 'my-button-active') Icons within buttons:
- .fc-button .fc-icon {
+ .my-button-icon {
/* custom CSS */
/* NOTE: rethink your vertical alignment technique. v7 uses flexbox */
- vertical-align: baseline;
}
// in JS settings
+ buttons: {
+ next: {
+ iconClass: 'my-button-icon',
+ // OR
+ iconContent: () => <svg className='my-button-icon'></svg>
+ },
+ prev: {
+ // SAME. must be applied to each INDIVIDUAL button entry
+ }
+ } Button colors (for Classic Theme only):
:root {
/* default button state */
- --fc-button-bg-color: #2C3E50;
+ --fc-classic-button: #2C3E50;
- --fc-button-border-color: #2C3E50;
+ --fc-classic-button-border: #2C3E50;
- --fc-button-hover-bg-color: #1a252f;
+ --fc-classic-button-over: #1a252f;
- --fc-button-hover-border-color: #1a252f;
+ --fc-classic-button-border-over: #1a252f;
- --fc-button-text-color: #fff;
+ --fc-classic-button-foreground: #fff;
/* selected button state */
- --fc-button-active-bg-color: #151e27;
+ --fc-classic-button-selected: #151e27;
- --fc-button-active-border-color: #151e27;
+ --fc-classic-button-border-selected: #151e27;
} Events (General)
Foreground (Normal) Events
- .fc-event {
+ .my-event {
/* custom css */
}
// in JS
+ eventClass: 'my-event' When the event segment represents the event’s start:
- .fc-event-start {
+ .my-event-start {
/* custom css */
}
// in JS
+ eventClass: (data) => clsx(data.isStart && 'my-event-start') When the event segment represents the event’s end:
- .fc-event-end {
+ .my-event-end {
/* custom css */
}
// in JS
+ eventClass: (data) => clsx(data.isEnd && 'my-event-end') Future event:
- .fc-event-future {
+ .my-event-future {
/* custom css */
}
// in JS
+ eventClass: (data) => clsx(data.isFuture && 'my-event-future') Past event:
- .fc-event-past {
+ .my-event-past {
/* custom css */
}
// in JS
+ eventClass: (data) => clsx(data.isPast && 'my-event-past') Event occuring today:
- .fc-event-today {
+ .my-event-today {
/* custom css */
}
// in JS
+ eventClass: (data) => clsx(data.isToday && 'my-event-today') Selected state:
- .fc-event-selected {
+ .my-event-selected {
/* custom css */
}
// in JS
+ eventClass: (data) => clsx(data.isSelected && 'my-event-selected') Draggable state:
- .fc-event-draggable {
+ .my-event-draggable {
/* custom css */
}
// in JS
+ eventClass: (data) => clsx(data.isDraggable && 'my-event-draggable') Dragging state:
- .fc-event-dragging {
+ .my-event-dragging {
/* custom css */
}
// in JS
+ eventClass: (data) => clsx(data.isDragging && 'my-event-dragging') Event “mirror” that appears during dragging/resize:
- .fc-event-mirror {
+ .my-event-mirror {
/* custom css */
}
// in JS
+ eventClass: (data) => clsx(data.isMirror && 'my-event-mirror') Resizable state:
- .fc-event-resizable {
+ .my-event-resizable {
/* custom css */
}
// in JS
+ eventClass: (data) => clsx((data.isStartResizable || data.isEndResizable) && 'my-event-resizable') Resizing state:
- .fc-event-resizing {
+ .my-event-resizing {
/* custom css */
}
// in JS
+ eventClass: (data) => clsx(data.isResizing && 'my-event-resizing') The resizer sub-element:
- .fc-event-resizer {
+ .my-event-resizer {
/* custom css */
}
// in JS
+ eventBeforeClass: (data) => clsx(data.isStartResizable && 'my-event-resizer')
+ eventAfterClass: (data) => clsx(data.isEndResizable && 'my-event-resizer') The start-resizer sub-element:
- .fc-event-resizer-start {
+ .my-event-resizer-start {
/* custom css */
}
// in JS
+ eventBeforeClass: (data) => clsx(data.isStartResizable && 'my-event-resizer-start') The end-resizer sub-element:
- .fc-event-resizer-end {
+ .my-event-resizer-end {
/* custom css */
}
// in JS
+ eventAfterClass: (data) => clsx(data.isEndResizable && 'my-event-resizer-end') The inner-element that wraps the time and title:
- .fc-event-main { /* OR .fc-event-title-container */
+ .my-event-inner {
/* custom css */
}
// in JS
+ eventInnerClass: 'my-event-inner' Time sub-element:
- .fc-event-time {
+ .my-event-time {
/* custom css */
}
// in JS
+ eventTimeClass: 'my-event-time' Title sub-element:
- .fc-event-title { /* OR .fc-event-title-container */
+ .my-event-title {
/* custom css */
}
// in JS
+ eventTitleClass: 'my-event-title' Event colors (for Classic Theme only):
:root {
/* NOTE: the classic theme forces both background and border as same color */
- --fc-event-bg-color: red;
- --fc-event-border-color: red;
+ --fc-classic-primary: red;
- --fc-event-text-color: white;
+ --fc-classic-primary-foreground: white;
} Event-related CSS variables that have no replacement:
:root {
- --fc-small-font-size: 9px; /* applied to events & more-link */
- --fc-event-resizer-dot-border-width: 1px
- --fc-event-resizer-dot-total-width: 8px;
- --fc-event-resizer-thickness: 8px;
- --fc-event-selected-overlay-color: red; /* dimming effect when selected. UX is different now */
} Background Events
- .fc-bg-event {
+ .my-bg-event {
/* custom css */
}
// in JS
+ backgroundEventClass: 'my-bg-event' When the event segment represents the event’s start:
- .fc-bg-event.fc-event-start {
+ .my-bg-event-start {
/* custom css */
}
// in JS
+ backgroundEventClass: (data) => clsx(data.isStart && 'my-bg-event-start') When the event segment represents the event’s end:
- .fc-bg-event.fc-event-end {
+ .my-bg-event-end {
/* custom css */
}
// in JS
+ backgroundEventClass: (data) => clsx(data.isEnd && 'my-bg-event-end') Future event:
- .fc-bg-event.fc-event-future {
+ .my-bg-event-future {
/* custom css */
}
// in JS
+ backgroundEventClass: (data) => clsx(data.isFuture && 'my-bg-event-future') Past event:
- .fc-bg-event.fc-event-past {
+ .my-bg-event-past {
/* custom css */
}
// in JS
+ backgroundEventClass: (data) => clsx(data.isPast && 'my-bg-event-past') Event occuring today:
- .fc-bg-event.fc-event-today {
+ .my-bg-event-today {
/* custom css */
}
// in JS
+ backgroundEventClass: (data) => clsx(data.isToday && 'my-bg-event-today') Background event colors (for Classic Theme only):
:root {
- --fc-bg-event-color: red;
+ --fc-classic-background-event: red;
- --fc-bg-event-opacity: 10%;
+ --fc-classic-background-event-opacity: 10%;
} Horizontal Events (aka “Row Events”)
These selectors and settings allow targetting both DayGrid and Timeline events at the same time.
- .fc-h-event {
+ .my-row-event {
/* custom css */
}
// in JS
+ rowEventClass: 'my-row-event' When the event segment represents the event’s start:
- .fc-h-event.fc-event-start {
+ .my-row-event-start {
/* custom css */
}
// in JS
+ rowEventClass: (data) => clsx(data.isStart && 'my-row-event-start') When the event segment represents the event’s end:
- .fc-h-event.fc-event-end {
+ .my-row-event-end {
/* custom css */
}
// in JS
+ rowEventClass: (data) => clsx(data.isEnd && 'my-row-event-end') Future event:
- .fc-h-event.fc-event-future {
+ .my-row-event-future {
/* custom css */
}
// in JS
+ rowEventClass: (data) => clsx(data.isFuture && 'my-row-event-future') Past event:
- .fc-h-event.fc-event-past {
+ .my-row-event-past {
/* custom css */
}
// in JS
+ rowEventClass: (data) => clsx(data.isPast && 'my-row-event-past') Event occuring today:
- .fc-h-event.fc-event-today {
+ .my-row-event-today {
/* custom css */
}
// in JS
+ rowEventClass: (data) => clsx(data.isToday && 'my-row-event-today') Selected state:
- .fc-h-event.fc-event-selected {
+ .my-row-event-selected {
/* custom css */
}
// in JS
+ rowEventClass: (data) => clsx(data.isSelected && 'my-row-event-selected') Draggable state:
- .fc-h-event.fc-event-draggable {
+ .my-row-event-draggable {
/* custom css */
}
// in JS
+ rowEventClass: (data) => clsx(data.isDraggable && 'my-row-event-draggable') Dragging state:
- .fc-h-event.fc-event-dragging {
+ .my-row-event-dragging {
/* custom css */
}
// in JS
+ rowEventClass: (data) => clsx(data.isDragging && 'my-row-event-dragging') Event “mirror” that appears during dragging/resize:
- .fc-h-event.fc-event-mirror {
+ .my-row-event-mirror {
/* custom css */
}
// in JS
+ rowEventClass: (data) => clsx(data.isMirror && 'my-row-event-mirror') Resizable state:
- .fc-h-event.fc-event-resizable {
+ .my-row-event-resizable {
/* custom css */
}
// in JS
+ rowEventClass: (data) => clsx((data.isStartResizable || data.isEndResizable) && 'my-row-event-resizable') Resizing state:
- .fc-h-event.fc-event-resizing {
+ .my-row-event-resizing {
/* custom css */
}
// in JS
+ rowEventClass: (data) => clsx(data.isResizing && 'my-row-event-resizing') The resizer sub-element:
- .fc-h-event .fc-event-resizer {
+ .my-row-event-resizer {
/* custom css */
}
// in JS
+ rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-row-event-resizer')
+ rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-row-event-resizer') The start-resizer sub-element:
- .fc-h-event .fc-event-resizer-start {
+ .my-row-event-resizer-start {
/* custom css */
}
// in JS
+ rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-row-event-resizer-start') The end-resizer sub-element:
- .fc-h-event .fc-event-resizer-end {
+ .my-row-event-resizer-end {
/* custom css */
}
// in JS
+ rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-row-event-resizer-end') The inner-element that wraps the time and title:
- .fc-h-event .fc-event-main {
+ .my-row-event-main {
/* custom css */
}
// in JS
+ rowEventInnerClass: 'my-row-event-main' Time sub-element:
- .fc-h-event .fc-event-time {
+ .my-row-event-time {
/* custom css */
}
// in JS
+ rowEventTimeClass: 'my-row-event-time' Title sub-element:
- .fc-h-event .fc-event-title {
+ .my-row-event-title {
/* custom css */
}
// in JS
+ rowEventTitleClass: 'my-row-event-title' Resources (General)
TODO: link to fc-resource stuff. label too?
Popover & More-Link
More-Link
The link that triggers a popover:
- .fc-more-link {
+ .my-more-link {
/* custom css */
}
// in JS
+ moreLinkClass: 'my-more-link' The above code shows how to style all more-links, but it’s possible to target specific ones.
More-link colors (for Classic Theme only):
:root {
/* bg color - easy */
- --fc-more-link-bg-color: #374151;
+ --fc-classic-strong: #374151; /* now uses a general-purpose neutral color */
/* text color - needs more complex migration... */
- --fc-more-link-text-color: #fff;
}
+ .my-more-link-inner {
+ color: #fff;
+ }
// in JS settings
+ moreLinkInnerClass: 'my-more-link-inner' Popover
Popover root element:
- .fc-popover { /* OR .fc-more-popover */
+ .my-popover {
/* custom css */
}
// in JS
+ popoverClass: 'my-popover' Popover for future date:
- .fc-popover.fc-day-future {
+ .my-popover-future { /* will apply separately to both popover header and body */
/* custom css */
}
// in JS settings
+ dayHeaderClass: (data) => clsx((data.inPopover && data.isFuture) && 'my-popover-future'),
+ dayCellClass: (data) => clsx((data.inPopover && data.isFuture) && 'my-popover-future'), Popover for past date:
- .fc-popover.fc-day-past {
+ .my-popover-past { /* will apply separately to both popover header and body */
/* custom css */
}
// in JS settings
+ dayHeaderClass: (data) => clsx((data.inPopover && data.isPast) && 'my-popover-past'),
+ dayCellClass: (data) => clsx((data.inPopover && data.isPast) && 'my-popover-past'), Popover for today:
- .fc-popover.fc-day-today {
+ .my-popover-today { /* will apply separately to both popover header and body */
/* custom css */
}
// in JS settings
+ dayHeaderClass: (data) => clsx((data.inPopover && data.isToday) && 'my-popover-today'),
+ dayCellClass: (data) => clsx((data.inPopover && data.isToday) && 'my-popover-today'), Popover for other month:
- .fc-popover.fc-day-other {
+ .my-popover-other { /* will apply separately to both popover header and body */
/* custom css */
}
// in JS settings
+ dayHeaderClass: (data) => clsx((data.inPopover && data.isOther) && 'my-popover-other'),
+ dayCellClass: (data) => clsx((data.inPopover && data.isOther) && 'my-popover-other'), Popover for specific day-of-week:
- .fc-popover.fc-day-sun {
+ .my-popover-sun {
/* custom CSS */
}
// in JS settings, timeZone='local'
+ dayHeaderClass: (data) => clsx((data.inPopover && data.getDay() === 0) && 'my-popover-sun'),
+ dayCellClass: (data) => clsx((data.inPopover && data.getDay() === 0) && 'my-popover-sun'),
// in JS settings, timeZone='UTC'
+ dayHeaderClass: (data) => clsx((data.inPopover && data.getUTCDay() === 0) && 'my-popover-sun'),
+ dayCellClass: (data) => clsx((data.inPopover && data.getUTCDay() === 0) && 'my-popover-sun'), For other days of week, modify the above example:
.fc-popover.fc-day-mon- change the=== 0to=== 1.fc-popover.fc-day-tue- change the=== 0to=== 2.fc-popover.fc-day-wed- change the=== 0to=== 3.fc-popover.fc-day-thu- change the=== 0to=== 4.fc-popover.fc-day-fri- change the=== 0to=== 5.fc-popover.fc-day-sat- change the=== 0to=== 6
Popover close button:
- .fc-popover-close { /* OR .fc-icon-x */
+ .my-popover-close {
/* custom css */
}
// in JS
+ popoverCloseClass: 'my-popover-close' Popover header (now a “day-header”):
- .fc-popover-header {
+ .my-popover-header {
/* custom css */
}
// in JS
+ dayHeaderClass: (data) => clsx(data.inPopover && 'my-popover-header') Popover title text element:
- .fc-popover-title {
+ .my-popover-title {
/* custom css */
}
// in JS
+ dayHeaderInnerClass: (data) => clsx(data.inPopover && 'my-popover-title') Popover header (now a “day-cell”):
- .fc-popover-body {
+ .my-popover-body {
/* custom css */
}
/* would wrap custom injected content (no longer possible) */
- .fc-more-popover-misc {}
// in JS
+ dayCellClass: (data) => clsx(data.inPopover && 'my-popover-body') Calendar Views (General)
All views:
- .fc-view {
+ .my-view {
/* custom css */
}
// in JS settings
+ viewClass: 'my-view' A specific view:
- .fc-timeGridWeek-view {
+ .my-timeGridWeek-view {
/* custom css */
}
// in JS settings
+ views: {
+ timeGridWeek: {
+ viewClass: 'my-timeGridWeek-view'
+ }
+ } Table Header Cells
Alignment for content within all header cells:
/* in CSS */
- .fc th {
- text-align: left;
- }
// in JS
+ dayHeaderAlign: 'left',
+ resourceDayHeaderAlign: 'left', Any other custom CSS for header cells:
/* in CSS */
- .fc th {
+ .my-header-class {
font-weight: 900;
}
// in JS
+ dayHeaderClass: 'my-header-class',
+ resourceDayHeaderClass: 'my-header-class',
+ listDayHeaderClass: 'my-header-class',
+ views: {
+ timeline: {
+ slotHeaderClass: 'my-header-class',
+ }
+ } NOTE: the default font-weight for header cells in DayGrid, TimeGrid, Timeline, and Resource-Timeline is now normal. If you wrote CSS to force normal, it is now unnecessary.
Background Colors (for Classic Theme only)
Colors for specific elements:
:root {
- --fc-border-color: #d0d7de;
+ --fc-classic-border: #d0d7de;
- --fc-now-indicator-color: #ef4444;
+ --fc-classic-now: #ef4444;
- --fc-today-bg-color: #fef3c7;
+ --fc-classic-today: #fef3c7;
- --fc-highlight-color: #fde68a;
+ --fc-classic-highlight: #fde68a;
- --fc-non-business-color: #f3f4f6;
+ --fc-classic-faint: #f3f4f6; /* now uses a general-purpose neutral color */
} Migrations for existing general-purpose neutral colors:
- --fc-neutral-bg-color: #f3f4f6;
+ --fc-classic-muted: #f3f4f6;
- --fc-neutral-text-color: #4b5563;
+ --fc-classic-muted-foreground: #4b5563; If you were customizing .fc-cell-shaded directly instead of --fc-neutral-bg-color:
- .fc-cell-shaded {
- background: red;
- }
+ :root {
+ --fc-classic-muted: red;
+ } If you were customizing .fc-highlight directly instead of --fc-highlight-color:
- .fc-highlight {
+ .my-highlight {
/* custom css */
}
// in JS
+ highlightClass: 'my-highlight' If you were customizing .fc-non-business directly instead of --fc-non-business-color:
- .fc-non-business {
+ .my-non-business {
/* custom css */
}
// in JS
+ nonBusinessClass: 'my-non-business' Obsolete
These class-names were intended internal-only and are now removed:
- .fc-view-harness {}
- .fc-view-harness-active {}
- .fc-view-harness-passive {}
- .fc-scrollgrid-section-liquid {}
- .fc-scrollgrid-section-footer {}
- .fc-scrollgrid-collapsible {}
- .fc-scrollgrid-liquid {}
- .fc-scrollgrid-shrink {}
- .fc-scrollgrid-shrink-cushion {}
- .fc-scrollgrid-shrink-frame {}
- .fc-scrollgrid-sticky-shim {}
- .fc-scrollgrid-sync-inner {}
- .fc-scrollgrid-sync-table {}
- .fc-scroller {}
- .fc-scroller-harness {}
- .fc-scroller-harness-liquid {}
- .fc-scroller-liquid {}
- .fc-scroller-liquid-absolute {}
- .fc-sticky {}
- .fc-liquid-hack {}
- .fc-not-allowed {}
- .fc-license-message {} DayGrid View
Root view element:
- .fc-daygrid { /* OR .fc-daygrid .fc-scrollgrid */
+ .my-daygrid-view {
/* custom CSS */
}
// in JS settings
+ views: {
+ daygrid: {
+ viewClass: 'my-daygrid-view'
+ }
+ } Table Structure
Table header section:
- .fc-daygrid .fc-scrollgrid-section-header { /* OR .fc-daygrid .fc-col-header */
+ .my-daygrid-header {
/* custom CSS */
}
// in JS settings
+ views: {
+ dayGrid: {
+ tableHeaderClass: 'my-daygrid-header'
+ }
+ } Sticky table header section:
- .fc-daygrid .fc-scrollgrid-section-sticky {
+ .my-daygrid-header-sticky {
/* custom CSS */
}
// in JS settings
+ views: {
+ dayGrid: {
+ tableHeaderClass: (data) => clsx(data.isSticky && 'my-daygrid-header-sticky')
+ }
+ } Table body section:
- .fc-daygrid .fc-scrollgrid-section-body { /* OR .fc-daygrid-body */
+ .my-daygrid-body {
/* custom CSS */
}
// in JS settings
+ views: {
+ dayGrid: {
+ tableBodyClass: 'my-daygrid-body'
+ }
+ } Day Header Cells
- .fc-col-header-cell {
+ .my-day-header {
/* custom css */
}
// in JS
+ dayHeaderClass: 'my-day-header' Day-of-week:
- .fc-col-header-cell.fc-day-sun {
+ .my-header-cell-sun {
/* custom CSS */
}
// in JS settings, timeZone='local'
+ dayCellClass: (data) => clsx(data.getDay() === 0 && 'my-header-cell-sun'),
// in JS settings, timeZone='UTC'
+ dayCellClass: (data) => clsx(data.getUTCDay() === 0 && 'my-header-cell-sun'), For other days of week, modify the above example:
.fc-col-header-cell.fc-day-mon- change the=== 0to=== 1.fc-col-header-cell.fc-day-tue- change the=== 0to=== 2.fc-col-header-cell.fc-day-wed- change the=== 0to=== 3.fc-col-header-cell.fc-day-thu- change the=== 0to=== 4.fc-col-header-cell.fc-day-fri- change the=== 0to=== 5.fc-col-header-cell.fc-day-sat- change the=== 0to=== 6
Inner-wrapper within table header cell:
- .fc-col-header-cell-cushion {
+ .my-day-header-inner {
/* custom css */
}
// in JS
+ dayHeaderInnerClass: 'my-day-header-inner' Day Body Cells
- .fc-daygrid-day {
+ .my-cell {
/* custom CSS */
}
// in JS settings
+ dayCellClass: 'my-cell' Future day:
- .fc-daygrid-day.fc-day-future {
+ .my-cell-future {
/* custom css */
}
// in JS settings
+ dayCellClass: (data) => clsx(data.isFuture && 'my-cell-future'), Past day:
- .fc-daygrid-day.fc-day-past {
+ .my-cell-past {
/* custom css */
}
// in JS settings
+ dayCellClass: (data) => clsx(data.isPast && 'my-cell-past'), Today:
- .fc-daygrid-day.fc-day-today {
+ .my-cell-today {
/* custom css */
}
// in JS settings
+ dayCellClass: (data) => clsx(data.isToday && 'my-cell-today'), Other month:
- .fc-daygrid-day.fc-day-other {
+ .my-cell-other {
/* custom css */
}
// in JS settings
+ dayCellClass: (data) => clsx(data.isOther && 'my-cell-other'), Day-of-week:
- .fc-daygrid-day.fc-day-sun {
+ .my-cell-sun {
/* custom CSS */
}
// in JS settings, timeZone='local'
+ dayCellClass: (data) => clsx(data.getDay() === 0 && 'my-cell-sun'),
// in JS settings, timeZone='UTC'
+ dayCellClass: (data) => clsx(data.getUTCDay() === 0 && 'my-cell-sun'), For other days of week, modify the above example:
.fc-daygrid-day.fc-day-mon- change the=== 0to=== 1.fc-daygrid-day.fc-day-tue- change the=== 0to=== 2.fc-daygrid-day.fc-day-wed- change the=== 0to=== 3.fc-daygrid-day.fc-day-thu- change the=== 0to=== 4.fc-daygrid-day.fc-day-fri- change the=== 0to=== 5.fc-daygrid-day.fc-day-sat- change the=== 0to=== 6
Day top sub-element. Contains the day-number:
- .fc-daygrid-day-top {
+ .my-day-top {
/* custom css */
}
// in JS
+ dayCellTopClass: 'my-day-top' Day-number:
- .fc-daygrid-day-number {
+ .my-day-number {
/* custom css */
}
// in JS
+ dayCellTopInnerClass: (data) => clsx((data.text === data.dayNumberText) && 'my-day-number') Month text within the day cell:
- .fc-daygrid-month-start {
+ .my-month-start {
/* custom css */
}
// in JS
+ dayCellTopInnerClass: (data) => clsx((data.text !== data.dayNumberText) && 'my-month-start') Events within the day cell:
- .fc-daygrid-day-events {
+ .my-day-events {
background: yellow;
}
// in JS
+ dayCellInnerClass: 'my-day-events' But adding space to the top/bottom requires a different technique:
- .fc-daygrid-day-events {
- margin-top: 10px;
- margin-bottom: 20px;
- }
+ .my-day-top {
+ min-height: 10px;
+ }
+ .my-day-bottom {
+ min-height: 20px;
+ }
// in JS settings
+ dayCellTopClass: 'my-day-top',
+ dayCellBottomClass: 'my-day-bottom', Day bottom sub-element. Contains the more-link:
- .fc-daygrid-day-bottom {
+ .my-day-bottom {
/* custom css */
}
// in JS
+ dayCellBottomClass: 'my-day-bottom' DayGrid More-Link
- .fc-daygrid-more-link {
+ .my-more-link {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: { rowMoreLinkClass: 'my-more-link' },
+ timeGrid: { rowMoreLinkClass: 'my-more-link' },
+ } DayGrid Week Number
- .fc-daygrid-week-number {
+ .my-daygrid-week-number {
/* custom CSS */
}
// in JS settings
+ inlineWeekNumberClass: 'my-daygrid-week-number' DayGrid Events
- .fc-daygrid-event {
+ .my-daygrid-event {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: { eventClass: 'my-daygrid-event' },
+ timeGrid: { rowEventClass: 'my-daygrid-event' },
+ } The solid-looking all-day or multi-day events:
- .fc-daygrid-block-event {
+ .my-row-event {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: { rowEventClass: 'my-row-event' },
+ timeGrid: { rowEventClass: 'my-row-event' },
+ } Timed events that are usually prefixed with a bullet-point:
- .fc-daygrid-dot-event {
+ .my-daygrid-list-event {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: { listItemEventClass: 'my-daygrid-list-event' },
+ } The bullet-point’s width (for Classic Theme only):
:root {
- --fc-daygrid-event-dot-width: 10px;
+ --fc-classic-small-dot-width: 10px;
} The bullet-point’s custom CSS:
- .fc-daygrid-event-dot {
+ .my-event-dot {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: { listItemEventBeforeClass: 'my-event-dot' },
+ } When the event segment represents the event’s start:
- .fc-daygrid-event.fc-event-start {
+ .my-daygrid-event-start {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ eventClass: (data) => clsx(data.isStart && 'my-daygrid-event-start')
+ },
+ timeGrid: {
+ rowEventClass: (data) => clsx(data.isStart && 'my-daygrid-event-start')
+ },
+ } When the event segment represents the event’s end:
- .fc-daygrid-event.fc-event-end {
+ .my-daygrid-event-end {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ eventClass: (data) => clsx(data.isEnd && 'my-daygrid-event-end')
+ },
+ timeGrid: {
+ rowEventClass: (data) => clsx(data.isEnd && 'my-daygrid-event-end')
+ },
+ } Future event:
- .fc-daygrid-event.fc-event-future {
+ .my-daygrid-event-future {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ eventClass: (data) => clsx(data.isFuture && 'my-daygrid-event-future')
+ },
+ timeGrid: {
+ rowEventClass: (data) => clsx(data.isFuture && 'my-daygrid-event-future')
+ },
+ } Past event:
- .fc-daygrid-event.fc-event-past {
+ .my-daygrid-event-past {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ eventClass: (data) => clsx(data.isPast && 'my-daygrid-event-past')
+ },
+ timeGrid: {
+ rowEventClass: (data) => clsx(data.isPast && 'my-daygrid-event-past')
+ },
+ } Event occuring today:
- .fc-daygrid-event.fc-event-today {
+ .my-daygrid-event-today {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ eventClass: (data) => clsx(data.isToday && 'my-daygrid-event-today')
+ },
+ timeGrid: {
+ rowEventClass: (data) => clsx(data.isToday && 'my-daygrid-event-today')
+ },
+ } Selected state:
- .fc-daygrid-event.fc-event-selected {
+ .my-daygrid-event-selected {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ eventClass: (data) => clsx(data.isSelected && 'my-daygrid-event-selected')
+ },
+ timeGrid: {
+ rowEventClass: (data) => clsx(data.isSelected && 'my-daygrid-event-selected')
+ },
+ } Draggable state:
- .fc-daygrid-event.fc-event-draggable {
+ .my-daygrid-event-draggable {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ eventClass: (data) => clsx(data.isDraggable && 'my-daygrid-event-draggable')
+ },
+ timeGrid: {
+ rowEventClass: (data) => clsx(data.isDraggable && 'my-daygrid-event-draggable')
+ },
+ } Dragging state:
- .fc-daygrid-event.fc-event-dragging {
+ .my-daygrid-event-dragging {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ eventClass: (data) => clsx(data.isDragging && 'my-daygrid-event-dragging')
+ },
+ timeGrid: {
+ rowEventClass: (data) => clsx(data.isDragging && 'my-daygrid-event-dragging')
+ },
+ } Event “mirror” that appears during dragging/resize:
- .fc-daygrid-event.fc-event-mirror {
+ .my-daygrid-event-mirror {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ eventClass: (data) => clsx(data.isMirror && 'my-daygrid-event-mirror')
+ },
+ timeGrid: {
+ rowEventClass: (data) => clsx(data.isMirror && 'my-daygrid-event-mirror')
+ },
+ } Resizable state:
- .fc-daygrid-event.fc-event-resizable {
+ .my-daygrid-event-resizable {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ rowEventClass: (data) => clsx((data.isStartResizable || data.isEndResizable) && 'my-daygrid-event-resizable')
+ },
+ timeGrid: {
+ rowEventClass: (data) => clsx((data.isStartResizable || data.isEndResizable) && 'my-daygrid-event-resizable')
+ },
+ } Resizing state:
- .fc-daygrid-event.fc-event-resizing {
+ .my-daygrid-event-resizing {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ rowEventClass: (data) => clsx(data.isResizing && 'my-daygrid-event-resizing')
+ },
+ timeGrid: {
+ rowEventClass: (data) => clsx(data.isResizing && 'my-daygrid-event-resizing')
+ },
+ } The resizer sub-element:
- .fc-daygrid-event .fc-event-resizer {
+ .my-daygrid-event-resizer {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-daygrid-event-resizer'),
+ rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-daygrid-event-resizer'),
+ },
+ timeGrid: {
+ rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-daygrid-event-resizer'),
+ rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-daygrid-event-resizer'),
+ },
+ } The start-resizer sub-element:
- .fc-daygrid-event .fc-event-resizer-start {
+ .my-daygrid-event-resizer-start {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-daygrid-event-resizer-start')
+ },
+ timeGrid: {
+ rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-daygrid-event-resizer-start')
+ },
+ } The end-resizer sub-element:
- .fc-daygrid-event .fc-event-resizer-end {
+ .my-daygrid-event-resizer-end {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-daygrid-event-resizer-end')
+ },
+ timeGrid: {
+ rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-daygrid-event-resizer-end')
+ },
+ } The inner-element that wraps the time and title:
- .fc-daygrid-event .fc-event-main {
+ .my-daygrid-event-main {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ eventClass: 'my-daygrid-event-main'
+ },
+ timeGrid: {
+ rowEventInnerClass: 'my-daygrid-event-main'
+ },
+ } Time sub-element:
- .fc-daygrid-event .fc-event-time {
+ .my-daygrid-event-time {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ eventClass: 'my-daygrid-event-time'
+ },
+ timeGrid: {
+ rowEventTimeClass: 'my-daygrid-event-time'
+ },
+ } Title sub-element:
- .fc-daygrid-event .fc-event-title {
+ .my-daygrid-event-title {
/* custom css */
}
// in JS
+ views: {
+ dayGrid: {
+ eventClass: 'my-daygrid-event-title'
+ },
+ timeGrid: {
+ rowEventTitleClass: 'my-daygrid-event-title'
+ },
+ } No Replacement
- .fc-daygrid-event-harness {}
- .fc-daygrid-event-harness-abs {}
- .fc-daygrid-bg-harness {}
- .fc-daygrid-body {}
- .fc-daygrid-body-balanced {}
- .fc-daygrid-body-natural {}
- .fc-daygrid-body-unbalanced {}
- .fc-daygrid-day-frame {}
- .fc-daygrid-day-bg {} Resource DayGrid View
Day header cell:
- .fc-col-header-cell.fc-resource {
+ .my-resource-header {
/* custom CSS */
}
// in JS settings
+ resourceDayHeaderClass: (data) => 'my-resource-header',
+ dayHeaderClass: (data) => clsx(data.resource && 'my-resource-header'), Day body cell:
- .fc-daygrid-day.fc-resource {
+ .my-resource-cell {
/* custom CSS */
}
// in JS settings
+ dayCellClass: (data) => clsx(data.resource && 'my-resource-cell') TimeGrid View
Root view element:
- .fc-timegrid {
+ .my-timegrid-view { /* OR .fc-timegrid .fc-scrollgrid */
/* custom CSS */
}
// in JS settings
+ views: {
+ timeGrid: {
+ viewClass: 'my-timegrid-view'
+ }
+ } Table Structure
Table header section:
- .fc-timegrid .fc-scrollgrid-section-header { /* OR .fc-timegrid .fc-col-header */
+ .my-timegrid-header {
/* custom CSS */
}
// in JS settings
+ views: {
+ timeGrid: {
+ tableHeaderClass: 'my-timegrid-header'
+ }
+ } Sticky table header section:
- .fc-timegrid .fc-scrollgrid-section-sticky {
+ .my-timegrid-header-sticky {
/* custom CSS */
}
// in JS settings
+ views: {
+ timeGrid: {
+ tableHeaderClass: (data) => clsx(data.isSticky && 'my-timegrid-header-sticky')
+ }
+ } Table body section:
- .fc-timegrid .fc-scrollgrid-section-body { /* OR .fc-timegrid-body */
+ .my-timegrid-body {
/* custom CSS */
}
// in JS settings
+ views: {
+ timeGrid: {
+ tableBodyClass: 'my-timegrid-body'
+ }
+ } All-Day Divider
The horizontal divider between the all-day area and timed area:
- .fc-timegrid-divider {
+ .my-timegrid-divider {
/* custom CSS */
}
// in JS settings
+ allDayDividerClass: 'my-timegrid-divider', Time Axis
Time-axis cells:
- .fc-timegrid-axis {
+ .my-timegrid-axis {
/* custom CSS */
}
// in JS settings
+ weekNumberHeaderClass: 'my-timegrid-axis',
+ allDayHeaderClass: 'my-timegrid-axis',
+ views: {
+ timeGrid: {
+ slotHeaderClass: 'my-timegrid-axis'
+ }
+ } Inner wrapper within time-axis cells:
- .fc-timegrid-axis-cushion {
+ .my-timegrid-axis-inner {
/* custom CSS */
}
// in JS settings
+ weekNumberHeaderInnerClass: 'my-timegrid-axis-inner',
+ allDayHeaderInnerClass: 'my-timegrid-axis-inner',
+ views: {
+ timeGrid: {
+ slotHeaderInnerClass: 'my-timegrid-axis-inner'
+ }
+ } Time Slots
Targeting both axis and lane:
- .fc-timegrid-slot {
+ .my-timegrid-slot {
/* custom CSS */
}
// in JS settings
+ views: {
+ timeGrid: {
+ slotHeaderClass: 'my-timegrid-slot',
+ slotLaneClass: 'my-timegrid-slot',
+ }
+ } Minor dotted slot (both axis and lane):
- .fc-timegrid-slot-minor {
+ .my-timegrid-slot-minor {
/* custom CSS */
}
// in JS settings
+ views: {
+ timeGrid: {
+ slotHeaderClass: (data) => clsx(data.isMinor && 'my-timegrid-slot-minor'),
+ slotLaneClass: (data) => clsx(data.isMinor && 'my-timegrid-slot-minor'),
+ }
+ } Slot axis (aka “header”):
- .fc-timegrid-slot-label {
+ .my-timegrid-slot-header {
/* custom CSS */
}
// in JS settings
+ views: {
+ timeGrid: {
+ slotHeaderClass: 'my-timegrid-slot-header',
+ }
+ } Slot axis inner wrapper:
- .fc-timegrid-slot-label-cushion {
+ .my-timegrid-slot-header-inner {
/* custom CSS */
}
// in JS settings
+ views: {
+ timeGrid: {
+ slotHeaderInnerClass: 'my-timegrid-slot-header-inner',
+ }
+ } Slot lane:
- .fc-timegrid-slot-lane {
+ .my-timegrid-slot-lane {
/* custom CSS */
}
// in JS settings
+ views: {
+ timeGrid: {
+ slotLaneClass: 'my-timegrid-slot-lane'
+ }
+ } Day Lane
In the timed area, day element that spans top-to-bottom:
- .fc-timegrid-col {
+ .my-lane {
/* custom CSS */
}
// in JS settings
+ dayLaneClass: 'my-lane', In future:
- .fc-timegrid-col.fc-day-future {
+ .my-lane-future {
/* custom css */
}
// in JS settings
+ dayLaneClass: (data) => clsx(data.isFuture && 'my-lane-future'), In past:
- .fc-timegrid-col.fc-day-past {
+ .my-lane-past {
/* custom css */
}
// in JS settings
+ dayLaneClass: (data) => clsx(data.isPast && 'my-lane-past'), Today:
- .fc-timegrid-col.fc-day-today {
+ .my-lane-today {
/* custom css */
}
// in JS settings
+ dayLaneClass: (data) => clsx(data.isToday && 'my-lane-today'), Other month:
- .fc-timegrid-col.fc-day-other {
+ .my-lane-other {
/* custom css */
}
// in JS settings
+ dayLaneClass: (data) => clsx(data.isOther && 'my-lane-other'), Day-of-week:
- .fc-timegrid-col.fc-day-sun {
+ .my-lane-sun {
/* custom CSS */
}
// in JS settings, timeZone='local'
+ dayLaneClass: (data) => clsx(data.getDay() === 0 && 'my-lane-sun'),
// in JS settings, timeZone='UTC'
+ dayLaneClass: (data) => clsx(data.getUTCDay() === 0 && 'my-lane-sun'), For other days of week, modify the above example:
.fc-timegrid-col.fc-day-mon- change the=== 0to=== 1.fc-timegrid-col.fc-day-tue- change the=== 0to=== 2.fc-timegrid-col.fc-day-wed- change the=== 0to=== 3.fc-timegrid-col.fc-day-thu- change the=== 0to=== 4.fc-timegrid-col.fc-day-fri- change the=== 0to=== 5.fc-timegrid-col.fc-day-sat- change the=== 0to=== 6
Lane inner-wrapper:
- .fc-timegrid-col-events {
+ .my-day-lane-inner {
/* custom CSS */
}
/* would wrap custom injected content (no longer possible) */
- .fc-timegrid-col-misc {}
// in JS settings
+ dayLaneInnerClass: 'my-day-lane-inner', Now-Indicator
Arrow:
- .fc-timegrid-now-indicator-arrow {
+ .my-timegrid-now-indicator-header {
/* custom CSS */
}
// in JS settings
+ views: {
+ timeGrid: {
+ nowIndicatorHeaderClass: 'my-timegrid-now-indicator-header'
+ }
+ } Line:
- .fc-timegrid-now-indicator-line {
+ .my-timegrid-now-indicator-line {
/* custom CSS */
}
// in JS settings
+ views: {
+ timeGrid: {
+ nowIndicatorLineClass: 'my-timegrid-now-indicator-line'
+ }
+ } More-Link
- .fc-timegrid-more-link {
+ .my-timegrid-more-link {
/* custom CSS */
}
// in JS settings
+ views: {
+ timeGrid: {
+ columnMoreLinkClass: 'my-timegrid-more-link'
+ }
+ } The inner-wrapper:
- .fc-timegrid-more-link-inner {
+ .my-timegrid-more-link-inner {
/* custom CSS */
}
// in JS settings
+ views: {
+ timeGrid: {
+ columnMoreLinkInnerClass: 'my-timegrid-more-link-inner'
+ }
+ } Events
- .fc-timegrid-event { /* OR .fc-v-event */
+ .my-timegrid-event {
/* custom css */
}
// in JS
+ columnEventClass: 'my-timegrid-event' Short event:
- .fc-timegrid-event-short {
+ .my-timegrid-event-short {
/* custom css */
}
// in JS
+ columnEventClass: (data) => clsx(data.isShort && 'my-timegrid-event-short') When the event segment represents the event’s start:
- .fc-timegrid-event.fc-event-start { /* OR .fc-v-event.fc-event-start */
+ .my-timegrid-event-start {
/* custom css */
}
// in JS
+ columnEventClass: (data) => clsx(data.isStart && 'my-timegrid-event-start') When the event segment represents the event’s end:
- .fc-timegrid-event.fc-event-end { /* OR .fc-v-event.fc-event-end */
+ .my-timegrid-event-end {
/* custom css */
}
// in JS
+ columnEventClass: (data) => clsx(data.isEnd && 'my-timegrid-event-end') Future event:
- .fc-timegrid-event.fc-event-future { /* OR .fc-v-event.fc-event-future */
+ .my-timegrid-event-future {
/* custom css */
}
// in JS
+ columnEventClass: (data) => clsx(data.isFuture && 'my-timegrid-event-future') Past event:
- .fc-timegrid-event.fc-event-past { /* OR .fc-v-event.fc-event-past */
+ .my-timegrid-event-past {
/* custom css */
}
// in JS
+ columnEventClass: (data) => clsx(data.isPast && 'my-timegrid-event-past') Event occurring today:
- .fc-timegrid-event.fc-event-today { /* OR .fc-v-event.fc-event-today */
+ .my-timegrid-event-today {
/* custom css */
}
// in JS
+ columnEventClass: (data) => clsx(data.isToday && 'my-timegrid-event-today') Selected state:
- .fc-timegrid-event.fc-event-selected { /* OR .fc-v-event.fc-event-selected */
+ .my-timegrid-event-selected {
/* custom css */
}
// in JS
+ columnEventClass: (data) => clsx(data.isSelected && 'my-timegrid-event-selected') Draggable state:
- .fc-timegrid-event.fc-event-draggable { /* OR .fc-v-event.fc-event-draggable */
+ .my-timegrid-event-draggable {
/* custom css */
}
// in JS
+ columnEventClass: (data) => clsx(data.isDraggable && 'my-timegrid-event-draggable') Dragging state:
- .fc-timegrid-event.fc-event-dragging { /* OR .fc-v-event.fc-event-dragging */
+ .my-timegrid-event-dragging {
/* custom css */
}
// in JS
+ columnEventClass: (data) => clsx(data.isDragging && 'my-timegrid-event-dragging') Event “mirror” that appears during dragging/resize:
- .fc-timegrid-event.fc-event-mirror { /* OR .fc-v-event.fc-event-mirror */
+ .my-timegrid-event-mirror {
/* custom css */
}
// in JS
+ columnEventClass: (data) => clsx(data.isMirror && 'my-timegrid-event-mirror') Resizable state:
- .fc-timegrid-event.fc-event-resizable { /* OR .fc-v-event.fc-event-resizable */
+ .my-timegrid-event-resizable {
/* custom css */
}
// in JS
+ columnEventClass: (data) => clsx(
+ (data.isStartResizable || data.isEndResizable) && 'my-timegrid-event-resizable'
+ ) Resizing state:
- .fc-timegrid-event.fc-event-resizing { /* OR .fc-v-event.fc-event-resizing */
+ .my-timegrid-event-resizing {
/* custom css */
}
// in JS
+ columnEventClass: (data) => clsx(data.isResizing && 'my-timegrid-event-resizing') The resizer sub-element:
- .fc-timegrid-event .fc-event-resizer { /* OR .fc-v-event .fc-event-resizer */
+ .my-timegrid-event-resizer {
/* custom css */
}
// in JS
+ columnEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-timegrid-event-resizer')
+ columnEventAfterClass: (data) => clsx(data.isEndResizable && 'my-timegrid-event-resizer') The start-resizer sub-element:
- .fc-timegrid-event .fc-event-resizer-start { /* OR .fc-v-event .fc-event-resizer-start */
+ .my-timegrid-event-resizer-start {
/* custom css */
}
// in JS
+ columnEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-timegrid-event-resizer-start') The end-resizer sub-element:
- .fc-timegrid-event .fc-event-resizer-end { /* OR .fc-v-event .fc-event-resizer-end */
+ .my-timegrid-event-resizer-end {
/* custom css */
}
// in JS
+ columnEventAfterClass: (data) => clsx(data.isEndResizable && 'my-timegrid-event-resizer-end') The inner-element that wraps the time and title:
- .fc-timegrid-event .fc-event-main { /* OR .fc-v-event .fc-event-main */
+ .my-timegrid-event-main {
/* custom css */
}
// in JS
+ columnEventInnerClass: 'my-timegrid-event-main' Time sub-element:
- .fc-timegrid-event .fc-event-time { /* OR .fc-v-event .fc-event-time */
+ .my-timegrid-event-time {
/* custom css */
}
// in JS
+ columnEventTimeClass: 'my-timegrid-event-time' Title sub-element:
- .fc-timegrid-event .fc-event-title { /* OR .fc-v-event .fc-event-title */
+ .my-timegrid-event-title {
/* custom css */
}
// in JS
+ columnEventTitleClass: 'my-timegrid-event-title' No Replacement
- .fc-timegrid-event-harness {}
- .fc-timegrid-event-harness-inset {}
- .fc-timegrid-axis-frame {}
- .fc-timegrid-axis-frame-liquid {}
- .fc-timegrid-axis-chunk {}
- .fc-timegrid-bg-harness {}
- .fc-timegrid-body {}
- .fc-timegrid-col-bg {}
- .fc-timegrid-col-frame {}
- .fc-timegrid-cols {}
- .fc-timegrid-now-indicator-container {}
- .fc-timegrid-slots {}
- .fc-timegrid-slot-label-frame {} Resource TimeGrid View
- .fc-timegrid-col.fc-resource {
+ .my-resource-lane {
/* custom CSS */
}
// in JS settings
+ dayLaneClass: (data) => clsx(data.resource && 'my-resource-lane') List View
- .fc-list { /* OR .fc-list-table */
+ .my-list-view {
/* custom CSS */
}
// in JS settings
+ views: {
+ list: {
+ viewClass: 'my-list-view'
+ }
+ } List Day-Header
The header that labels a group of events:
- .fc-list-day {
+ .my-list-day-header {
/* custom css */
}
// in JS
+ listDayHeaderClass: 'my-list-day-header' Inner wrapper that applies to both primary and secondary header text:
- .fc-list-day-cushion {
+ .my-list-day-header-inner {
/* custom css */
}
// in JS
+ listDayHeaderInnerClass: 'my-list-day-header-inner' Primary header text element (usually to left):
- .fc-list-day-side-text {
+ .my-list-day-header-inner-primary {
/* custom css */
}
// in JS
+ listDayHeaderInnerClass: (data) => clsx((data.level === 0) && 'my-list-day-header-inner-primary') Secondary header text element (usually to right):
- .fc-list-day-side-text {
+ .my-list-day-header-inner-secondary {
/* custom css */
}
// in JS
+ listDayHeaderInnerClass: (data) => clsx((data.level > 0) && 'my-list-day-header-inner-secondary') Events
- .fc-list-event {
+ .my-list-event {
/* custom css */
}
// in JS
+ views: {
+ list: {
+ listItemEventClass: 'my-list-event'
+ }
+ } When the event segment represents the event’s start:
- .fc-list-event.fc-event-start {
+ .my-list-event-start {
/* custom css */
}
// in JS
+ views: {
+ list: {
+ listItemEventClass: (data) => clsx(data.isStart && 'my-list-event-start')
+ }
+ } When the event segment represents the event’s end:
- .fc-list-event.fc-event-end {
+ .my-list-event-end {
/* custom css */
}
// in JS
+ views: {
+ list: {
+ listItemEventClass: (data) => clsx(data.isEnd && 'my-list-event-end')
+ }
+ } Future event:
- .fc-list-event.fc-event-future {
+ .my-list-event-future {
/* custom css */
}
// in JS
+ views: {
+ list: {
+ listItemEventClass: (data) => clsx(data.isFuture && 'my-list-event-future')
+ }
+ } Past event:
- .fc-list-event.fc-event-past {
+ .my-list-event-past {
/* custom css */
}
// in JS
+ views: {
+ list: {
+ listItemEventClass: (data) => clsx(data.isPast && 'my-list-event-past')
+ }
+ } Event occuring today:
- .fc-list-event.fc-event-today {
+ .my-list-event-today {
/* custom css */
}
// in JS
+ views: {
+ list: {
+ listItemEventClass: (data) => clsx(data.isToday && 'my-list-event-today')
+ }
+ } Bullet-point sub-element’s size (only for Classic Theme):
:root {
- --fc-list-event-dot-width: 8px;
+ --fc-classic-large-dot-width: 8px;
} Bullet-point sub-element custom CSS:
- .fc-list-event-dot {
+ .my-list-event-dot {
/* custom css */
}
// in JS
+ views: {
+ list: {
+ listItemEventBeforeClass: 'my-list-event-dot'
+ }
+ } Time sub-element
- .fc-list-event-time {
+ .my-list-event-time {
/* custom css */
}
// in JS
+ views: {
+ list: {
+ listItemEventTimeClass: 'my-list-event-time'
+ }
+ } Title sub-element:
- .fc-list-event-title {
+ .my-list-event-title {
/* custom css */
}
// in JS
+ views: {
+ list: {
+ listItemEventTitleClass: 'my-list-event-title'
+ }
+ } Event colors (for Classic Theme only):
:root {
- --fc-list-event-hover-bg-color: #f3f4f6;
+ --fc-classic-muted: #f3f4f6; /* now uses a general-purpose neutral color */
} No-events Screen
- .fc-list-empty {
+ .my-no-events {
/* custom css */
}
// in JS
+ noEventsClass: 'my-no-events' Inner wrapper:
- .fc-list-empty-cushion {
+ .my-no-events-inner {
/* custom css */
}
// in JS
+ noEventsInnerClass: 'my-no-events-inner' No Replacement
- .fc-list-sticky {} /* day-headers are always sticky now. TODO: changelog */
- .fc-list-event-graphic {} /* wrapper for dot. style that instead */
- .fc-event-forced-url {} MultiMonth View
View root element:
- .fc-multimonth {
+ .my-multimonth-view {
/* custom CSS */
}
// in JS
+ views: {
+ multiMonth: {
+ viewClass: 'my-multimonth-view'
+ }
+ } View States
No longer put on the view root…
Single-column:
- .fc-multimonth-singlecol .fc-multimonth-month {
+ .my-month-singlecol {
/* custom CSS */
}
- .fc-multimonth-singlecol .fc-multimonth-header {
+ .my-month-header-singlecol {
/* custom CSS */
}
// in JS settings
+ singleMonthClass: (data) => clsx((data.colCount === 1) && 'my-month-singlecol')
+ singleMonthHeaderClass: (data) => clsx((data.colCount === 1) && 'my-month-header-singlecol') Multiple columns:
- .fc-multimonth-multicol .fc-multimonth-month {
+ .my-month-multicol {
/* custom CSS */
}
- .fc-multimonth-multicol .fc-multimonth-header {
+ .my-month-header-multicol {
/* custom CSS */
}
// in JS settings
+ singleMonthClass: (data) => clsx((data.colCount > 1) && 'my-month-multicol')
+ singleMonthHeaderClass: (data) => clsx((data.colCount > 1) && 'my-month-header-multicol') Narrow single-months:
- .fc-multimonth-compact .fc-multimonth-month {
+ .my-month-narrow {
/* custom CSS */
}
- .fc-multimonth-compact .fc-multimonth-header {
+ .my-month-header-narrow {
/* custom CSS */
}
- .fc-multimonth-compact .fc-col-header-cell {
+ .my-day-header-narrow {
/* custom CSS */
}
- .fc-multimonth-compact .fc-daygrid-day {
+ .my-cell-narrow {
/* custom CSS */
}
- .fc-multimonth-compact .fc-h-event {
+ .my-row-event-narrow {
/* custom CSS */
}
// in JS settings
+ singleMonthClass: (data) => clsx(data.isNarrow && 'my-month-narrow')
+ singleMonthHeaderClass: (data) => clsx(data.isNarrow && 'my-month-header-narrow')
+ dayHeaderClass: (data) => clsx(data.isNarrow && 'my-day-header-narrow')
+ dayCellClass: (data) => clsx(data.isNarrow && 'my-cell-narrow')
+ rowEventClass: (data) => clsx(data.isNarrow && 'my-row-event-narrow') Single Month
- .fc-multimonth-month {
+ .my-single-month {
/* custom CSS */
}
// in JS
+ singleMonthClass: 'my-single-month' Single-month header like wraps “January 2025”:
- .fc-multimonth-title {
+ .my-single-month-header {
/* custom CSS */
}
// in JS
+ singleMonthHeaderClass: 'my-single-month-header' Single-month header section for DAY-HEADERS:
- .fc-multimonth-header { /* OR .fc-multimonth-header-table */
+ .my-single-month-table-header {
/* custom CSS */
}
// in JS
+ views: {
+ multiMonth: {
+ tableHeaderClass: 'my-single-month-table-header'
+ }
+ } Single-month body section for DAY-CELLS:
- .fc-multimonth-daygrid { /* OR .fc-multimonth-daygrid-table */
+ .my-single-month-table-body {
/* custom CSS */
}
// in JS
+ views: {
+ multiMonth: {
+ tableBodyClass: 'my-single-month-table-body'
+ }
+ } Timeline View
View root element:
- .fc-timeline { /* OR .fc-timeline .fc-scrollgrid */
+ .my-timeline-view {
/* custom CSS */
}
// in JS
+ views: {
+ timeline: {
+ viewClass: 'my-timeline-view'
+ }
+ } View States
Timeline view with time slots (as opposed to day/week/month slots):
- .fc-timeline-header-row-chrono .fc-timeline-slot-frame {
- justify-content: flex-start;
- }
+ .my-timeline-slot-header-chrono {
+ align-items: flex-start;
+ }
// in JS settings
+ views: {
+ timeline: {
+ slotHeaderClass: (data) => clsx(data.isTime && 'my-timeline-slot-header-chrono')
+ }
+ } Timeline view with overlap enabled:
- .fc-timeline-overlap-enabled .fc-timeline-events { /* event container */
- padding-bottom: 20px; /* creates extra padding under events */
- }
+ .my-timeline-lane-bottom-spacious {
+ min-height: 20px;
+ }
// in JS settings
+ resourceLaneBottomClass: (data) => clsx(data.options.eventOverlap && 'my-timeline-lane-bottom-spacious') Timeline view with overlap disabled:
- .fc-timeline-overlap-disabled .fc-timeline-event {
+ .my-timeline-event-inner-chunky {
padding-top: 10px;
padding-bottom: 10px;
}
// in JS settings
+ views: {
+ timeline: {
+ rowEventInnerClass: (data) => clsx(!data.options.eventOverlap && 'my-timeline-event-inner-chunky')
+ }
+ } Table Structure
Header section:
- .fc-timeline .fc-scrollgrid-section-header {
+ .my-timeline-view-header {
/* custom CSS */
}
// in JS
+ views: {
+ timeline: {
+ tableHeaderClass: 'my-timeline-view-header'
+ }
+ } Sticky header section:
- .fc-timeline .fc-scrollgrid-section-sticky {
+ .my-timeline-header-sticky {
/* custom CSS */
}
// in JS
+ views: {
+ timeline: {
+ tableHeaderClass: (data) => clsx(data.isSticky && 'my-timeline-header-sticky')
+ }
+ } Body section:
- .fc-timeline .fc-scrollgrid-section-body { /* OR .fc-timeline-body */
+ .my-timeline-body {
/* custom CSS */
}
// in JS
+ views: {
+ timeline: {
+ tableBodyClass: 'my-timeline-body'
+ }
+ } Time Slots
Row of slot labels (aka slot headers):
- .fc-timeline-header-row {
+ .my-timeline-header-row {
/* custom CSS */
}
// in JS
+ slotHeaderRowClass: 'my-timeline-header-row' Slot label cell (aka header cell):
- .fc-timeline-slot-label {
+ .my-timeline-slot-header {
/* custom CSS */
}
// in JS
+ views: {
+ timeline: {
+ slotHeaderClass: 'my-timeline-slot-header'
+ }
+ } Slot label cell inner wrapper:
- .fc-timeline-slot-cushion {
+ .my-timeline-slot-header-inner {
/* custom CSS */
}
// in JS
+ views: {
+ timeline: {
+ slotHeaderInnerClass: 'my-timeline-slot-header-inner'
+ }
+ } Targets slot label AND slot lane:
- .fc-timeline-slot {
+ .my-timeline-slot {
/* custom CSS */
}
// in JS
+ views: {
+ timeline: {
+ slotHeaderClass: 'my-timeline-slot',
+ slotLaneClass: 'my-timeline-slot',
+ }
+ } Dotted minor slot (label AND lane):
- .fc-timeline-slot-minor {
+ .my-timeline-slot-minor {
/* custom CSS */
}
// in JS
+ views: {
+ timeline: {
+ slotHeaderClass: (data) => clsx(data.isMinor && 'my-timeline-slot-minor'),
+ slotLaneClass: (data) => clsx(data.isMinor && 'my-timeline-slot-minor'),
+ }
+ } Bolded major slot (label AND lane):
- .fc-timeline-slot-major { /* OR .fc-timeline-slot-em */
+ .my-timeline-slot-major {
/* custom CSS */
}
// in JS
+ views: {
+ timeline: {
+ slotHeaderClass: (data) => clsx(data.isMajor && 'my-timeline-slot-major'),
+ slotLaneClass: (data) => clsx(data.isMajor && 'my-timeline-slot-major'),
+ }
+ } Slot lane:
- .fc-timeline-slot-lane {
+ .my-timeline-slot-lane {
/* custom CSS */
}
// in JS
+ views: {
+ timeline: {
+ slotLaneClass: 'my-timeline-slot-lane'
+ }
+ } Now Indicator
Arrow:
- .fc-timeline-now-indicator-arrow {
+ .my-timeline-now-indicator-header {
/* custom CSS */
}
// in JS
+ views: {
+ timeline: {
+ nowIndicatorHeaderClass: 'my-timeline-now-indicator-header'
+ }
+ } Line:
- .fc-timeline-now-indicator-line {
+ .my-timeline-now-indicator-line {
/* custom CSS */
}
// in JS
+ views: {
+ timeline: {
+ nowIndicatorLineClass: 'my-timeline-now-indicator-line'
+ }
+ } More-Link
More-link root element:
- .fc-timeline-more-link {
+ .my-timeline-more-link {
/* custom CSS */
}
// in JS
+ views: {
+ timeline: {
+ rowMoreLinkClass: 'my-timeline-more-link'
+ }
+ } More-link inner wrapper element:
- .fc-timeline-more-link-inner {
+ .my-timeline-more-link-inner {
/* custom CSS */
}
// in JS
+ views: {
+ timeline: {
+ rowMoreLinkInnerClass: 'my-timeline-more-link-inner'
+ }
+ } Events
Base event:
- .fc-timeline-event {
+ .my-timeline-event {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventClass: 'my-timeline-event'
+ }
+ } When the event segment represents the event’s start:
- .fc-timeline-event.fc-event-start {
+ .my-timeline-event-start {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventClass: (data) => clsx(data.isStart && 'my-timeline-event-start')
+ }
+ } When the event segment represents the event’s end:
- .fc-timeline-event.fc-event-end {
+ .my-timeline-event-end {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventClass: (data) => clsx(data.isEnd && 'my-timeline-event-end')
+ }
+ } Future event:
- .fc-timeline-event.fc-event-future {
+ .my-timeline-event-future {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventClass: (data) => clsx(data.isFuture && 'my-timeline-event-future')
+ }
+ } Past event:
- .fc-timeline-event.fc-event-past {
+ .my-timeline-event-past {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventClass: (data) => clsx(data.isPast && 'my-timeline-event-past')
+ }
+ } Event occuring today:
- .fc-timeline-event.fc-event-today {
+ .my-timeline-event-today {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventClass: (data) => clsx(data.isToday && 'my-timeline-event-today')
+ }
+ } Selected state:
- .fc-timeline-event.fc-event-selected {
+ .my-timeline-event-selected {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventClass: (data) => clsx(data.isSelected && 'my-timeline-event-selected')
+ }
+ } Draggable state:
- .fc-timeline-event.fc-event-draggable {
+ .my-timeline-event-draggable {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventClass: (data) => clsx(data.isDraggable && 'my-timeline-event-draggable')
+ }
+ } Dragging state:
- .fc-timeline-event.fc-event-dragging {
+ .my-timeline-event-dragging {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventClass: (data) => clsx(data.isDragging && 'my-timeline-event-dragging')
+ }
+ } Event “mirror” that appears during dragging/resize:
- .fc-timeline-event.fc-event-mirror {
+ .my-timeline-event-mirror {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventClass: (data) => clsx(data.isMirror && 'my-timeline-event-mirror')
+ }
+ } Resizable state:
- .fc-timeline-event.fc-event-resizable {
+ .my-timeline-event-resizable {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventClass: (data) =>
+ clsx((data.isStartResizable || data.isEndResizable) && 'my-timeline-event-resizable')
+ }
+ } Resizing state:
- .fc-timeline-event.fc-event-resizing {
+ .my-timeline-event-resizing {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventClass: (data) => clsx(data.isResizing && 'my-timeline-event-resizing')
+ }
+ } The resizer sub-element:
- .fc-timeline-event .fc-event-resizer {
+ .my-timeline-event-resizer {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-timeline-event-resizer'),
+ rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-timeline-event-resizer')
+ }
+ } The start-resizer sub-element:
- .fc-timeline-event .fc-event-resizer-start {
+ .my-timeline-event-resizer-start {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventBeforeClass: (data) => clsx(data.isStartResizable && 'my-timeline-event-resizer-start')
+ }
+ } The end-resizer sub-element:
- .fc-timeline-event .fc-event-resizer-end {
+ .my-timeline-event-resizer-end {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventAfterClass: (data) => clsx(data.isEndResizable && 'my-timeline-event-resizer-end')
+ }
+ } Continuation arrow in start-direction:
- .fc-timeline-event:not(.fc-event-start):before {
+ .my-timeline-event-start-contd {
/* custom CSS */
}
// in JS settings
+ views: {
+ timeline: {
+ rowEventBeforeClass: (data) => clsx(!data.isStart && 'my-timeline-event-start-contd')
+ }
+ } Continuation arrow in end-direction:
- .fc-timeline-event:not(.fc-event-end):after {
+ .my-timeline-event-end-contd {
/* custom CSS */
}
// in JS settings
+ views: {
+ timeline: {
+ rowEventAfterClass: (data) => clsx(!data.isEnd && 'my-timeline-event-end-contd')
+ }
+ } The inner-element that wraps the time and title:
- .fc-timeline-event .fc-event-main {
+ .my-timeline-event-main {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventInnerClass: 'my-timeline-event-main'
+ }
+ } Time sub-element:
- .fc-timeline-event .fc-event-time {
+ .my-timeline-event-time {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventTimeClass: 'my-timeline-event-time'
+ }
+ } Title sub-element:
- .fc-timeline-event .fc-event-title {
+ .my-timeline-event-title {
/* custom css */
}
// in JS
+ views: {
+ timeline: {
+ rowEventTitleClass: 'my-timeline-event-title'
+ }
+ } No Replacement
- .fc-timeline-header /* is the header but ONLY for the timeline area */
- .fc-timeline-event-harness
- .fc-timeline-bg
- .fc-timeline-bg-harness
- .fc-timeline-body-expandrows
- .fc-timeline-events /* see top/bottom tho */
- .fc-timeline-slots
- .fc-timeline-lane-frame
- .fc-timeline-lane-misc /* no longer allow injecting content in "inner", but see "top"/"bottom" */
- .fc-timeline-slot-frame
- .fc-timeline-now-indicator-container Resource Timeline View
View root element:
- .fc-resource-timeline {
+ .my-resource-timeline-view {
/* custom CSS */
}
// in JS settings
+ views: {
+ resourceTimeline: {
+ viewClass: 'my-resource-timeline-view'
+ }
+ } Data Grid
Datagrid ANY cell:
- .fc-datagrid-cell {
+ .my-any-cell {
/* custom CSS */
}
// in JS settings
+ resourceColumnHeaderClass: 'my-any-cell',
+ resourceGroupHeaderClass: 'my-any-cell',
+ resourceCellClass: 'my-any-cell', Inner wrapper within ANY datagrid cell:
- .fc-datagrid-cell-cushion {
+ .my-any-cell-inner {
/* custom CSS */
}
// in JS settings
+ resourceColumnHeaderInnerClass: 'my-any-cell-inner',
+ resourceGroupHeaderInnerClass: 'my-any-cell-inner',
+ resourceCellInnerClass: 'my-any-cell-inner', Datagrid header cell:
- .fc-datagrid-header .fc-datagrid-cell {
+ .my-header-cell {
/* custom CSS */
}
// in JS settings
+ resourceColumnHeaderClass: 'my-header-cell', Datagrid header cell that encompasses other header cells beneath:
- .fc-datagrid-cell-super {
+ .my-header-super {
/* custom CSS */
}
// in JS settings
+ resourceColumnHeaderClass: (data) => clsx((data.level > 0) && 'my-header-super') Column resizer in header:
- .fc-datagrid-cell-resizer {
+ .my-resizer {
/* custom CSS */
}
// in JS settings
+ resourceColumnResizerClass: 'my-resizer', Datagrid row-group cell (is a row “header” that lives in the body):
- .fc-datagrid-cell.fc-resource-group {
+ .my-resource-group-header {
/* custom CSS */
}
// in JS settings
+ resourceGroupHeaderClass: 'my-resource-group-header', Datagrid resource-specific cell in body:
- .fc-datagrid-cell.fc-resource {
+ .my-resource-cell {
/* custom CSS */
}
// in JS settings
+ resourceCellClass: 'my-resource-cell', For datagrids with row hierarchy, the space force at the beginning of each row:
- .fc-datagrid-expander-placeholder {
+ .my-resource-indent {
/* custom CSS */
}
// in JS settings
+ resourceIndentClass: 'my-resource-indent', For datagrids with row hierarchy, the expander icon for each row:
- .fc-datagrid-expander { /* OR .fc-datagrid-expander .fc-icon */
+ .my-expander {
/* custom CSS */
}
// in JS settings
+ resourceExpanderClass: 'my-expander' Expander icon in different expanded states:
- .fc-icon-minus-square {
+ .my-expander-expanded {
/* custom CSS */
}
- .fc-icon-plus-square {
+ .my-expander-collapsed {
/* custom CSS */
}
+ resourceExpanderClass: (data) => (
+ data.isExpanded ? 'my-expander-expanded' : 'my-expander-collapsed'
+ ) Divider
Divider between datagrid & timeline area:
- .fc-resource-timeline-divider {
+ .my-resource-column-divider {
/* custom CSS */
}
// in JS settings
+ views: {
+ resourceColumnDividerClass: 'my-resource-column-divider'
+ } Timeline Area
Targets both resource lanes & resource-group lanes:
- .fc-timeline-lane {
+ .my-lane {
/* custom CSS */
}
// in JS settings
+ resourceLaneClass: 'my-lane'
+ resourceGroupLaneClass: 'my-lane' Resource lane:
- .fc-timeline-lane.fc-resource {
+ .my-resource-lane {
/* custom CSS */
}
// in JS settings
+ resourceLaneClass: 'my-resource-lane' Resource group lane:
- .fc-timeline-lane.fc-resource-group {
+ .my-resource-group-lane {
/* custom CSS */
}
// in JS settings
+ resourceGroupLaneClass: 'my-resource-group-lane' No Replacement
- .fc-resource-timeline-flat {} /* see resourceIndentClass */
- .fc-datagrid-header {} /* ONLY above datagrid */
- .fc-datagrid-body {} /* ONLY for datagrid */
- .fc-datagrid-cell-frame {}
- .fc-datagrid-cell-frame-liquid {}
- .fc-datagrid-cell-main {} /* resourceColumnHeaderInnerClass and resourceCellInnerClass */
- .fc-main-col {}