-
Notifications
You must be signed in to change notification settings - Fork 0
Time and date
Flux can supply the current local time and date as CSS properties. We can use them to draw a clock, show a calendar label, or indicate how far through a day, week, month, or year we are.
<section data-flux="flux-time flux-date">
<div class="clock-face">
<span class="hour-hand"></span>
<span class="minute-hand"></span>
<span class="second-hand"></span>
</div>
<p class="today"></p>
</section>These values come from the visitor's device clock and local time zone. They are refreshed once a second and do not make requests to the server. For a server-rendered clock refreshed over HTTP, see Live updates.
data-flux="flux-time" supplies:
| Property | Value |
|---|---|
--flux-time-second |
Whole second, 0–59 |
--flux-time-minute |
Whole minute, 0–59 |
--flux-time-hour |
Hour on a twelve-hour dial, 0–11; midnight and noon are both 0 |
--flux-time-second-scalar |
second / 60: progress through the minute |
--flux-time-minute-scalar |
(minute + second / 60) / 60: progress through the hour |
--flux-time-hour-scalar |
(hour + (minute + second / 60) / 60) / 12: progress through the twelve-hour dial |
The scalars let the minute and hour hands include the smaller units without repeating the arithmetic in each stylesheet. At 3:30, for example, the hour hand is halfway between three and four. Multiply a scalar by 360deg to position a hand.
.clock-face {
position: relative;
width: 16rem;
aspect-ratio: 1;
border: 2px solid currentColor;
border-radius: 50%;
}
.clock-face > span {
position: absolute;
bottom: 50%;
left: calc(50% - 1px);
width: 2px;
background: currentColor;
transform-origin: center bottom;
}
.hour-hand {
height: 25%;
transform: rotate(calc(var(--flux-time-hour-scalar, 0) * 360deg));
}
.minute-hand {
height: 35%;
transform: rotate(calc(var(--flux-time-minute-scalar, 0) * 360deg));
}
.second-hand {
height: 40%;
transform: rotate(calc(var(--flux-time-second-scalar, 0) * 360deg));
}The properties update in one-second steps, rather than providing a continuously sweeping hand. Avoid a simple rotation transition: when a scalar wraps back to zero, that transition could sweep the hand backwards. The basic CSS above uses direct rotation updates. The working example transitions two registered numeric CSS properties: the sine and cosine of the hand angle. CSS uses atan2() to calculate the displayed rotation from those values. The rotation itself has no transition, so crossing six or twelve cannot interpolate through a full turn. A 180ms easing adds a subtle overshoot; reduced-motion preferences disable the transitions.
data-flux="flux-date" supplies:
| Property | Value |
|---|---|
--flux-date-year |
Full Gregorian year, such as 2026 |
--flux-date-month |
Month number, 1–12 |
--flux-date-month-name |
Localised full month name, such as "September"
|
--flux-date-month-name-short |
Localised abbreviated month name, such as "Sept" in British English |
--flux-date-day |
Day of the month, 1–31 |
--flux-date-day-name |
Localised full weekday name, such as "Monday"
|
--flux-date-day-name-short |
Localised abbreviated weekday name, such as "Mon"
|
--flux-date-weekday |
Weekday number, 1 for Monday through 7 for Sunday |
--flux-date-year-scalar |
Progress through the local calendar year |
--flux-date-month-scalar |
Progress through the local calendar month |
--flux-date-week-scalar |
Progress through the week, beginning on Monday at midnight |
--flux-day-scalar |
Progress through the local day, beginning at midnight |
The day-progress property is named --flux-day-scalar, with no date- segment. It belongs to the flux-date source and is included when that source is connected to another element.
Names are quoted CSS strings, ready to use in content. They follow the declaring element's nearest ancestor-or-self lang attribute, falling back to the browser's language when it is absent, empty, or invalid. Abbreviations and punctuation follow the browser's locale data. Calendar numbering remains Gregorian for every language.
<section lang="en-GB" data-flux="flux-date">
<p class="today"></p>
</section>.today::after {
counter-reset: day var(--flux-date-day, 1) year var(--flux-date-year, 2026);
content: var(--flux-date-day-name, "") ", "
counter(day) " " var(--flux-date-month-name, "") " " counter(year);
}The same date properties can be inherited by descendants or copied to a connected region. Changing the source's inherited lang refreshes the names; the destination's language does not translate values that it receives.
Progress is expressed as a number from 0 to 1, with no unit suffix:
- Day progress is the local time of day divided by 24 hours. Noon is 0.5.
- Week progress is the completed days since Monday plus day progress, divided by seven.
- Month progress is the completed days in the month plus day progress, divided by that month's number of days.
- Year progress is the completed days in the year plus day progress, divided by 365 or 366 as appropriate.
Months of different lengths and Gregorian leap-year rules are included. These are wall-clock calendar fractions, rather than elapsed milliseconds between two timestamps. On daylight-saving changes the fractions follow the local clock, so a skipped or repeated hour can make progress jump forwards or backwards. Calendar day counts remain correct across those changes.
As with other Flux numeric properties, values are rounded to four decimal places. A fraction very close to the end of a period may round to 1 before resetting to 0 at its boundary. Milliseconds are not included.
<div data-flux="flux-date">
<div class="day-progress" aria-hidden="true"></div>
</div>.day-progress {
height: 0.5rem;
background: #326c85;
transform: scaleX(var(--flux-day-scalar, 0));
transform-origin: left;
}Time and date work with the usual CSS source connections:
<div data-flux="(flux-time,flux-date@#clock, footer > .calendar)"></div>
<div id="clock"></div>
<footer><div class="calendar"></div></footer>All active time/date bindings share one timer. Each tick is aligned to the next whole second using the device clock, which prevents an accumulating interval error. Updates pass through the existing batched CSS writer; unchanged values do not cause repeated style writes. Name formatters are reused, and names are formatted again only when the local date or language changes.
A source pauses when neither it nor any connected destination is visible. Hidden tabs stop the timer when all sources pause, and removal releases subscriptions. When a source becomes active again it reads the current clock immediately; it does not replay missed seconds. Replacements and connections use the same lifecycle as other CSS properties.
Time and date examples includes an analogue clock, a digital readout, localised date labels, and four progress indicators in a connected region. The clock uses only HTML attributes and CSS after loading Flux.
PHP.GT/Flux is a separately maintained component of PHP.GT/WebEngine.