Bear Blog age widget
A card-style widget that shows how many years, months, and days you've been active on Bear, along with a link to your first post.
It calculates the time straight from a date you set once, so there's nothing to update by hand as time passes.1
Preview
How to use
Add the markup below wherever you want the widget to appear, then add the script and styles. Update the script settings with the date of your first post, its link, and optionally its title.
Markup
<div class="bear-age-widget">
<span class="bear-age-label">My Bear age</span>
<p id="bear-age-sentence">Calculating...</p>
</div>
Script
<script>
(function () {
/* =========================
Settings (edit only this)
========================= */
// Date of your first post (YYYY-MM-DD)
const [startYear, startMonth, startDay] = "2023-02-16".split("-").map(Number);
const startDate = new Date(startYear, startMonth - 1, startDay);
// Link to first post
const firstPostUrl = "https://robertbirming.com/its-alive/";
// Title of your first post (optional — leave empty to show "my first post")
const firstPostTitle = "";
/* =========================
Calculation (don't pet the bear)
========================= */
const now = new Date();
let years = now.getFullYear() - startDate.getFullYear();
let months = now.getMonth() - startDate.getMonth();
let days = now.getDate() - startDate.getDate();
if (days < 0) {
months--;
const lastMonth = new Date(now.getFullYear(), now.getMonth(), 0);
days += lastMonth.getDate();
}
if (months < 0) {
years--;
months += 12;
}
const segments = [];
if (years > 0) {
segments.push(years + (years === 1 ? " year" : " years"));
}
if (months > 0) {
segments.push(months + (months === 1 ? " month" : " months"));
}
// Always show days if nothing else exists
if (days > 0 || segments.length === 0) {
segments.push(days + (days === 1 ? " day" : " days"));
}
let timeString = "";
if (segments.length === 1) {
timeString = segments[0];
} else if (segments.length === 2) {
timeString = segments.join(" and ");
} else {
timeString = segments[0] + ", " + segments[1] + ", and " + segments[2];
}
const container = document.getElementById("bear-age-sentence");
if (!container) return;
const linkText = firstPostTitle ? "\u201C" + firstPostTitle + "\u201D" : "my first post";
container.textContent = "It\u2019s been " + timeString + " since ";
try {
new URL(firstPostUrl);
const link = document.createElement("a");
link.href = firstPostUrl;
link.textContent = linkText;
container.appendChild(link);
} catch {
container.appendChild(document.createTextNode(linkText));
}
container.appendChild(document.createTextNode("."));
})();
</script>
Styles
.bear-age-widget {
position: relative;
max-width: fit-content;
margin-block: 1.5rem;
margin-inline: auto;
padding-block: 1rem;
padding-inline: 1.25rem;
background-color: var(--code-background-color);
border: 1px solid color-mix(in srgb, var(--text-color), transparent 78%);
border-radius: 3px;
}
.bear-age-widget::after {
content: "ʕ•ᴥ•ʔ";
position: absolute;
inset-block-start: 0.8em;
inset-inline-end: 1em;
font-size: 0.9em;
opacity: 0.3;
pointer-events: none;
transition: opacity 0.15s ease;
}
@media (hover: hover) {
.bear-age-widget:hover::after {
opacity: 0.5;
}
}
.bear-age-label {
display: block;
margin-block-end: 0.75em;
font-size: 0.75em;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: color-mix(in srgb, var(--text-color), transparent 45%);
}
#bear-age-sentence {
margin-block: 0;
font-size: calc(var(--font-scale) * 0.9);
line-height: 1.5;
color: var(--text-color);
}
Want more? Check out the full Bear Blog library.
Requires JavaScript, available with Bear Blog subscription.↩