fix: accessibility fixes

This commit is contained in:
saicaca 2023-10-20 11:36:55 +08:00
parent 1ccf80f9a2
commit a15b88bdbd
14 changed files with 31 additions and 44 deletions

View File

@ -69,7 +69,7 @@ function formatTag(tag: string[]) {
<div class="w-[80%] transition text-left text-black/50 dark:text-white/50">{group.posts.length} Articles</div> <div class="w-[80%] transition text-left text-black/50 dark:text-white/50">{group.posts.length} Articles</div>
</div> </div>
{group.posts.map(post => ( {group.posts.map(post => (
<a href={getPostUrlBySlug(post.slug)} class="group"> <a href={getPostUrlBySlug(post.slug)} aria-label={post.data.title} class="group">
<Button light height="40px" class="w-full rounded-lg hover:text-[initial]"> <Button light height="40px" class="w-full rounded-lg hover:text-[initial]">
<div class="flex flex-row justify-start items-center h-full"> <div class="flex flex-row justify-start items-center h-full">
<!-- date --> <!-- date -->

View File

@ -30,15 +30,15 @@ function getLinkName(name: string) {
</Button></a> </Button></a>
<div> <div>
{Object.keys(getConfig().menu).map((key) => { {Object.keys(getConfig().menu).map((key) => {
return <a href={getConfig().menu[key]}><Button light class="font-bold px-5 rounded-lg active:scale-95">{getLinkName(key)}</Button></a> return <a aria-label={getLinkName(key)} href={getConfig().menu[key]}><Button light class="font-bold px-5 rounded-lg active:scale-95">{getLinkName(key)}</Button></a>
})} })}
</div> </div>
<div class="flex"> <div class="flex">
<div> <div>
<Button class="rounded-lg active:scale-90" id="display-settings-switch" iconName="material-symbols:palette-outline" iconSize={20} isIcon light></Button> <Button name="Display Settings" class="rounded-lg active:scale-90" id="display-settings-switch" iconName="material-symbols:palette-outline" iconSize={20} isIcon light></Button>
</div> </div>
<div> <div>
<Button class="rounded-lg flex items-center justify-center active:scale-90" id="scheme-switch" light height="44px" width="44px"> <Button name="Light/Dark Mode" class="rounded-lg flex items-center justify-center active:scale-90" id="scheme-switch" light height="44px" width="44px">
<Icon name="material-symbols:wb-sunny-outline-rounded" size={20} class="absolute opacity-[var(--display-light-icon)]"></Icon> <Icon name="material-symbols:wb-sunny-outline-rounded" size={20} class="absolute opacity-[var(--display-light-icon)]"></Icon>
<Icon name="material-symbols:dark-mode-outline-rounded" size={20} class="absolute opacity-[var(--display-dark-icon)]"></Icon> <Icon name="material-symbols:dark-mode-outline-rounded" size={20} class="absolute opacity-[var(--display-dark-icon)]"></Icon>
</Button> </Button>

View File

@ -34,7 +34,7 @@ const className = Astro.props.class;
{(categories && categories.length > 0) && categories.map(category => <div {(categories && categories.length > 0) && categories.map(category => <div
class="with-divider" class="with-divider"
> >
<a href=`/archive/category/${category}` <a href=`/archive/category/${category}` aria-label=`View all posts in the ${category} category`
class="link transition text-black/50 dark:text-white/50 text-sm font-medium class="link transition text-black/50 dark:text-white/50 text-sm font-medium
hover:text-[var(--primary)] dark:hover:text-[var(--primary)] whitespace-nowrap"> hover:text-[var(--primary)] dark:hover:text-[var(--primary)] whitespace-nowrap">
{category} {category}
@ -54,7 +54,7 @@ const className = Astro.props.class;
{(tags && tags.length > 0) && tags.map(tag => <div {(tags && tags.length > 0) && tags.map(tag => <div
class="with-divider" class="with-divider"
> >
<a href=`/archive/tag/${tag}` <a href=`/archive/tag/${tag}` aria-label=`View all posts with the ${tag} tag`
class="link transition text-black/50 dark:text-white/50 text-sm font-medium class="link transition text-black/50 dark:text-white/50 text-sm font-medium
hover:text-[var(--primary)] dark:hover:text-[var(--primary)] whitespace-nowrap"> hover:text-[var(--primary)] dark:hover:text-[var(--primary)] whitespace-nowrap">
{tag} {tag}

View File

@ -22,10 +22,6 @@ import Button from "./control/Button.astro";
import {i18n} from "../i18n/translation"; import {i18n} from "../i18n/translation";
import I18nKey from "../i18n/i18nKey"; import I18nKey from "../i18n/i18nKey";
// tags = ['Foo', 'Bar', 'Baz', 'Qux', 'Quux'];
// const cover = 'https://saicaca.github.io/vivia-preview/assets/79905307_p0.jpg';
// cover = null;
const hasCover = cover !== undefined && cover !== null && cover !== ''; const hasCover = cover !== undefined && cover !== null && cover !== '';
const coverWidth = "28%"; const coverWidth = "28%";
@ -60,7 +56,7 @@ const { remarkPluginFrontmatter } = await entry.render();
</div> </div>
{hasCover && <a href={url} {hasCover && <a href={url} aria-label={title}
class:list={["group", class:list={["group",
"max-h-[20vh] md:max-h-none mx-4 mt-4 md:mx-0 md:mt-0", "max-h-[20vh] md:max-h-none mx-4 mt-4 md:mx-0 md:mt-0",
"md:w-[var(--coverWidth)] relative md:absolute md:top-3 md:bottom-3 md:right-3 rounded-xl overflow-hidden active:scale-95" "md:w-[var(--coverWidth)] relative md:absolute md:top-3 md:bottom-3 md:right-3 rounded-xl overflow-hidden active:scale-95"
@ -71,14 +67,14 @@ const { remarkPluginFrontmatter } = await entry.render();
class="transition opacity-0 group-hover:opacity-100 text-white text-5xl"> class="transition opacity-0 group-hover:opacity-100 text-white text-5xl">
</Icon> </Icon>
</div> </div>
<ImageBox src={cover} <ImageBox src={cover} alt={entry.data.cover.alt || "Cover Image of the Post"}
class="w-full h-full"> class="w-full h-full">
</ImageBox> </ImageBox>
</a>} </a>}
{!hasCover && {!hasCover &&
<a href={url} class="hidden md:block"> <a href={url} aria-label={title} class="hidden md:block">
<Button width="52px" height="full" class="absolute right-3 top-3 bottom-3 rounded-xl bg-[var(--enter-btn-bg)] hover:bg-[var(--enter-btn-bg-hover)] active:bg-[var(--enter-btn-bg-active)] active:scale-95"> <Button name="Enter the Post" width="52px" height="full" class="absolute right-3 top-3 bottom-3 rounded-xl bg-[var(--enter-btn-bg)] hover:bg-[var(--enter-btn-bg-hover)] active:bg-[var(--enter-btn-bg-active)] active:scale-95">
<Icon name="material-symbols:chevron-right-rounded" <Icon name="material-symbols:chevron-right-rounded"
class="transition text-[var(--primary)] text-4xl mx-auto"> class="transition text-[var(--primary)] text-4xl mx-auto">
</Icon> </Icon>

View File

@ -6,7 +6,7 @@ import Button from "./Button.astro";
<!-- There can't be a filter on parent element, or it will break `fixed` --> <!-- There can't be a filter on parent element, or it will break `fixed` -->
<div class="back-to-top-wrapper hidden lg:block" transition:persist> <div class="back-to-top-wrapper hidden lg:block" transition:persist>
<div id="back-to-top-btn" class="back-to-top-btn hide flex items-center rounded-2xl overflow-hidden transition active:scale-90" onclick="topFunction()"> <div id="back-to-top-btn" class="back-to-top-btn hide flex items-center rounded-2xl overflow-hidden transition active:scale-90" onclick="topFunction()">
<Button card height="60px" width="60px"> <Button name="Back to Top" card height="60px" width="60px">
<Icon name="material-symbols:keyboard-arrow-up-rounded" class="mx-auto"></Icon> <Icon name="material-symbols:keyboard-arrow-up-rounded" class="mx-auto"></Icon>
</Button> </Button>
</div> </div>

View File

@ -1,6 +1,7 @@
--- ---
interface Props { interface Props {
id?: string; id?: string;
name?: string;
isIcon?: boolean; isIcon?: boolean;
iconName?: string; iconName?: string;
width?: string; width?: string;
@ -15,6 +16,7 @@ interface Props {
const props = Astro.props; const props = Astro.props;
const { const {
id, id,
name,
isIcon = false, isIcon = false,
iconName, iconName,
width, width,
@ -31,6 +33,7 @@ import { Icon } from 'astro-icon/components';
<button id={id} <button id={id}
disabled={disabled} disabled={disabled}
aria-label={name}
class:list={[ class:list={[
className, className,
` `

View File

@ -2,10 +2,11 @@
interface Props { interface Props {
badge?: string badge?: string
url?: string url?: string
label?: string
} }
const { badge, url } = Astro.props const { badge, url, name } = Astro.props
--- ---
<a href={url}> <a href={url} aria-label={name}>
<button <button
class:list={` class:list={`
w-full w-full

View File

@ -4,10 +4,11 @@ interface Props {
size?: string; size?: string;
dot?: boolean; dot?: boolean;
href?: string; href?: string;
label?: string;
} }
const { size, dot, href }: Props = Astro.props; const { size, dot, href, label }: Props = Astro.props;
--- ---
<a href={href}> <a href={href} aria-label={label}>
<Button regular height="32px" class="text-[15px] px-3 flex flex-row items-center rounded-lg"> <Button regular height="32px" class="text-[15px] px-3 flex flex-row items-center rounded-lg">
{dot && <div class="h-1 w-1 bg-[var(--btn-content)] dark:bg-[var(--card-bg)] transition rounded-md mr-2"></div>} {dot && <div class="h-1 w-1 bg-[var(--btn-content)] dark:bg-[var(--card-bg)] transition rounded-md mr-2"></div>}
<slot></slot> <slot></slot>

View File

@ -54,7 +54,7 @@ const commonUrl: string = parts.slice(0, -1).join('/') + '/';
--- ---
<div class:list={[className, "flex flex-row gap-3 justify-center"]}> <div class:list={[className, "flex flex-row gap-3 justify-center"]}>
<a href={page.url.prev}> <a href={page.url.prev} aria-label={page.url.prev ? "Previous Page" : null}>
<Button isIcon card iconName="material-symbols:chevron-left-rounded" class:list={["text-[var(--primary)] rounded-lg", {"active:scale-90": page.url.prev != undefined}]} iconSize={28} <Button isIcon card iconName="material-symbols:chevron-left-rounded" class:list={["text-[var(--primary)] rounded-lg", {"active:scale-90": page.url.prev != undefined}]} iconSize={28}
disabled = {page.url.prev == undefined} disabled = {page.url.prev == undefined}
></Button> ></Button>
@ -69,15 +69,15 @@ const commonUrl: string = parts.slice(0, -1).join('/') + '/';
> >
{p} {p}
</div> </div>
return <a href={commonUrl + p}> return <a href={commonUrl + p} aria-label=`Page ${p}`>
<Button card iconName="material-symbols:chevron-left-rounded" class="rounded-lg active:scale-[0.85]" height="44px" width="44px"> <Button card iconName="material-symbols:chevron-left-rounded" class="rounded-lg active:scale-[0.85]" height="44px" width="44px">
{p} {p}
</Button> </Button>
</a> </a>
})} })}
</div> </div>
<a href={page.url.next}> <a href={page.url.next} aria-label={page.url.next ? "Next Page" : null}>
<Button isIcon card iconName="material-symbols:chevron-right-rounded" class:list={["text-[var(--primary)] rounded-lg", {"active:scale-90": page.url.next != undefined}]} iconSize={28} <Button isIcon card name="Next Page" iconName="material-symbols:chevron-right-rounded" class:list={["text-[var(--primary)] rounded-lg", {"active:scale-90": page.url.next != undefined}]} iconSize={28}
disabled = {page.url.next == undefined} disabled = {page.url.next == undefined}
></Button> ></Button>
</a> </a>

View File

@ -13,7 +13,7 @@ const {categories} = Astro.props;
--- ---
<div> <div>
{Object.entries(categories).map(([key, value]) => {Object.entries(categories).map(([key, value]) =>
<ButtonLink url={getCategoryUrl(key)} badge={value.count}>{value.name}</ButtonLink> <ButtonLink url={getCategoryUrl(key)} badge={value.count} label=`View all posts in the ${value.name} category`>{value.name}</ButtonLink>
<div class="ml-2"> <div class="ml-2">
{Object.keys(value.children).length > 0 && <Astro.self categories={value.children}></Astro.self>} {Object.keys(value.children).length > 0 && <Astro.self categories={value.children}></Astro.self>}
</div> </div>

View File

@ -2,7 +2,6 @@
import {getConfig} from "../../utils/config-utils"; import {getConfig} from "../../utils/config-utils";
import {i18n} from "../../i18n/translation"; import {i18n} from "../../i18n/translation";
import I18nKey from "../../i18n/i18nKey"; import I18nKey from "../../i18n/i18nKey";
const hueSet: number[] = [0, 30, 60, 180, 250, 270, 300, 330, 345];
const enableBanner = getConfig().banner.enable; const enableBanner = getConfig().banner.enable;
@ -21,20 +20,8 @@ const enableBanner = getConfig().banner.enable;
{0} {0}
</div> </div>
</div> </div>
<div id="preset-list" class="flex flex-row gap-1 mb-4 hidden">
{hueSet.map((hue) => <div
class="h-7 w-8 rounded-md cursor-pointer
bg-[oklch(0.75_0.14_var(--hue))]
hover:bg-[oklch(0.70_0.12_var(--hue))]
active:bg-[oklch(0.65_0.11_var(--hue))]
"
style=`--hue: ${hue}` data-hue={hue}
>
</div>)}
</div>
<div class="w-full h-6 px-1 bg-[oklch(0.80_0.10_0)] dark:bg-[oklch(0.70_0.10_0)] rounded select-none"> <div class="w-full h-6 px-1 bg-[oklch(0.80_0.10_0)] dark:bg-[oklch(0.70_0.10_0)] rounded select-none">
<input type="range" min="0" max="360" value="0" class="slider" id="colorSlider" step="5" style="width: 100%;"> <input aria-label="Theme Color" type="range" min="0" max="360" value="0" class="slider" id="colorSlider" step="5" style="width: 100%;">
</div> </div>
</div> </div>

View File

@ -12,20 +12,20 @@ const vConf = getConfig();
--- ---
<div class="card-base"> <div class="card-base">
<a href="/about" class="group block relative m-3 overflow-hidden rounded-xl active:scale-95"> <a aria-label="Go to About Page" href="/about" class="group block relative m-3 overflow-hidden rounded-xl active:scale-95">
<div class="absolute transition group-hover:bg-black/30 group-active:bg-black/50 w-full h-full z-50 flex items-center justify-center"> <div class="absolute transition group-hover:bg-black/30 group-active:bg-black/50 w-full h-full z-50 flex items-center justify-center">
<Icon name="material-symbols:person-outline-rounded" <Icon name="material-symbols:person-outline-rounded"
class="transition opacity-0 group-hover:opacity-100 text-white text-6xl"> class="transition opacity-0 group-hover:opacity-100 text-white text-6xl">
</Icon> </Icon>
</div> </div>
<ImageBox src={vConf.profile.avatar} class="mt-1 mx-auto w-[240px] lg:w-full h-full lg:mt-0 "></ImageBox> <ImageBox src={vConf.profile.avatar} alt="Profile Image of the Author" class="mt-1 mx-auto w-[240px] lg:w-full h-full lg:mt-0 "></ImageBox>
</a> </a>
<div class="font-bold text-xl text-center mb-1 dark:text-neutral-50 transition">{vConf.profile.author}</div> <div class="font-bold text-xl text-center mb-1 dark:text-neutral-50 transition">{vConf.profile.author}</div>
<div class="h-1 w-5 bg-[var(--primary)] mx-auto rounded-full mb-3 transition"></div> <div class="h-1 w-5 bg-[var(--primary)] mx-auto rounded-full mb-3 transition"></div>
<div class="text-center text-neutral-400 mb-2 transition">{vConf.profile.subtitle}</div> <div class="text-center text-neutral-400 mb-2 transition">{vConf.profile.subtitle}</div>
<div class="flex gap-2 mx-2 justify-center mb-4"> <div class="flex gap-2 mx-2 justify-center mb-4">
{vConf.profile.links.map(item => {vConf.profile.links.map(item =>
<a href={item.url} target="_blank"> <a aria-label={item.name} href={item.url} target="_blank">
<Button isIcon iconName={item.icon} regular height="40px" class="rounded-lg active:scale-90"></Button> <Button isIcon iconName={item.icon} regular height="40px" class="rounded-lg active:scale-90"></Button>
</a> </a>
)} )}

View File

@ -16,7 +16,7 @@ const isCollapsed = tags.length >= 20;
<WidgetLayout name={i18n(I18nKey.tags)} id="tags" isCollapsed={isCollapsed} collapsedHeight={COLLAPSED_HEIGHT}> <WidgetLayout name={i18n(I18nKey.tags)} id="tags" isCollapsed={isCollapsed} collapsedHeight={COLLAPSED_HEIGHT}>
<div class="flex gap-2 flex-wrap"> <div class="flex gap-2 flex-wrap">
{tags.map(t => ( {tags.map(t => (
<ButtonTag href={`/archive/tag/${t.name}`}> <ButtonTag href={`/archive/tag/${t.name}`} label={`View all posts with the ${t.name} tag`}>
{t.name} {t.name}
</ButtonTag> </ButtonTag>
))} ))}

View File

@ -94,8 +94,7 @@ if (title) {
class:list={{'banner-home': isHomePage, 'banner-else': !isHomePage}} class:list={{'banner-home': isHomePage, 'banner-else': !isHomePage}}
> >
<!-- TODO the transition here is not correct --> <ImageBox id="boxtest" alt="Banner image of the blog" class:list={["object-center object-cover h-full", {"hidden": !viConf.banner.enable}]}
<ImageBox id="boxtest" class:list={["object-center object-cover h-full", {"hidden": !viConf.banner.enable}]}
src={banner} transition:animate="fade" src={banner} transition:animate="fade"
> >
</ImageBox> </ImageBox>