The Basics of Remix

You’ve probably heard a lot of hype around one of the newest kids on the framework block, Remix. It may be surprising that it got its start back in 2019, but it was originally only available as a subscription-based premium framework. In 2021, the founders raised seed funding and open sourced the framework to let users start using Remix for free. The floodgates opened and everyone seems to be talking about it, good or bad. Let’s dive in and look at some of the basics of Remix.

Remix is a server “edge” first JavaScript framework. It uses React, at least for now, for the front end and prioritizes server-side rendering the application on the edge. Platforms can take the server-side code and run it as serverless or edge functions making it cheaper than a traditional server and putting it closer to your users. The Remix founders like to call it a “center stack” framework because it adapts the requests and responses made between the server and the client for the platform it is being run on.

Deploying Remix

Because Remix requires a server, let’s talk about how you can deploy it. Remix does not provide the server itself — you bring the server — allowing it to be run in any Node.js or Deno environment, including Netlify Edge and DigitalOcean’s App Platform. Remix itself is a compiler, a program that translates the requests for the platform it is running on. This process uses esbuild to create handlers for the requests to the server. The HTTP handlers it uses are built on the Web Fetch API and are ran on the server by adapting them for the platform they will be deployed to.

Remix stacks

Remix stacks are projects that have some common tools that come preconfigured for you. There are three official stacks that are maintained by the Remix team and they are all named after musical genres. There is also a number of community Remix stacks including the K-Pop Stack created by the Templates Team at Netlify. This stack is a powerhouse and includes a Supabase database and authentication, Tailwind for styling, Cypress end-to-end testing, Prettier code formatting, ESLint linting, and TypeScript static typing. Check out Tara Manicsic’s post on deploying the K-Pop Stack.

Caching routes

Even though Remix requires a server, it can still take advantage of the Jamstack benefits by caching routes. A static site or static site generation (SSG) is when all of your content is rendered at build time and stays static until another rebuild. The content is pre-generated and can be put on a CDN. This provides many benefits and speedy site loads for the end user. However, Remix does not do typical SSG like other popular React frameworks, including Next.js and Gatsby. To get the some of the benefits of SSG, you can use the native Cache-Control HTTP header in a Remix headers function to cache a particular route or directly in the root.tsx file.

[[headers]]
  for = "/build/*"
  [headers.values]
    "Cache-Control" = "public, max-age=31536000, s-maxage=31536000"

Then add in your headers function where you want it. This caches for one hour:

export function headers() {
  return {
    "Cache-Control": "public, s-maxage=360",
  };
};

Remixing routing

A lot of frameworks have leaned into routing based on file systems. This is a technique where a designated folder is used to define routes for your application. They typically have special syntax for declaring dynamic routes and endpoints. The biggest difference currently between Remix and other popular frameworks is the ability to use nested routing.

Every Remix app starts with the root.tsx file. This is where the entire base of the app is rendered. You’ll find some of the common HTML layout here like the <html> tag, the <head> tag, and then the <body> tag with the components needed to render the app. The one thing to point out here is the <Scripts> component is what enables JavaScript on the site; some things will work without it, but not everything. The root.tsx file acts as a parent layout for everything inside of the routes directory, everything in routes is rendered where the <Outlet/> component is in root.tsx. This is the base of nested routing in Remix.

Nested routing

Not only was Remix founded by some of the team from React Router, it also uses React Router. In fact, they are bringing some of the good things about Remix back to React Router. A complex problem that the maintainers of Next.js and SvelteKit are trying to solve right now is nested routing.

Nested routing is unlike traditional routing. Where a new route would take a user to a new page, each nested route is a separate section of the same page. It allows for separation of concerns by keeping business logic associated with only the files that need it. Remix is able to handle errors localized to only the section of the page the nested route is at. The other routes on the page are still usable and the route that broke can provide relevant context to the error without the entire page crashing.

Remix does this when a root file in app/routes is named the same as a directory of files that will load inside of the base file. The root file becomes a layout for the files in the directory by using an <Outlet /> component to tell Remix where to load the other routes.

Outlet component

The <Outlet /> Component is a signal to Remix for where it should render content for nested routes. It’s put in the file at the root of the app/routes directory with the same name as the nested routes. The following code goes in a app/routes/about.tsx file and includes the outlet for the files inside app/routes/about folder:

import { Outlet } from "@remix-run/react";

export default function About() {
  return (
    <>
      <section>
        I am the parent layout. I will be on any page inside of my named directory.
      </section>
      { /* All of my children, the files in the named directory, will go here. */ }
      <Outlet />
    </>
  )
}

Folder structure

Any file in the app/routes/ directory becomes a route at the URL of its name. A directory can also be added with an index.tsx file.

app/
├── routes/
│   │
│   └── blog
|   |   ├── index.tsx ## The /blog route
│   └── about.tsx  ## The /about route
│   ├── index.tsx  ## The / or home route
└── root.tsx

If a route has the same name as a directory, the named file becomes a layout file for the files inside the directory and the layout file needs an Outlet component to place the nested route in.

app/
├── routes/
│   │
│   └── about
│   │   ├── index.tsx
│   ├── about.tsx ## this is a layout for /about/index.tsx
│   ├── index.tsx
└── root.tsx

Layouts can also be created by prefixing them with a double underscore (__).

app/
├── routes/
│   │
│   └── about
│   │   ├── index.tsx
│   ├── index.tsx
│   ├── about.tsx
│   ├── __blog.tsx ## this is also a layout
└── root.tsx

https://your-url.com/about will still render the app/routes/about.tsx file, but will also render whatever is in app/routes/about/index.tsx where the Outlet component is in the markup of app/routes/about.tsx.

Dynamic Routes

A dynamic route is a route that changes based on information in the url. That may be a name of a blog post or a customer id, but no matter what it is the $ syntax added to the front of the route signals to Remix that it is dynamic. The name doesn’t matter other than the $ prefix.

app/
├── routes/
│   │
│   └── about
│   │   ├── $id.tsx
│   │   ├── index.tsx
│   ├── about.tsx ## this is a layout for /about/index.tsx
│   ├── index.tsx
└── root.tsx

Fetch that data!

Since Remix renders all of its data on the server, you don’t see a lot of the things that have become the standard of a React app, like useState() and useEffect() hooks, in Remix. There is less need for client-side state since it has already been evaluated on the server.

It also doesn’t matter what type of server you use for fetching data. Since Remix sits between the request and response and translates it appropriately, you can use the standard Web Fetch API. Remix does this in a loader function that only runs on the server and uses the useLoaderData() hook to render the data in the component. Here’s an example using the Cat as a Service API to render a random cat image.

import { Outlet, useLoaderData } from '@remix-run/react'

export async function loader() {
  const response = await fetch('<https://cataas.com/cat?json=true>')
  const data = await response.json()
  return {
    data
  }
}

export default function AboutLayout() {
  const cat = useLoaderData<typeof loader>()
  return (
    <>
      <img
        src={`https://cataas.com/cat/${cat}`}
        alt="A random cat."
      />
      <Outlet />
    </>
  )
}

Route parameters

In dynamic routes, routes prefixed with $ need to be able to access the URL parameter to handle that data that should be rendered. The loader function has access to these through a params argument.

import { useLoaderData } from '@remix-run/react'
import type { LoaderArgs } from '@remix-run/node'

export async function loader({ params }: LoaderArgs) {
  return {
      params
  }
}

export default function AboutLayout() {
  const { params } = useLoaderData<typeof loader>()
  return <p>The url parameter is {params.tag}.</p>
}

Other Remix functions

Remix has a few other helper functions that add extra functionality to normal HTML elements and attributes in the route module API. Each route can define its own of these types of functions.

Action function

An action function allows you to add extra functionality to a form action using the standard web FormData API.

export async function action({ request }) {
  const body = await request.formData();
  const todo = await fakeCreateTodo({
      title: body.get("title"),
  });
  return redirect(`/todos/${todo.id}`);
}

Headers function

Any HTTP standard headers can go in a headers function. Because each route can have a header, to avoid conflicts with nested routes, the deepest route — or the URL with the most forward slashes (/) — wins. You can also get the headers passed through, actionHeaders, loaderHeaders, or parentHeaders

export function headers({
  actionHeaders,
  loaderHeaders,
  parentHeaders,
}) {
  return {
"Cache-Control": loaderHeaders.get("Cache-Control"),
  };
}

Meta function

This function will set the meta tags for the HTML document. One is set in the root.tsx file by default, but they can be updated for each route.

export function meta() {
  return {
    title: "Your page title",
    description: "A new description for each route.",
  };
};

HTML link elements live in the <head> tag of an HTML document and they import CSS, among other things. The links function, not to be confused with the <Link /> component, allows you to only import things in the routes that need them. So, for example, CSS files can be scoped and only imported on the routes that need those specific files. The link elements are returned from a links() function as an array of objects and can either be a HtmlLinkDescriptor from the link API or a PageLinkDescriptor that can prefetch the data for a page.

export function links() {
  return [
    // add a favicon
    {
      rel: "icon",
      href: "/favicon.png",
      type: "image/png",
    },
    // add an external stylesheet
    {
      rel: "stylesheet",
      href: "<https://example.com/some/styles.css>",
      crossOrigin: "true",
    },
    // add a local stylesheet,
    { rel: "stylesheet", href: stylesHref },

    // prefetch a page's data
    { page: "/about/community" }
  ]
}

Linking between routes

Remix provides a component to go between the different routes in your app called <Link/>. To get client-side routing, use the <Link to="">Name</Link> component instead of <a href="">Name</a>. The <Link /> component also takes a prop of prefetch with accepts none by default, intent to prefetch the data if Remix detects the user hovers or focuses the link, or render which will fetch the route’s data as soon as the link is rendered.

import { Link } from "@remix-run/react";

export default function Nav() {
  return (
    <nav>
      <Link to="/">Home</Link>{" "}
      <Link to="/about">About</Link>{" "}
      <Link to="/about/community" prefetch="intent">Community</Link>
    </nav>
  );
}

Next steps

Now you know the basics of Remix and you’re ready to get started actually building applications, right? Remix provides a Jokes app and a Blog tutorial to get you started implementing this basic knowledge. You can also start from scratch and create a brand new Remix app. Or if you are ready to dive in, give the K-Pop Stack a try. I have really enjoyed my time with Remix and love the focus on web standards and bringing it back to the basics. Now it’s your turn to start creating!


The Basics of Remix originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

The Key Distinctions Between JavaScript vs Python

Do you ever think how much technology has taken over our world that we cannot imagine our lives without it? Behind all this, there is a complete world of computers, programming languages, coding, etc.

We spend most of our lives on computers and mobile phones. Watching screens running our commands is not as simple as it seems. The programming languages are not new in technology, but these entities play a critical and tremendous role.

Data Distribution via API — Can a Single Developer Do It?

Data distribution and your data availability strategy are central to any data department. It does not help that an organization's data is centralized and neatly captured, but users have no access to the data. There are many options, and depending on your organization, you might need a combination of options to fulfill all user's needs. 

Some of the options include:

How to Allow Users to Invite Their Friends to Register in WordPress

Would you like for users to invite their friends to become members of your WordPress site?

People trust recommendations from people they know. That makes personal invitations a great way to increase the number of registered users of your social network or membership site.

In this article, we will show you how to allow your users to invite their friends to register in WordPress.

How to Allow Users to Invite Their Friends to Register in WordPress

Why Allow Users to Invite Their Friends?

If you are looking for an easy and cost-effective way to add new users to your membership site or WordPress social network, then allowing your existing users to invite their friends is one of the most effective strategies.

This kind of word-of-mouth advertising works really well because it uses social proof, so it’s very common on almost all popular registration sites.

For example, Twitter users can invite their followers to join a community, and on Facebook, they can invite friends to join a group.

Facebook Allows Users to Invite Friends to a Group

If you make money from your website, such as offering paid memberships or selling products in an online store, then you can also pay your users to promote your website by creating a referral or affiliate program.

With that being said, let’s take a look at how to allow your users to invite their friends to register in WordPress.

This is what we’ll cover in this article:

Method 1: Adding a Simple Invitation Form to Any WordPress Site

The easiest way to allow your users to invite their friends to your website is to add a simple invitation form to your sidebar. However, this method will not allow you to track which invitations were responded to.

What if you need to track invitations? If you have a BuddyPress site, then you should follow Method 2 below. If you have an online store or membership site, then we recommend you create a referral or affiliate program instead.

For the simple invitation form, we’ll use WPForms Lite because it’s free and easy to use. However, the premium version of WPForms will store all form entries in your WordPress dashboard after they are submitted. This will let you more easily see how many invitations have been sent and who they were sent to.

The first thing you need to do is install the Contact Forms by WPForms plugin. For more details, see our step by step guide on how to install a WordPress plugin.

Creating the Invitation Form

Once the plugin is activated, you can create your invitation form by navigating to the WPForms » Add New page. Here you can give your form a name, and then click the ‘Create Blank Form’ button.

Add a New Blank Form in WPForms

This will open the WPForms drag and drop form builder. You will see a preview of the form on the right, and this is currently blank. You’ll also see a list of form fields on the left.

You need to locate the Email form field and drag it onto the form.

Drag an Email Field Onto the Blank Form

Next, you need to configure the Email field.

When you click on the field, its settings will be displayed on the left.

Configure the Email Field

Here you should change the label to ‘Invite Your Friends.’ After that, you can add a description that will be displayed under the field. This should let your users know what to enter, such as, ‘Enter your friend’s email address. Separate multiple email addresses using commas.’

Now you can configure the field so that it’s displayed across the full width of the sidebar. Simply click on the Advanced tab and then select ‘Large’ from the Field Size dropdown menu.

Make the Field Size Large

You’ll find more settings by navigating to Settings » General. For example, you can also change the label on the button to something more helpful.

In the Submit Button Text field, simply type ‘Send Invitation.’

Rename the Button Text

Composing the Invitation Email

Next, you’ll need to head over to Settings » Notifications and set up the invitation email. This will be a confirmation email sent after form submission.

You can use smart tags to automatically fill in the details of the user filling in the form as well as the information they submitted on the form. You’ll find a complete list of smart tags on the WPForms website.

In the ‘Send To Email Address’ field, you need to enter the email address that was submitted in the form. When you click the ‘Show Smart Tags’ link, a list of available fields will be displayed. Simply click on the ‘Invite Your Friends’ field.

Fill in the Email Settings

You should type in the email subject line you wish to use. After that, you can enter the user’s full name in the ‘From Name’ field by entering the smart tag {user_full_name}.

It’s important that you choose the correct ‘From Email’, or your invitations may be sent to the spam folder. Make sure that the domain name used in the email address matches your WordPress blog.

For example, if your website’s URL is www.example.com, then the email address should look like john@example.com.

That means you shouldn’t enter the user’s email address in the ‘From Email’ field. Instead, you can use {admin_email}, which is the default setting. Alternatively, if you are concerned about your admin email receiving spam, then you can use an email address that doesn’t exist, such as no-reply@example.com.

Next, you should scroll down to the ‘Reply-To Email Address.’ Here you can enter the user’s email address using the smart tag {user_email}. Then, if the person who was invited replies to the email, it will be sent to the user who invited them.

Compose Your Invitation Email Using HTML and Smart Fields

Finally, you need to compose the invitation message you wish to send in the ‘Email Message’ field. We recommend you keep it short and casual. You can use smart tags in the message, such as ending the email with the user’s name by entering {user_first_name}.

You will need to add a link to your website. This link could take the invited person to your home page or a user registration page.

Better still, you can link to a landing page that clearly explains the features and benefits of your website.

Creating a Confirmation Message for Form Submission

Now you should navigate to Settings » Confirmations. Here you can compose a brief message that’s displayed to the user after they invite their friends.

You should leave the Confirmation Type as ‘Message’ and then type a brief thank you message in the Confirmation Message field.

Create a Confirmation Message for Form Submission

Now that you have finished the setup of your invitation form, make sure you click the orange Save button at the top of the screen to store the settings. Once you’ve done that, you can click the ‘X’ button to close the WPForms editor.

Adding the Invitation Form to Your WordPress Site

All you need to do now is add the form to your website’s sidebar or another widget-ready area. You’ll need to head over to the Appearance » Widgets page in the WordPress admin area.

Add the Invitation Form to Your Sidebar

Once there, you should locate the WPForms block and drag it onto your sidebar. For more details, see our guide on how to add and use widgets in WordPress.

After that, you need to select the ‘Invite Your Friends’ form from the Select a Form dropdown. Don’t forget to click the Update button to store your settings.

Now you can visit your website to see the simple invitation form in action.

Invitation Form Preview

When a user sends an invitation using the form, the thank you confirmation message is displayed in place of the form.

Confirmation Message Preview

Note: If the invitation emails are not received, then see our guide on how to fix WordPress not sending email.

Method 2: Allowing Users to Invite Friends to Your BuddyPress Site

BuddyPress is a sister project of WordPress.org that turns your WordPress site into a social network, allowing you to build your own online community.

It allows you and your users to create groups, and each group can have its own members and activity streams. Users can join these groups and invite others, but only if they are already members of your site.

If you use BuddyPress and want to let your users send invitations to their friends who haven’t yet signed up, then you’ll need to install the Invite Anyone plugin. For more details, see our step-by-step guide on how to install a WordPress plugin.

Upon activation, you should navigate to Settings » Invite Anyone to configure the plugin. On the ‘General Settings’ tab, you can customize the email message that is sent when someone is invited to register on your site.

Invite Anyone Plugin General Settings

There are plenty of customization options for the email subject, body, and footer. You can also allow your users to customize the email before it is sent, limit the number of emails that can be sent at one time, and more.

If you like, you can also place limits on who can send invitations to your site. For example, you may not want new users to be able to invite their friends right away. This will discourage spammers who want to set up fake accounts.

To set up these limits, you need to click the ‘Access Control’ tab at the top of the page, and then select the ‘A limited set of users’ option.

Invite Anyone Plugin Access Control

Now you will see three checkboxes that let you decide which users can send invitations.

You can limit invitations to users who have been members of your site for a minimum number of days, or to those who have a certain member role. You can also ban specific users from being able to send invitations by typing a list of user IDs separated by commas.

Once you are happy with these settings, you will need to scroll to the bottom of the page and click the ‘Save Changes’ button to store your settings.

Now your users will be able to send invitations to their friends, directly from their own profile page just by clicking the ‘Send Invites’ tab.

Users Can Invite Their Friends From Their Profile Page

After that, they simply type up to five email addresses in the first text box, and if you allow them, they can customize the email message that will be sent.

If the user belongs to any BuddyPress groups, then they can also check any groups they think their friends might be interested in once they join your site.

The Invite New Members Page

Finally, your users need to click the ‘Send Invites’ button at the bottom of the page. After that, the plugin will send the invitations to their friends to register on your website.

Note: If your website is having trouble sending emails from your website, then see our guide on how to fix WordPress not sending email issue.

Once the invitations are sent, the user can see the status of all of their sent invitations.

Users See a List of Invites They Have Sent

They can clear individual invitations from the list by clicking the red ‘X’ button. They can also clear accepted invitations or all invitations by clicking the links at the bottom of the list. These actions will not cancel the invitations, but simply clear them from the list.

As the site administrator, you can keep track of invitations sent by all users by navigating to the BuddyPress Invitations » BuddyPress Invitations page in your WordPress admin area.

You Can See a List of Invitations Sent by All Users

Other Ways to Grow Your Registered Users

Now that your users can invite their friends, let’s have a look at some other ways you can encourage more users to visit your website and sign up.

Luckily, using WordPress gives you access to incredibly powerful tools to grow your business.

  1. OptinMonster is the best lead generation and conversion optimization tool on the market. It allows you to easily increase your email subscribers, create mobile popups, and make a high converting sales funnel.
  2. All in One SEO is the best WordPress SEO plugin. It allows you to optimize your content for search engines without any technical skills.
  3. SeedProd is the best WordPress page builder and theme builder plugin. It lets you easily create a beautiful landing page or custom theme.
  4. WPForms is the best WordPress form builder on the market. Besides creating an invitation form, you can use it to add a custom login page and sign-up form to your site.
  5. MonsterInsights allows you to easily track your website performance using Google Analytics. It shows beginner friendly reports so you can track website visitors and set up eCommerce tracking.

Need more recommendations? See our list of must have WordPress plugins for all websites.

We hope this tutorial helped you learn how to allow users to invite their friends to register on your WordPress website. You may also want to learn how to create an email newsletter the right way, or check out our list of the best GoDaddy alternatives.

If you liked this article, then please subscribe to our YouTube Channel for WordPress video tutorials. You can also find us on Twitter and Facebook.

The post How to Allow Users to Invite Their Friends to Register in WordPress first appeared on WPBeginner.

Making Sense Of WAI-ARIA: A Comprehensive Guide

This article is a sponsored by Fable

The Web Accessibility Initiative — Accessible Rich Internet Applications (WAI-ARIA) is a technical specification that provides direction on how to improve the accessibility of web applications. Where the Web Content Accessibility Guidelines (WCAG) focus more on static web content, WAI-ARIA focuses on making interactions more accessible.

Interactions on the web are notorious for being inaccessible and are often part of the most critical functions such as:

  • submitting a job application,
  • purchasing from an online store, or
  • booking a healthcare appointment.

I’m currently the Head of Accessibility Innovation at Fable, a company that connects organizations to people with disabilities for user research and accessibility testing and provides custom training for digital teams to gain the skills to build inclusive products.

As an instructor for accessible web development, I spend a lot of time examining the source code of websites and web apps and ARIA is one of the things I see developers misusing the most.

HTML

When you use HTML elements like input, select, and button, there are two things you’ll get for accessibility: information about the element is passed to the DOM (Document Object Model) and into an Accessibility Tree. Assistive technologies can access the nodes of the accessibility tree to understand:

  • what kind of element it is by checking its role, e.g., checkbox;
  • what state the element is in, e.g., checked/not checked;
  • the name of the element, e.g., “Sign up for our newsletter.”

The other thing you get when using HTML elements is keyboard interactivity. For example, a checkbox can be focused using the tab key and selected using the spacebar (specific interactions can vary by browser and operating system, but the point is they are available and standardized across all websites when you use HTML elements).

When you don’t use HTML, for example, if you build your own custom select using <div>s and <span>s or you use a component library, you need to do extra work to provide information about the element and build keyboard interactivity for assistive technology users. This is where ARIA comes into play.

ARIA

Accessible Rich Internet Applications (ARIA) include a set of roles and attributes that define ways to make web content and web applications more accessible to people with disabilities.

You can use ARIA to pass information to the accessibility tree. ARIA roles and attributes don’t include any keyboard interactivity. Adding role="button” to a <div> doesn’t make it respond when you press the Enter key — that you have to build using JavaScript or another language. However, the ARIA Authoring Practices Guide does include a list of what keyboard interactivity should be added to various components such as accordions, buttons, carousels, etc.

Roles

Let’s start with roles. What the heck is this thing in the code below?

<div className="dd-wrapper">
  <div className="dd-header">
    <div className="dd-header-title"></div>
  </div>
  <div className="dd-list">
    <button className="dd-list-item"></button>
    <button className="dd-list-item"></button>
    <button className="dd-list-item"></button>
  </div>
</div>

This is actually a snippet of code I found online from a select element for React. The fact that the element is completely unrecognizable from the code is exactly the issue that any assistive technology would have — it can’t tell the user what it is or how to interact with it because there’s no ARIA role.

Watch what we can do here:

<div className="dd-wrapper" role="listbox">

You might not be familiar with a listbox, but it’s a type of select that a screen reader user could recognize and know how to interact with. Now you could just use <select>, and you wouldn’t have to give it a role because it’s already got one that the DOM and accessibility tree will recognize, but I know that’s not always a feasible option.

A role tells an assistive technology user what the thing is, so make sure you use the correct role. A button is very different from a banner. Choose a role that matches the function of the component you’re building.

Another thing you should know about ARIA roles is that they override an HTML element’s inherent role.

<img role="button">

This is no longer an image but a button. There are very few reasons to do this, and unless you exactly knew what you’re doing and why, I’d stay away from overriding existing HTML roles. There are many other ways to achieve this that make more sense from accessibility and a code robustness perspective:

<button><img src="image.png" alt="Print" /></button> 
<input type="image" src="image.png" alt="Print" />
<button style="background: url(image.png)" />Print</button>

If you’re building a component, you can look up the pattern for that component in the ARIA Authoring Practices Guide which includes information on which role(s) to use. You can also look up all available roles in the mdn web docs.

In summary, if you’re building something that doesn’t have a semantic HTML tag that describes it (i.e., anything interactive built using <div> or <span>), it needs to have an ARIA role so that assistive technology can recognize what it is.

States And Properties (Aka ARIA Attributes)

In addition to knowing what an element is, if it has a state (e.g., hidden, disabled, invalid, readonly, selected, and so on) or changes state (e.g., checked/not checked, open/closed, and so on), you need to tell assistive technology users what its current state is and its new state whenever it changes. You can also share certain properties of an element. The difference between states and properties isn’t really clear or important, so let’s just call them attributes.

Here are some of the most common ARIA attributes you might need to use:

  • aria-checked
    It’s used with ="true" or ="false" to indicate if checkboxes and radio buttons are currently checked or not.
  • aria-current
    It’s used with ="true" or ="false" to indicate the current page within breadcrumbs or pagination.
  • aria-describedby
    It’s used with the id of an element to add more information to a form field in addition to its label. aria-describedby can be used to give examples of the required format for a field, for example, a date, or to add an error message to a form field.
<label for="birthday">Birthday</label>
<input type="text" id="birthday" aria-describedby="date-format">
<span id="date-format">MM-DD-YYYY</span>
  • aria-expanded
    It’s used with ="true" or ="false" to indicate if pressing a button will show more content. Examples include accordions and navigation items with submenus.
<button aria-expanded="false">Products</button>

This indicates that the Products menu will open a submenu (for example, of different product categories). If you were to code it like this:

<a href="/products/">Products</a>

You’re setting the expectation that it’s a link, and clicking it will go to a new page. If it’s not going to go to a new page, but it actually stays on the same page but opens a submenu, that’s what button plus aria-expanded says to an assistive technology user. That simple difference between <button> and <a> and the addition of aria-expanded communicates so much about how to interact with elements and what will happen when you do.

  • aria-hidden
    It’s used with ="true" or ="false" to hide something that is visible, but you don’t want assistive technology users to know about it. Use it with extreme caution as there are very few cases where you don’t want equivalent information to be presented.

One interesting use case I’ve seen is a card with both an image and the text title of the card linking to the same page but structured as two separate links. Imagine many of these cards on a page. For a screen reader user, they’d hear every link read out twice. So the image links used aria-hidden="true". The ideal way to solve this is to combine the links into one that has both an image and the text title, but real-life coding isn’t always ideal, and you don’t always have that level of control.

Note that this breaks the fourth rule of ARIA (which we’ll get to in a bit), but it does it in a way that doesn’t break accessibility. Use it with extreme caution when there are no better workarounds, and you’ve tested it with assistive technology users.

  • aria-required
    It’s used with ="true" or ="false" to indicate if a form element has to be filled out before the form can be submitted.

If you’re building a component, you can look up the attributes for that component on the ARIA Authoring Practices Guide. The mdn web docs covers states and properties as well as ARIA roles.

Keep in mind that all these ARIA attributes tell a user something, but you still have to code the thing you’re telling them. aria-checked="true" doesn’t actually check a checkbox; it just tells the user the checkbox is checked, so that better be true or you’ll make things worse and not better for accessibility. The exception would be aria-hidden="true" which removes an element from the accessibility tree, effectively hiding it from anyone using assistive technology who can’t see.

So now we know how to use ARIA to explain what something is, what state it’s in, and what properties it has. The last thing I’ll cover is focus management.

Focus Management

Anything interactive on a website or web app must be able to receive focus. Not everyone will use a mouse, trackpad, or touch screen to interact with sites. Many people use their keyboard or an assistive technology device that emulates a keyboard. This means that for everything you can click on, you should also be able to use the tab key or arrow keys to reach it and the Enter key, and sometimes the spacebar, to select it.

There are three concepts you’ll need to consider if you use <div> and <span> to create interactive elements:

  1. You need to add tabindex="0" so that a keyboard or emulator can focus on them.
  2. For anything that accepts keyboard input, you need to add an event listener to listen for key presses.
  3. You need to add the appropriate role so that a screen reader user can identify what element you’ve built.

Remember that native HTML controls already accept keyboard focus and input and have inherent roles. This is just what you need to do when creating custom elements from non-semantic HTML.

Ben Myers does a deep dive into turning a div into a button, and I’ll share parts of his example here. Notice the tabindex and the role:

<div tabindex="0" role="button" onclick="doSomething();">
    Click me!
</div>

And you’ll need JavaScript to listen to the key presses:

const ENTER = 13;
const SPACE = 32;
// Select your button and store it in ‘myButton’
myButton.addEventListener('keydown', function(event) {
    if (event.keyCode === ENTER || event.keyCode === SPACE) {
        event.preventDefault(); // Prevents unintentional form submissions, page scrollings, the like
        doSomething(event);
    }
});

When it comes to figuring out which keys to listen for, I suggest looking up the component you’re building in the ARIA Authoring Practices Guide and following the keyboard interaction recommendations.

Common Mistakes

Having looked at a lot of code in my lifetime, I see some accessibility errors being made repeatedly. Here’s a list of the most common mistakes I find and how to avoid them:

Using An aria-labelledby Attribute That References An ID That Doesn’t Exist

For example, a modal that has a title in the modal but aria-labelledby is referencing something else that no longer exists. It’s probably something removed by another developer who didn’t realize the aria-labelledby connection was there. Instead, the modal title could’ve been an <h1> and either aria-labelledby could reference the <h1> or you could set the focus on the <h1> when the modal opens and a screen reader user would know what’s going on as long as role="dialog” was also used. Try to avoid fragile structures that, if someone else came along and edited the code, would break easily.

Not Moving The Focus Into The Modal When It Opens

Countless times I’ve seen a screen reader user navigating the page behind the modal either unaware a modal has opened or confused because they can’t find the contents of the modal. There are several ways to trap focus within a modal, but one of the newer methods is to add inert to the <main> landmark (and, of course, make sure the modal isn’t inside <main>). Inert is getting better support across browsers lately. To learn more, check out Lars Magnus Klavenes’ Accessible modal dialogs using inert.

Adding Roles That Duplicate HTML

In general, doing something like this <button role="button”> is pointless. There is one case where it might make sense to do this. VoiceOver and Safari remove list element semantics when list-style: none is used. This was done on purpose because if there is no indication to a sighted user that the content is a list, why tell a screen reader user that it’s a list? If you want to override this, you can add an explicit ARIA role="list" to the <ul>.

Adrian Roselli says an unstyled list not being announced as a list “…may not be a big deal unless user testing says you really need a list.” I agree with him on that point, but I’m sharing the fix in case your user testing shows it’s beneficial.

Adding tabindex="0" To Every Element

Sometimes developers start using a screen reader and assume that tabbing is the only way to navigate; therefore, anything without tabindex isn’t accessible. This is NOT true. Remember, if you don’t know how to use a screen reader, you can’t troubleshoot usability issues. Meet with an everyday screen reader user to figure those out.

Using Child Roles Without Parent Roles

For example, role="option" must have a direct parent with role="listbox".

<div role="listbox">
    <ul>
      <li role="option">

The above code isn’t valid because there’s a <ul> between the parent and child elements. This can be fixed by adding a presentation role to essentially hide the <ul> from the accessibility tree, like <ul role="presentation”>.

Using role="menu" For Navigation

Website navigation is really a table of contents and not a menu. ARIA menus are not meant to be used for navigation but application behavior like the menus in a desktop application. Instead, use <nav>, and if you have child navigation links, those should be hidden until a button is pressed to show them:

<nav aria-label="Main menu">
    <button aria-expanded="false">Products</button>
    <ul hidden>
       <li>Cat pyjamas</li>...

If you want to learn more, Heydon Pickering does a deep dive into Building Accessible Menu Systems in his Smashing Magazine article.

Regarding navigation, using <nav> more than once on a page without giving each instance a unique label means that screen reader users will have to explore each navigation region to find the one they’re looking for. A simple aria-label on each <nav> will make it much easier.

<nav aria-label="Customer service">
  <ul>
    <li><a href="#">Help</a></li>
    <li><a href="#">Order tracking</a></li>
    <li><a href="#">Shipping & Delivery</a></li>
    <li><a href="#">Returns</a></li>
    <li><a href="#">Contact us</a></li>
    <li><a href="#">Find a store</a></li>
  </ul>
</nav>
How To Validate ARIA

Use automated accessibility checkers like Axe or WAVE extensions when you run your code in a browser. Accessibility linters like Axe for Visual Studio Code or ESLint for JSX elements will check your code as you write it.

Listen to your code with a screen reader. You’d never ship code without running it in a browser to make sure it works, and using a screen reader can be the same kind of check. NVDA is free for Windows, and VoiceOver comes built into Macs and iPhones. TalkBack is built into Android phones.

Test with assistive technology users. I consider this mandatory for any large organization that has a budget for accessibility (and they all should). There are companies that can recruit assistive technology users for testing or run user testing for you, and the company I work for can provide 2-day turnarounds on user testing that is facilitated by you or unmoderated to support accessibility testing at scale.

Frameworks And Component Libraries

If you’re using a web framework, one way to make the lift of building for accessibility a bit lighter is to use a component library with accessibility built in. I’ll add the caveat that accessibility can be complex and not everything that claims to be accessible is truly usable by assistive technology users. The best way to ensure accessibility is to always test with the users you are building for.

Here are some starting points for your search:

Conclusion

Hopefully, this has demystified ARIA for you. Like a secret language that only the most elite accessibility geeks know, it has its own Fight Club-esque rules.

  1. The first rule of ARIA is “Don’t use ARIA.” A <button> will always be better than <div role="button">.
  2. Secondly, don’t override native semantics. Instead of <button role="heading">, use <h3><button>.
  3. Also, always remember that all ARIA interactive elements must work with the keyboard.
  4. Don’t use role="presentation" or aria-hidden="true" on a focusable element. <button role="presentation”> means you’re hiding that button only from assistive technology users. That’s not just inaccessible; it’s outright excluding certain users.
  5. Last but not least, all interactive elements must have an accessible name. There are many ways to do that, and here are some of them:
<button>Print</button> (the name is the button text)

<div aria-label="Settings"><svg></div> (the aria-label assigns a name)

<div aria-labelledby="myName">
  <h1 id="myName">Heading</h1>
</div>

<label for="name">Name</label>
<input type="text" id="name" />

I like to think of ARIA as a tool used by the most elite Special Ops Team that you call in for your most difficult accessibility challenges. Well, maybe I just always wanted to do one-arm pushups like Emily Blunt in Edge of Tomorrow, and this is the closest I can get. Anyhow, I hope this was helpful and that you are no longer confused about ARIA. Go forth and build accessible things!

5 Website Header Design Trends for 2023

There’s nothing wrong with going the classic route when it comes to website header design. Data suggests that the traditional layout with the logo on the left and the navigation on the right is and always will be an effective way to go. 

That said, there are ways to maintain this long-standing and winning formula while putting a modern spin on it. While WordPress might not provide you with the tools to do much in the way of customizing your header, BeTheme’s Header Builder does:

If you’re curious to see what kind of website header trends will be popular in the coming year (and which ones you can easily create using the BeTheme Builder), keep reading.

5 website header design trends to experiment with in 2023

As web design technologies give us more control over how websites look, we’re going to see a more diverse array of design trends. In 2023, here is how those trends will transform website header design:

1. The multi-level header

Every website header must include two components: the logo and the navigation. As websites have grown to provide more information and perform more complex tasks, though, users would greatly benefit from other elements being included in the header. 

By affixing additional sections to the header, you can provide visitors with the most important information and action buttons at the very top of the website. 

These additional levels can create space for things like:

  • Primary call-to-action button (like “Book Now”)
  • Search bar
  • eCommerce shopping cart and account login icons
  • Website notifications and promotional messages
  • And more

You can also use the multi-level header design to add secondary navigations. For instance, BeThemeStore2’s website header has four levels — one of which is a dismissable notification bar at the top of the page:

The main navigation appears below the logo where users expect it to be. They can search through different device categories to narrow down their search from here. 

The secondary navigation, on the other hand, appears above the logo section. It contains pages about the company. While these types of links are often placed in the footer, the multi-level header design enables them to appear at the top without overcrowding. 

Another way to make the multi-level design work for dual navigations is to do as Gap does:

When building a website for a company that has sister brands, use extra header levels to add links to those websites. This way, you can create a truly omnichannel shopping experience and users won’t have to stumble across the connection between the brands only once they’ve scrolled to the footer.

2. The mega menu header

In recent years, many designers have used the footer as overflow for navigational links. It’s an effective way to save space in the header, which is great if you want to maintain a minimal design throughout each page. However, it’s not always the ideal approach, especially as web pages get longer and longer on both desktop and mobile.

One way of dealing with this is to create a multi-level header and to place the secondary links outside of the main navigation. Another option is to create a mega menu.

Mega menus used to be popular, though they sometimes ended up being clunky and difficult to use — especially as smartphones became an increasingly popular way to access the internet. Mega menu design has gotten much better today and we’re going to see them make a big comeback in 2023.

News sites, retailers, and enterprises with dozens of pages that need to be front and center will make use of this design trend. Urban Outfitters is one such website currently using a mega menu design:

Modern mega menu headers will be cleaner and better organized than their predecessors. What’s more, they’ll be more visually pleasing to look at with promotional graphics included within them. 

BeFurnitureStore is another website that demonstrates how to pull off this header design trend:

It’s up to you to determine how much information to include in the mega menu. Just be careful about how many clicks you ask your visitors to make. Generally, the mega menu should go no more than two or three levels deep. 

3. The left-aligned header

Internet users’ eyes are naturally drawn to the top-left area of a website (or right on websites published using right-to-left languages like Arabic or Hebrew). This is why the logo is commonly placed in the corner. Not only does it strengthen brand recognition, but it makes navigating back “Home” an intuitive task for all users. 

While the horizontal header at the top of the page is the common way we see the logo and navigation presented, we can also turn the header on its side and make it vertical. So long as we have the logo in the top corner, our visitors’ eyes will naturally pivot around it to find the navigation.

While this layout usually doesn’t work for larger websites, it’s a creative and unique way to design the header on smaller websites — like for local restaurants, event companies, services providers, and so on. 

For example, here’s how the left-aligned header design looks on the BeEvent7 website:

The nice thing about the left-aligned header and navigation is that it’s always present. This way, it won’t matter how long the page gets. Visitors won’t have to scroll through your content in order to re-engage with the header at any point. 

This will come in handy with a portfolio website like Dylan Perlot’s:

One thing to keep in mind with this header layout is that it’s not inherently responsive. So it will need to be converted into a hamburger menu for smaller screens.

4. The minimal content header

This trend is another way in which you can design the header for smaller websites. Rather than leave every part of it on full display, the minimal content header will tuck the navigation (and secondary elements like the search bar) away under a hamburger menu icon.

As more and more people spend time browsing the web from their phones, their familiarity with the hamburger icon has grown. In turn, this navigation icon can now be used on larger screens without creating usability problems. 

Typically, the minimal content header is presented with just a logo in the left corner and a hamburger icon in the right. When the icon is clicked, the navigation appears as a dismissible sidebar. You can see an example of this on the BePortfolio2 site:

Another way to handle this is by turning the menu into a fullscreen pop-up as Kellogg’s does:

If you compare the BePortfolio and Kellogg’s examples, you’ll get a good idea of which to use for the type of website you’re building. 

For smaller websites, a less intrusive sidebar menu header would look good. However, if your users need to spend more time in the navigation (like if it’s a mega menu), then a fullscreen pop-up that hides the main website UI would be best.

5. The transparent background header

The website header is its own section. However, just as different sections on our web pages don’t need clearly defined borders in order for visitors to recognize where one starts and another ends, the header doesn’t need them either. 

Something we’ll see more of next year will be transparent header design. This will give websites a more open feel as the header blends into the rest of the content. 

The one thing to be careful of when removing the solid background from the header is color — be it a solid color background, image, or video. In order for the website header elements to be easy to locate and use, they need to be visible at all times, so color contrast is important.

One way to avoid any contrast issues is to make the header solid when the visitor scrolls. You can see how this works on the BeVR website:

Another website that uses this transparent header scrolling effect is e-Money:

While this transparent-to-solid effect works, you can always choose a header font color that stands out against your background. You’ll have the most luck with this when your web page background is the same color throughout.

Make a strong impression with website header design

While WordPress themes are indispensable web design tools, until recently there have been limitations on how much of a website they allow us to customize. But that’s all changing with the BeTheme Header & Mega Menu Builder.

One thing to keep in mind is that just because you have the ability to fully customize the website header design, that doesn’t mean you should break all the rules. If you look at these 2023 trends, you’ll see that good website header design principles persist. 

So as you experiment with header customization, find a good balance. Flex your creative muscles as you add more information to the header and make it more visually engaging, but never forget the general structure that users have come to know and appreciate.

The Easiest Way to Inspect and Copy CSS Code From Websites

Do you ever get frustrated using Dev Tools when working on a website project? Having to go back and forth between the web page you’re working on and the inspector to view CSS and make adjustments can often be a bit of a challenge. Thankfully, there is a browser extension that streamlines that process: CSS Scan. In this article, we are going to look at how this exciting tool could quite possibly change your life as a web developer, or at the very least, speed up your workflow.

CSS Scan website

Easy Installation & Lifetime License

It’s pretty simple to get started with CSS Scan, since it’s a browser extension/add-on. Whatever your preferred browser, CSS Scan can be installed on Chrome, Firefox, Safari, and Edge. Since this is a premium extension, you have to buy a license first, but it’s a lifetime license so it’s a one-time purchase that can then be used on 3 browsers or devices simultaneously.

Considering all of that and what you get with this license, the regular one-time purchase price of $120 is a steal! Even better, CSS Scan is often on sale for a discount, so you can get started for even less cost to you. You can even try it out on the website before you buy to make sure it’s as great as we say it is.

Getting Started

Once the extension is installed, all you have to do is right click on a web page and select “Inspect with CSS Scan” from the menu. A toolbar will appear at the top right of the window (you can also move it to the bottom if you prefer).

CSS Scan toolbar

Here you can set up your preferred options, such as what happens when you click, whether or not to copy CSS of child elements or HTML code, what to show on the screen, and more. It’s very handy to be able to customize and adjust your experience and usage.

Once you’re ready, simply hover over any element on the page to view its CSS.

CSS Scan demo

As opposed to browser Dev Tools, you don’t have to scroll through countless CSS rules. Everything related to the specified element is displayed and simple to copy with just a single click. View and copy all child elements, pseudo-classes and media queries in one place!

To edit the CSS in place, you just hit the spacebar and the CSS Scan window gets pinned to the screen. Then you can edit to your heart’s content, right there on the page you’re working on. You can also view the CSS of parent elements by holding control and clicking on the element or using the up and down arrow keys.

Export to Codepen

Taking it even further, you can easily extract and export the HTML and CSS of elements and all its child elements as whole components to Codepen. Just hover over the element you want to export, hit the spacebar to pin it to the screen, and then click the “Export to Codepen” button. Voila! Your element is now in your Codepen account! Now that element is available for you to use in future projects or experiment with however you want.

Should You Get CSS Scan?

We can answer that question with a resounding “Yes!” CSS Scan has a price tag that is very reasonable for everything you get, and it will immediately change your workflow, with a quick and easy adjustment period away from Dev Tools. About the only thing missing we could find is the ability to adjust the window size for responsive testing. We had to do this in Dev Tools and then use CSS Scan from there, which still works but seems like an extra step. However, CSS Scan does show and copy all related media queries for an element at once, so this is handier than only seeing the active media query for the current window size, as done in Dev Tools. Chalk this up to getting used to doing things differently than what we’re used to doing in the past.

All in all, after trying CSS Scan out, we can confidently and highly recommend it!