add SmallCaps component and use for title
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
|
||||
export default new Map([
|
||||
["posts/after.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Fafter.mdx&astroContentModuleFlag=true")],
|
||||
["posts/test.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Ftest.mdx&astroContentModuleFlag=true")],
|
||||
["posts/before.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Fbefore.mdx&astroContentModuleFlag=true")]]);
|
||||
["posts/before.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Fbefore.mdx&astroContentModuleFlag=true")],
|
||||
["posts/test.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Ftest.mdx&astroContentModuleFlag=true")]]);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import type { CollectionEntry } from 'astro:content';
|
||||
import { render } from 'astro:content';
|
||||
|
||||
import SmallCaps from '@components/SmallCaps.astro';
|
||||
import Toc from '@components/Toc.vue';
|
||||
import { formatDate } from '@lib/datefmt';
|
||||
|
||||
@@ -39,9 +40,9 @@ article {
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 0.9em;
|
||||
font-size: 0.85em;
|
||||
font-style: italic;
|
||||
margin-top: -0.75rem;
|
||||
margin-top: -1rem;
|
||||
}
|
||||
|
||||
.post {
|
||||
@@ -73,7 +74,9 @@ footer {
|
||||
|
||||
<article class="prose">
|
||||
<header class="title">
|
||||
<h1>{ entry.data.title }</h1>
|
||||
<h1>
|
||||
<SmallCaps text={entry.data.title} upperWeight={500} lowerWeight={800} />
|
||||
</h1>
|
||||
<p class="subtitle">{ formatDate(entry.data.date) }</p>
|
||||
</header>
|
||||
|
||||
|
||||
50
src/components/SmallCaps.astro
Normal file
50
src/components/SmallCaps.astro
Normal file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
// few web fonts have "true" smallcaps, so instead they just take the full-size caps and scale them
|
||||
// down to match the height of lowercase letters. But this leads to an awkward effect where the
|
||||
// scaled-down caps are "lighter" looking than the regular-sized caps, so here we reduce the weight
|
||||
// of just the full-sized caps to compensate.
|
||||
export interface Props {
|
||||
text: string,
|
||||
upperWeight?: number | string,
|
||||
lowerWeight?: number | string,
|
||||
};
|
||||
|
||||
const { text, upperWeight = 'inherit', lowerWeight = 'bolder' } = Astro.props;
|
||||
|
||||
const upperOrDigit = /[A-Z0-9]+/g;
|
||||
let prevIdx = 0;
|
||||
let segments = [];
|
||||
for (const match of text.matchAll(upperOrDigit)) {
|
||||
const lower = text.slice(prevIdx, match.index);
|
||||
// if the first letter of the text is upper, this first segment will be '', so skip it
|
||||
if (lower) {
|
||||
segments.push({type: 'lower', chars: lower})
|
||||
};
|
||||
segments.push({type: 'upper', chars: match[0]})
|
||||
prevIdx = match.index + match[0].length;
|
||||
}
|
||||
const final = text.slice(prevIdx);
|
||||
// if there is a final segment, it wasn't a match, so it must be lowercase
|
||||
if (final) {
|
||||
segments.push({type: 'lower', chars: final})
|
||||
};
|
||||
---
|
||||
|
||||
<span class="small-caps">
|
||||
{ segments.map(s => <span class={s.type}>{ s.chars }</span>) }
|
||||
</span>
|
||||
|
||||
|
||||
<style define:vars={{ upperWeight, lowerWeight }}>
|
||||
.small-caps {
|
||||
font-variant: small-caps;
|
||||
}
|
||||
|
||||
.upper {
|
||||
font-weight: var(--upperWeight);
|
||||
}
|
||||
|
||||
.lower {
|
||||
font-weight: var(--lowerWeight);
|
||||
}
|
||||
</style>
|
||||
@@ -69,7 +69,7 @@ onBeforeUnmount(() => {
|
||||
|
||||
<template>
|
||||
<div id="toc">
|
||||
<h5><span class="initial">C</span>ontents</h5>
|
||||
<h5>C<span class="lower">ontents</span></h5>
|
||||
<ul id="toc-list">
|
||||
<li
|
||||
v-for="heading in headings"
|
||||
@@ -108,7 +108,7 @@ onBeforeUnmount(() => {
|
||||
|
||||
h5 {
|
||||
font-variant: petite-caps;
|
||||
font-weight: 500;
|
||||
font-weight: 350;
|
||||
font-size: var(--content-size);
|
||||
font-family: 'Figtree Variable';
|
||||
color: var(--content-color-faded);
|
||||
@@ -122,12 +122,9 @@ h5 {
|
||||
/* make the border stretch beyond the text just a bit, because I like the effect */
|
||||
padding-right: 1.5rem;
|
||||
|
||||
& .initial {
|
||||
/*
|
||||
Our font doesn't have "proper" smallcaps, but we can fake it by
|
||||
setting the weight separately for the initial (non-small) capital
|
||||
*/
|
||||
font-weight: 350
|
||||
/* SmallCaps is an Astro component so we can't use it here, but we can fake it */
|
||||
& .lower {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user