Skip to main content

Styling

Style your calendar using data attributes, Tailwind CSS, or plain CSS.

Data attributes

The calendar outputs data-* attributes on every element. These give you full control over styling without any shipped CSS.

Day cell attributes

AttributeValuesDescription
data-selected"true"Day is selected
data-today"true"Day is today
data-disabled"true"Day is disabled
data-outside-month"true"Day belongs to adjacent month
data-range-start"true"First day in a range selection
data-range-middle"true"Middle day in a range selection
data-range-end"true"Last day in a range selection
data-focused"true"Day has keyboard focus
data-weekend"true"Day is a weekend

Tailwind CSS

Use attribute selectors to style based on state:

/* Selected day */
[data-selected="true"] {
  @apply bg-primary text-primary-foreground;
}
 
/* Today */
[data-today="true"] {
  @apply bg-accent text-accent-foreground;
}
 
/* Disabled */
[data-disabled="true"] {
  @apply opacity-50 cursor-not-allowed;
}
 
/* Range selection */
[data-range-start="true"] {
  @apply rounded-l-md bg-primary;
}
[data-range-middle="true"] {
  @apply bg-accent;
}
[data-range-end="true"] {
  @apply rounded-r-md bg-primary;
}
 
/* Outside month */
[data-outside-month="true"] {
  @apply text-muted-foreground;
}
 
/* Focus ring */
[data-focused="true"] {
  @apply ring-2 ring-ring;
}
/* Selected day */
[data-selected="true"] {
  @apply bg-primary text-primary-foreground;
}
 
/* Today */
[data-today="true"] {
  @apply bg-accent text-accent-foreground;
}
 
/* Disabled */
[data-disabled="true"] {
  @apply opacity-50 cursor-not-allowed;
}
 
/* Range selection */
[data-range-start="true"] {
  @apply rounded-l-md bg-primary;
}
[data-range-middle="true"] {
  @apply bg-accent;
}
[data-range-end="true"] {
  @apply rounded-r-md bg-primary;
}
 
/* Outside month */
[data-outside-month="true"] {
  @apply text-muted-foreground;
}
 
/* Focus ring */
[data-focused="true"] {
  @apply ring-2 ring-ring;
}

Plain CSS

The same data attributes work with plain CSS:

[data-selected="true"] {
  background: var(--color-primary);
  color: white;
  border-radius: 4px;
}
 
[data-today="true"] {
  border: 2px solid var(--color-primary);
}
 
[data-disabled="true"] {
  opacity: 0.4;
  pointer-events: none;
}
 
[data-outside-month="true"] {
  color: var(--color-muted);
}
[data-selected="true"] {
  background: var(--color-primary);
  color: white;
  border-radius: 4px;
}
 
[data-today="true"] {
  border: 2px solid var(--color-primary);
}
 
[data-disabled="true"] {
  opacity: 0.4;
  pointer-events: none;
}
 
[data-outside-month="true"] {
  color: var(--color-muted);
}

Slot attributes

When using compound components from @gentleduck/primitives/calendar, each component sets a data-slot attribute for targeted styling:

SlotComponent
calendarCalendar.Root
calendar-headerCalendar.Header
calendar-navCalendar.Nav
calendar-nav-buttonCalendar.PrevButton / Calendar.NextButton
calendar-gridCalendar.Grid
calendar-weekdaysCalendar.Weekdays
calendar-weekdayIndividual weekday header cells
calendar-dayCalendar.Day
calendar-month-viewCalendar.MonthView
calendar-year-viewCalendar.YearView
[data-slot="calendar"] {
  /* Root container styles */
}
 
[data-slot="calendar-day"] {
  /* Base day cell styles */
}
[data-slot="calendar"] {
  /* Root container styles */
}
 
[data-slot="calendar-day"] {
  /* Base day cell styles */
}