• Stars
    star
    251
  • Rank 161,862 (Top 4 %)
  • Language Astro
  • License
    MIT License
  • Created over 3 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A set of Accessible, easy to use, Front-end UI Components for Astro.

Accessible Astro Components

A set of Accessible, easy to use, Front-end UI Components for Astro. Most of these components are used in the Accessible Astro Starter and the Accessible Astro Dashboard themes and they provide exemplary use cases for these components. As a bonus, these themes also have their own dedicated components (like keyboard accessible and responsive navigations) and many Design System utility classes, patterns and primitives (such as grids, buttons, lists, spacings, sizes and more).

πŸš€ Live preview

Installation

Run the following command in your project folder to get started:

npm install accessible-astro-components --save-dev

Usage

You can import the different components from the package using the following import statement:

---
import { Accordion, AccordionItem, Card, Modal, ... } from 'accessible-astro-components'
---

Skip to: Accordion, Breadcrumbs, Card, DarkMode, Media, Modal, Notification, Pagination, SkipLinks

Accordion

Accordions are great from grouping big chunks of content into easier to scan headers which the user can expand when he or she wants to read what is associated with that header.

Some (accessibility) features of the Accordion:

  • Navigation the AccordionItems using the ArrowUp and ArrowDown keys
  • Closing an opened AccordionItem using the Escape key
  • Helps identify content to screen reader users with aria-controls, aria-labelledby, aria-expanded
  • Using an unordered list structure to tell screen readers users how many items there are and which they are currently on

Example

---
import { Accordion, AccordionItem } from 'accessible-astro-components'
---
<Accordion>
  <AccordionItem
    header="First Item"
  >
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Architecto quasi nobis optio? Qui in quo accusantium debitis sapiente obcaecati magnam incidunt sit. Molestiae exercitationem quibusdam quod veritatis laboriosam est tenetur. </p>
    <a href="#">Tab to me!</a>
  </AccordionItem>
  <AccordionItem
    header="Second Item"
  >
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Architecto quasi nobis optio? Qui in quo accusantium debitis sapiente obcaecati magnam incidunt sit. Molestiae exercitationem quibusdam quod veritatis laboriosam est tenetur. </p>
  </AccordionItem>

  <!-- ... -->

</Accordion>

Overwriting styles

You can apply your own styles by either setting the individual properties using :global(body .accordion__item) for example, or set up a global style tag and define your styles in there:

<style lang="scss" is:global>
  body .accordion__item {
    button {
      background-color: purple;

      &:hover
      &:focus {
        background-color: peru;
      }
    }

    &.is-active button {
      background-color: peru;
    }
  }
</style>

Breadcrumbs

Breadcrumbs are a great way to help users navigate back to a previous page or section. They are also a great way to help screen reader users understand where they are in the website.

Some (accessibility) features of the Breadcrumbs:

  • Helps identify content to screen reader users with aria-label="Breadcrumbs"
  • Using an unordered list structure to tell screen readers users how many items there are and which they are currently on
  • Using a <nav> element to tell screen readers users that this is a navigation element

Example

---
import { Breadcrumbs, BreadcrumbsItem } from 'accessible-astro-components'
---
<Breadcrumbs>
  <BreadcrumbsItem
    href="/"
    label="Home"
  />
  <BreadcrumbsItem
    href="/blog"
    label="Blog"
  />
  <BreadcrumbsItem
    currentPage={true}
    label="My blog post"
  />
</Breadcrumbs>

Overwriting styles

You can apply your own styles by either setting the individual properties using :global(body .breadcrumbs__item) for example, or set up a global style tag and define your styles in there:

<style lang="scss" is:global>
  body .breadcrumbs__item {
    li::after {
      content: '>';
    }
  }
</style>

Card

Cards are usually used in groups. By wrapping them in an unordered list we provide screen reader users with shortcuts to lists and list items. Screen readers also let the users know how many items there are in a list. In the example below you'll find the structure using an unordered list and display: grid, making sure we leave enough of a gap between Cards on touch devices for people who find they have low accuracy when targeting items, including those with Parkinson's disease and rheumatism. Leaving a bigger gap makes it easier to scroll without accidentally activating a Cards link.

Some (accessibility) features of the Card:

  • The whole Card is made clickable using the <a> ::after pseudo element
  • The user still has access to the context menu when right clicking on the Card
  • The title is an <h3> so it can be used in many contexts (<h2> would be too limiting
  • To maintain readable text within the Card on larger screen sizes, max-width is set to 70ch

Example

---
import { Card } from 'accessible-astro-components'
---
<ul>
  <li>
    <Card
      url="/link-to-my-post"
      img="/assets/post-cover.jpg"
      title="My Awesome Post"
      footer="Tony Stark"
    >
      Lorem ipsum dolor sit amet.
    </Card>
  </li>
  <li>
    <!-- ... -->
  </li>
</ul>
<style lang="scss">
  ul {
    display: grid;
    grid-template-columns: 1fr;
    grid-gap: 4rem;

    @media (min-width: 550px) {
      grid-template-columns: repeat(2, 1fr);
      grid-gap: 2rem;
    }

    @media (min-width: 950px) {
      grid-template-columns: repeat(3, 1fr);
    }
  }
</style>

Overwriting styles

You can apply your own styles by either setting the individual properties using :global(body .card) for example, or set up a global style tag and define your styles in there:

<style lang="scss" is:global>
  body .card {
    color: purple;
    background-color: blue;

    a {
      color: gold;
    }
  }

  // set your own image height
  .card__image {
    height: 10rem;
  }
</style>

DarkMode

DarkMode is a toggle button component to add and remove a class of .darkmode to the <body> based on the user's preference for either a light or dark color scheme. The user's preference is saved to the localStorage to preserve their choice for future visits.

Some (accessibility) features of the DarkMode:

  • Utilizes aria-pressed to indicate to screen reader users whether the dark scheme is toggled or not
  • Gives feedback to screen reader users which state is toggled using aria-labels
  • Uses aria-hidden to hide the icons for dark and light mode and uses the aria-labelss instead

Example

---
import { DarkMode } from 'accessible-astro-components'
---
<DarkMode />
<style lang="scss">
  body.darkmode {
    // define your dark color scheme
  }
</style>

Media

Media is a very simple component used for <img> tags. It has a default empty alt tag which is required for non-decorative images. Should the image be descriptive, for example when there's no (complementary) text, then you should always write a good descriptive alt tag. The Media component also utilizes the loading="lazy" tag to optimize performance from the browsers side.

Some (accessibility) features of the Media:

  • Sets a default empty alt tag which is always required for non descriptive images.

Example

---
import { Media } from 'accessible-astro-components'
---
<Media
  classes="elevation-300 radius-large"
  src="https://unsplash.com/photos/d0oYF8hm4GI"
  alt="A tiny toy astronaut, sitting on a yellow toy moon"
/>

Modal

Modals are windows that appear on top of the parent screen, usually disabling the use of the parent screen and demanding immediate action from the user. They are pretty intrusive, so use them wisely. Though, they can be handy to confirm (destructive) actions from the user before proceeding. If you only want to communicate a notification, don't use a Modal but use the Notification component (coming soon) instead. Always combine the Modal with some kind of user action, for example, confirming the deletion of an item in an application. Modals are usually triggered by a <button>. By providing the button with an id you can link the button to the Modal, providing necessary functionality for opening the targeted Modal. You can also customize the text of the close Modal action using the closeText prop on the Modal.

Some (accessibility) features of the Modal:

  • Closing Modal with the Escape key
  • Trapping focus inside Modal using Tab and Shift + Tab
  • Linking the trigger element and the Modal using id and aria-labeledby
  • Setting focus back on the element that triggered the Modal after closing the Modal
  • Teleporting the Modal from where you call it to the root of the <body>
  • Exposing closeModal() function to use as a callback in your own JavaScript

Example

---
import { Modal } from 'accessible-astro-components'
---
<button id="modal1-trigger">Modal 1</button>
<button id="modal2-trigger">Modal 2</button>

<Modal
  triggerId="modal1-trigger"
  title="Modal 1"
>
  <p>Why hello, I be the <strong>first</strong> Modal.</p>
</Modal>
<Modal
  triggerId="modal2-trigger"
  title="Modal 2"
  closeText="Cancel"
>
  <p>Ah yes, and I be the <strong>second</strong> Modal.</p>
  <!--
    calls the closeModal function, you can also use this
    as a callback in your own function
  -->
  <button onclick="closeModal()">Confirm action</button>
</Modal>

Overwriting styles

You can apply your own styles by either setting the individual properties using :global(body .modal) for example, or set up a global style tag and define your styles in there:

<style lang="scss" is:global>
  body {
    .modal__inner {
      color: purple;
      background-color: gold;
      border-color: orange;
    }

    .modal__content {
      gap: 1.5rem;
      padding: 1rem;
    }

    .modal__close button {
      background-color: blue;

      &:hover,
      &:focus {
        background-color: green;
      }
    }
  }
</style>

Notification

Notifications are often used to keep the user updated about changing state on a website or application. They can also be used as a general way to display some highlighted information in an article for example. There are two rules of thumb when it comes to Notifications and those are to always add contextual information about the Notification (such as starting with "Tip:", "Info:", "Error:") and when adding a Notification to the DOM in response to a user action, you should always use role="status" and aria-live="polite" to inform screen reader users. To add some extra visuals you can combine the Notification component with Astro Icon.

Some (accessibility) features of the Notification:

  • Use color to identify the type of Notification (info, success, warning, error)
  • Provide contextual feedback besides just color by mentioning what type of Notification is displayed
  • Help identify content to screen reader users with role="status" and aria-live="polite"

Example

---
import { Notification } from 'accessible-astro-components'
---
<Notification
  type="info"
>
  <p><strong>Info:</strong> This is a notification of type info.</p>
</Notification>

<!-- example using Astro Icon -->
<Notification
  type="info"
>
  <Icon pack="ion" name="information-circle-outline" /><p><strong>Info:</strong> This is a notification of type info.</p>
</Notification>

<!-- when added to the DOM after a user interaction -->
<Notification
  type="info"
  role="status"
  aria-live="polite"
>
  <p><strong>Info:</strong> This is a notification of type info.</p>
</Notification>

Overwriting styles

You can apply your own styles by either setting the individual properties using :global(body .notification) for example, or set up a global style tag and define your styles in there:

<style lang="scss" is:global>
  body {
    .notification {
      color: var(--neutral-900, #202427);
      background-color: var(--neutral-200, #f6f8f9);
      border: 2px solid var(--neutral-600, #858d93);

      &.type-info {
        color: var(--info-900, #035486);
        background-color: var(--info-100, #e0f7ff);
        border-color: var(--info-600, #1a91d1);
      }

      &.type-success {
        color: var(--success-900, #014b3e);
        background-color: var(--success-100, #eefcf6);
        border-color: var(--success-500, #28a980);
      }

      &.type-warning {
        color: var(--warning-900, #8e2a0b);
        background-color: var(--warning-100, #fffbeb);
        border-color: var(--warning-600, #dc901e);
      }

      &.type-error {
        color: var(--error-900, #5e0317);
        background-color: var(--error-100, #ffe0e0);
        border-color: var(--error-500, #df2a39);
      }
    }
  }
</style>

Pagination

A fairly simple yet effective Pagination component which has a first, previous, next, and last page button. It also tells the user how many pages there are and what page they are currently on. The Pagination component is also fully accessible and keyboard navigable.

Some (accessibility) features of the Pagination:

  • Uses aria-labels to tell the user whether they will go to the previous or next page and which page number
  • Uses aria-hidden to hide the icons for the previous and next pages
  • Disables the first and previous page buttons when on the first page
  • Disables the last and next page buttons when on the last page

Example

---
import { Pagination } from 'accessible-astro-components'
---
<Pagination
  firstPage="/1"
  previousPage="/4"
  nextPage="/6"
  lastPage="/10"
  currentPage="/5"
  totalPages="10"
/>

Example using Astro's Dynamic Pages

---
import { Pagination } from 'accessible-astro-components'

export async function getStaticPaths({ paginate }) {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts')
  const data = await response.json()

  return paginate(data, { pageSize: 6 })
}

const { page } = Astro.props
---
<Pagination
  firstPage={page.url.prev ? '/blog' : null}
  previousPage={page.url.prev ? page.url.prev : null}
  nextPage={page.url.next ? page.url.next : null}
  lastPage={page.url.next ? `/blog/${Math.round(page.total / page.size)}` : null}
  currentPage={page.currentPage}
  totalPages={Math.round(page.total / page.size)}
/>

Overwriting styles

You can apply your own styles by either setting the individual properties using :global(body .pagination) for example, or set up a global style tag and define your styles in there:

<style lang="scss" is:global>
  body .pagination a {
    svg path {
      stroke: gold;
    }

    &:hover,
    &:focus-visible {
      background-color: purple;

      svg path {
        stroke: white;
      }
    }

    .disabled {
      border-color: red;
      opacity: 0.1;
    }
  }
</style>

SkipLinks

SkipLinks provide a way for users using assistive technologies to skip repeated content on pages to go directly to the main content of a website or application. To use this component properly, make sure you give the main content of your project an id of #main-content so that the SkipLink can target it. As a fallback the SkipLink will try to target the h1 of the page. If neither are found a warning will be logged to the console.

Some (accessibility) features of the SkipLinks:

  • Lets assistive technologies skip to the main navigation and main content of a website

Example

---
import { SkipLinks } from 'accessible-astro-components'
---
<SkipLinks />

Overwriting styles

You can apply your own styles by either setting the individual properties using :global(body .skiplinks) for example, or set up a global style tag and define your styles in there:

<style lang="scss" is:global>
  body .skiplinks a {
    color: white;
    background-color: purple;

    &:hover
    &:focus {
      background-color: indigo;
    }
  }
</style>

πŸ“¦ Other Accessible Astro projects

❀️ Helping out

If you find that something isn't working right then I'm always happy to hear it to improve these components! You can contribute in many ways and forms. Let me know by either:

  1. Filing an issue
  2. Submitting a pull request
  3. Starting a discussion
  4. Buying me a coffee!

β˜• Thank you!

A big thank you to the creators of Astro and to all using these components and the information to make the web a bit more accessible for all people around the world :) Also a big thanks to creators around the web for providing us with information to build accessible web interfaces, such as Zell Liew from Learn JavaScript Today and Heydon Pickering, the author of Inclusive Components and many more.

buymeacoffee-button

More Repositories

1

accessible-astro-starter

An Accessible Starter Theme for Astro including accessibility features such as landmarks, better focus-outline and skip-links navigation. Ships with Tailwind, Prettier and ESLint support.
Astro
528
star
2

accessible-astro-dashboard

An Accessible Admin Dashboard Theme for Astro with a login page and a dashboard overview. Includes accessibility features such as landmarks, better focus-outline and skip-links navigation.
Astro
106
star
3

frontend-resources

A list of resources concerning front-end web development. From HTML, CSS and JavaScript to testing, accessibility, Atom packages, UI Design and Design Systems.
16
star
4

easybank-landing-page

Frontend Mentor challenge "Easybank Landing Page" using CSS Flexbox and Grid, Accessibility best practices, CSS Animations and the JavaScript IntersectionObserver.
Astro
9
star
5

coding-knowledge-base

My own personal knowledge base for my coding career. It contains all the tools, snippets and frameworks I've learned and acts as a lookup reference. I use Obisian to manage the information. Feel free to use things from this knowledge base for yourself.
7
star
6

accessible-vue-starter

An Accessible Starter Theme for Vue 3 + Vite including accessiblity features such as landmarks, better focus-outline and skip-links navigation.
SCSS
6
star
7

accessible-vue-components

A set of Accessible, easy to use, Front-end UI Components for Vue 3.
Vue
6
star
8

tiny-code-snippets

Collection of Front-end Code Snippets (HTML, (S)CSS, JavaScript) to use as a reverence for common problems and solutions.
CSS
4
star
9

base-css

Responsive front-end HTML and SCSS starter template using a simple Flexbox Grid, basic Design System patterns and ES6 support for writing JavaScript functions. Powered by Gulp.
CSS
4
star
10

accessible-astro-docs

Documentation website for all the availible Accessible Themes and Components for Astro.
SCSS
3
star
11

neon-signs

Neon Sign flickering animated letters using box-shadow, keyframes and JavaScript.
SCSS
3
star
12

frontend-mentor-challenge-starter

A starter project to take on a Frontend Mentor challenge. Build with Astro, with a basic configuration, utility classes and Tailwind CSS. Comes with a GitHub action to automatically deploy the project to GitHub Pages.
SCSS
2
star
13

personal-portfolio-mark

My personal portfollio website, build with Astro in 2023.
Astro
2
star
14

blogr-landing-page

Frontend Mentor challenge Blogr Landing Page using Tailwind CSS, Astro Static Site Generator, a color scheme switcher and the IntersectionObserver.
Astro
2
star
15

accessible-react-word-game

Excersise building a Wordle Game clone using React components and the useState hook. With added personal stretch goals such as making the game accessible, make it more interactive with animations and by adding a DarkMode and Modal component.
JavaScript
2
star
16

flexbox-grid

Flexbox Grid is a simple yet powerful responsive front-end grid based on the Flexbox CSS property. It helps you to quickly build advanced layouts for prototyping and real-life projects.
CSS
1
star
17

mealplanner

Personal mealprep tool for my wife and me to plan out weekly meals, snacks and other healthy goodies.
SCSS
1
star
18

super-mario-brothers-mouse-tracking

A demo where Mario and Luigi SVG's follow your mouse or finger across the screen using the mousemove and touchemove event listeners respectively.
HTML
1
star
19

outer-space

Demo using only CSS Keyframes and Animations and a SCSS function to generate the stars with box-shadow.
SCSS
1
star
20

new-game

Start a new game (project), ideal for building simple HTML, CSS and JavaScript websites. Includes a Flexbox Grid, Breakpoints, Colors, Space Tokens and Size Tokens.
SCSS
1
star
21

markteekman

Personal GitHub profile README.
1
star
22

e-commerce-product-page

Frontend Mentor challenge "E-commerce Product Page" using CSS Flexbox and Grid, Accessibility best practices, CSS Animations, Vue.js and Pinia State Management.
SCSS
1
star
23

nft-preview-card-component

Frontend Mentor challenge "NFT Preview Card Component" using CSS Flexbox and Grid, Accessibility best practices and CSS Animations.
SCSS
1
star
24

rock-paper-scissors-game

Frontend Mentor challenge "Rock, Paper, Scissors Game" using CSS Flexbox and Grid, Accessibility best practices, CSS Animations to make the game more interactive and vanilla JavaScript for the game logic.
Astro
1
star
25

sunnyside-agency-landing-page

Frontend Mentor challenge "Sunnyside Agency Landing Page" using CSS Flexbox and Grid, Accessibility best practices, CSS Animations and the JavaScript IntersectionObserver. Includes a sticky navigation and a revealing footer.
Astro
1
star
26

time-tracking-dashboard

Frontend Mentor challenge "Time Tracking Dashboard" using CSS Grid, CSS Animations, Accessibility best practices and the JavaScript Fetch API to toggle between JSON Data.
SCSS
1
star
27

advice-generator-app

Frontend Mentor challenge "Advice Generator App" using CSS Flexbox and Grid, Accessibility best practices, CSS Animations and the Fetch API for the random advices.
SCSS
1
star
28

drag-drop-mini-game

Small demo of a drag and drop interface using JavaScript's PointerEvents, Node.cloneNode() and getBoundingClientRect().
SCSS
1
star