PostMeta
The author and date byline the default post cards share.
On this page
PostMeta renders a post's byline: the author, a • separator and the date. PostCard and HighlightCard both use it, and you can use it in your own card or post header. Each side can be hidden on its own, and the separator only appears when both show.
import { PostMeta } from '@systhemaui/next'
export default function Demo() {
return (
<PostMeta
className="post-byline"
author="Mira Kovač"
authorAvatar={{ url: '/demo-assets/avatar-1.webp' }}
date="September 14, 2026"
dateTime="2026-09-14T09:00:00.000Z"
showAuthor
showDate
/>
)
}ImportLink to this section
import { PostMeta } from '@systhemaui/next'In a React app without Next.js, import it from @systhemaui/react.
ExamplesLink to this section
From a PostViewLink to this section
postByline(post) returns the author, the formatted date and the ISO dateTime from a PostView, formatted in post.locale (en-US by default):
import { PostMeta, postByline, type PostView } from '@systhemaui/next'
export function Byline({ post }: { post: PostView }) {
const { author, date, dateTime } = postByline(post)
return (
<PostMeta
className="post-byline"
author={author}
authorAvatar={post.author?.avatar}
date={date}
dateTime={dateTime}
showAuthor
showDate
/>
)
}One side onlyLink to this section
showAuthor and showDate are required, so the caller decides what shows. A side with no value (null) is skipped as well, and when neither side renders, PostMeta renders nothing.
import { PostMeta } from '@systhemaui/next'
export default function Demo() {
return (
<div className="flex flex-col items-center gap-4">
<PostMeta
className="post-byline"
author="Jonas Weber"
date={null}
showAuthor
showDate={false}
/>
<PostMeta
className="post-byline"
author={null}
date="September 2, 2026"
dateTime="2026-09-02"
showAuthor={false}
showDate
/>
</div>
)
}Styling each sideLink to this section
className goes on the row, and authorClassName and dateClassName are merged over each side's default classes with tailwind-merge.
<PostMeta
className="post-card-meta"
author="Mira Kovač"
date="September 14, 2026"
showAuthor
showDate
dateClassName="uppercase tracking-wide"
/>PropsLink to this section
| Prop | Type | Default | Description |
|---|---|---|---|
author (required) | string | null | - | |
authorAvatar | AuthorAvatar | null | - | |
date (required) | string | null | - | |
dateTime | string | - | |
showAuthor (required) | boolean | - | |
showDate (required) | boolean | - | |
className (required) | string | - | Root class for the meta row (e.g. post-card-meta/post-highlight-meta). |
authorClassName | string | - | |
dateClassName | string | - |
PostMeta does not format dates. Pass a display string as date and the machine-readable value as dateTime, or use postByline.
HTML and CSSLink to this section
<div class="post-meta text-small flex flex-wrap items-center gap-x-2">
<span class="post-meta-author inline-flex items-center gap-2">
<img class="post-meta-avatar size-6 rounded-full object-cover" src="/media/mira.webp" alt="Mira Kovač" />
Mira Kovač
</span>
<span class="post-meta-separator" aria-hidden="true">•</span>
<time class="post-meta-date" datetime="2026-09-14T09:00:00.000Z">September 14, 2026</time>
</div>The .post-meta* hooks come from the posts CSS layer, which mutes the byline against the current text color.
| Class | Styles |
|---|---|
posts-list | width: 100%;max-width: var(--container-width);margin-inline: auto; |
posts-list-grid | & { display: grid; grid-template-columns: minmax(0, 1fr); column-gap: var(--gap-sm, 1.25rem); row-gap: var(--gap-md, 2.5rem); }& > .post-card { animation-delay: var(--post-card-stagger-delay, 0ms); }& > * > .post-card { animation-delay: var(--post-card-stagger-delay, 0ms); } |
posts-list-row | display: flex;flex-direction: column;row-gap: var(--gap-md, 2.5rem); |
posts-list-grid-2 | @media (width >= 640px) { & { grid-template-columns: repeat(2, minmax(0, 1fr)); } }@media (width >= 640px) { & > :nth-child(2n - 1) { --post-card-stagger-delay: 0ms; } }@media (width >= 640px) { & > :nth-child(2n) { --post-card-stagger-delay: calc(var(--tw-stagger-delay, 120ms) * 1); } } |
posts-list-grid-3 | @media (width >= 640px) { & { grid-template-columns: repeat(2, minmax(0, 1fr)); } }@media (width >= 1192px) { & { grid-template-columns: repeat(3, minmax(0, 1fr)); } }@media (width >= 640px) and (width < 1192px) { & > :nth-child(2n - 1) { --post-card-stagger-delay: 0ms; } }@media (width >= 640px) and (width < 1192px) { & > :nth-child(2n) { --post-card-stagger-delay: calc(var(--tw-stagger-delay, 120ms) * 1); } }+ 3 more rules |
posts-list-grid-4 | @media (width >= 640px) { & { grid-template-columns: repeat(2, minmax(0, 1fr)); } }@media (width >= 1192px) { & { grid-template-columns: repeat(4, minmax(0, 1fr)); } }@media (width >= 640px) and (width < 1192px) { & > :nth-child(2n - 1) { --post-card-stagger-delay: 0ms; } }@media (width >= 640px) and (width < 1192px) { & > :nth-child(2n) { --post-card-stagger-delay: calc(var(--tw-stagger-delay, 120ms) * 1); } }+ 4 more rules |
posts-list-interspace | width: 100%; |
posts-list-empty | color: color-mix(in srgb, currentColor 60%, transparent);text-align: center;padding-block: var(--gap-md, 2.5rem); |
posts-list-actions | display: flex;align-items: center;justify-content: center;gap: var(--gap-sm, 1.25rem); |
posts-list-load-more | &:disabled, .posts-list-load-more[disabled] { opacity: 0.4; cursor: not-allowed; } |
posts-list-pagination | & { display: flex; justify-content: center; align-items: center; gap: var(--gallery-navigation-gap-x, 10px); }+ 13 more rules |
post-card | & { color: var(--color-typography-body); }.posts-list-grid > .post-card { animation-delay: var(--post-card-stagger-delay, 0ms); }.posts-list-grid > * > .post-card { animation-delay: var(--post-card-stagger-delay, 0ms); } |
post-card-label | & { color: color-mix(in srgb, currentColor 60%, transparent); }&.text-label { color: color-mix(in srgb, currentColor 60%, transparent); } |
post-highlight-label | & { color: color-mix(in srgb, currentColor 60%, transparent); }&.text-label { color: color-mix(in srgb, currentColor 60%, transparent); } |
post-type | color: color-mix(in srgb, currentColor 60%, transparent); |
text-label | & { font-family: var(--font-label-font-family); font-size: var(--typography-label-font-size); font-weight: var(--font-label-font-weight); letter-spacing: var(--typography-label-letter-spacing); line-height: var(--typography-label-line-height); text-transform: uppercase; text-decoration: none; font-style: var(--font-label-font-style); }.post-card-label.text-label { color: color-mix(in srgb, currentColor 60%, transparent); }+ 1 more rule |
post-card-title | text-wrap: balance; |
post-card-read-more | color: var(--color-link-text-default, currentColor);font-weight: 600;text-decoration-line: underline; |
post-highlight-read-more | color: var(--color-link-text-default, currentColor);font-weight: 600;text-decoration-line: underline; |
post-card-media-placeholder | width: 100%;height: 100%;background-color: color-mix(in srgb, currentColor 6%, transparent); |
post-card-row | @media (width >= 640px) { & .post-card-body { align-self: start; justify-content: flex-start; } } |
post-card-body | @media (width >= 640px) { .post-card-row .post-card-body { align-self: start; justify-content: flex-start; } } |
post-highlight | position: relative;overflow: hidden;border-radius: var(--card-default-border-radius, 12px); |
highlight-card | position: relative;overflow: hidden;border-radius: var(--card-default-border-radius, 12px); |
post-highlight-scrim | position: absolute;inset: 0;background: linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.35) 35%, rgba(0,0,0,0) 70%);pointer-events: none; |
post-highlight-overlay | position: relative;z-index: 1; |
post-highlight-excerpt | color: color-mix(in srgb, #ffffff 85%, transparent); |
post-meta | display: flex;align-items: center;flex-wrap: wrap;gap: 0.5em;color: color-mix(in srgb, currentColor 60%, transparent); |
post-byline-meta | display: flex;align-items: center;flex-wrap: wrap;gap: 0.5em;color: color-mix(in srgb, currentColor 60%, transparent); |
post-meta-avatar | width: var(--post-byline-avatar-size, 1.75em);height: var(--post-byline-avatar-size, 1.75em);border-radius: 9999px;object-fit: cover;flex-shrink: 0; |
post-meta-separator | opacity: 0.5; |
post-meta-author-role | & { opacity: 0.7; }&::before { content: ", "; } |
archive-filter | display: flex;flex-direction: column;gap: var(--gap-sm, 1.25rem); |
archive-filter-bar | display: flex;flex-wrap: wrap;align-items: center;gap: var(--gap-sm, 1.25rem); |
archive-filter-label | flex: 0 0 auto;color: color-mix(in srgb, currentColor 60%, transparent); |
archive-filter-search | flex: 1 1 16rem;min-width: 0;margin: 0; |
archive-filter-select | flex: 1 1 16rem;min-width: 0;margin: 0; |
archive-filter-chips | display: flex;flex-wrap: wrap;align-items: center;gap: var(--chip-gap, 0.5rem);flex: 1 1 16rem;min-width: 0; |
archive-filter-chip-toggle | cursor: pointer;appearance: none; |
archive-filter-chip-toggle-active | background-color: var(--color-chip-hover-background);border-color: var(--color-chip-hover-border);color: var(--color-chip-hover-text); |
archive-filter-active | display: flex;flex-wrap: wrap;align-items: center;gap: var(--chip-gap, 0.5rem); |
archive-filter-chip | & { appearance: none; cursor: pointer; display: inline-flex; align-items: center; gap: var(--chip-gap); font-size: var(--chip-font-size); line-height: var(--chip-line-height); letter-spacing: calc(var(--chip-letter-spacing, 0) * 1px); padding-inline: var(--chip-padding-x); padding-block: var(--chip-padding-y); border-radius: var(--chip-border-radius); border-style: solid; border-width: var(--chip-border-width); background-color: var(--color-chip-normal-background); border-co…+ 1 more rule |
archive-filter-chip-remove | font-size: 1.2em;line-height: 1;opacity: 0.7; |
post-related-title | margin-bottom: var(--gap-sm, 1.25rem); |
post-single | & .article > :not(section, .figure-w-full, .figure-w-screen, .figure-w-container, a:not([class*="card"]), div:not(.columns, .stack, [class*="card"], [class*="accordion"])) { max-width: var(--post-reading-width, calc(var(--container-width) - (var(--article-padding-x) * 2))); } |
post-share-button-label | font-size: var(--text-small-font-size, 0.875rem);line-height: 1; |
post-share-icon-label | & .post-share-list > a { display: inline-flex; align-items: center; gap: var(--gap-xs, 0.5rem); width: auto; }& .post-share-list > button { display: inline-flex; align-items: center; gap: var(--gap-xs, 0.5rem); width: auto; } |
post-share-list | .post-share-icon-label .post-share-list > a { display: inline-flex; align-items: center; gap: var(--gap-xs, 0.5rem); width: auto; }.post-share-icon-label .post-share-list > button { display: inline-flex; align-items: center; gap: var(--gap-xs, 0.5rem); width: auto; }.post-share-pills .post-share-list > a { display: inline-flex; align-items: center; gap: var(--gap-xs, 0.5rem); width: auto; }+ 3 more rules |
post-share-pills | & .post-share-list > a { display: inline-flex; align-items: center; gap: var(--gap-xs, 0.5rem); width: auto; }& .post-share-list > button { display: inline-flex; align-items: center; gap: var(--gap-xs, 0.5rem); width: auto; }& .post-share-list > a { padding: var(--gap-xs, 0.5rem) var(--gap-sm, 1.25rem); border-radius: 9999px; border: 1px solid var(--color-separator-line, currentColor); }+ 1 more rule |
post-share-sticky-bottom | position: fixed;left: 0;right: 0;bottom: 0;z-index: 40;justify-content: center;background-color: var(--color-foundations-surface-bg);border-top: 1px solid var(--color-separator-line, currentColor);padding-block: var(--gap-sm, 1.25rem); |
post-share-floating-sidebar | @media (width >= 1192px) { & { position: fixed; left: var(--gap-lg, 1.5rem); top: 50%; transform: translateY(-50%); flex-direction: column; align-items: center; z-index: 40; } } |
Next.jsLink to this section
@systhemaui/next re-exports PostMeta from @systhemaui/react unchanged.
AccessibilityLink to this section
- The separator is
aria-hidden, so screen readers hear "Mira Kovač September 14, 2026". - The date is a
<time>element; passdateTimeso it carries a machine-readable value. - The avatar's
altisauthorAvatar.alt, or the author's name when that is empty, so a screen reader hears the name twice when an avatar shows. An emptyaltfalls back to the name too.
Mira Kovač