CSS and JavaScript accessibility best practices - Learn web development

CSS and JavaScript accessibility best practices
===============================================

* Previous
* Overview: Accessibility
* Next

CSS and JavaScript, when used properly, also have the potential to allow for accessible web experiences, or they can significantly harm accessibility if misused. This article outlines some CSS and JavaScript best practices that should be considered to ensure even complex content is as accessible as possible.

|  |  |
| --- | --- |
| Prerequisites: |
 A basic understanding of HTML, CSS, and
 JavaScript, and understanding of
 what accessibility is.
  |
| Objective: |
 To gain familiarity with using CSS and JavaScript appropriately in your
 web documents to maximize accessibility and not detract from it.
  |

CSS and JavaScript are accessible?
----------------------------------

CSS and JavaScript don't have the same immediate importance for accessibility as HTML, but they are still able to help or damage accessibility, depending on how they are used. To put it another way, it is important that you consider some best practice advice to make sure that your use of CSS and JavaScript doesn't ruin the accessibility of your documents.

CSS
---

Let's start off by looking at CSS.

### Correct semantics and user expectation

It is possible to use CSS to make any HTML element look like *anything*, but this doesn't mean that you should. As we frequently mentioned in our HTML: A good basis for accessibility article, you should use the appropriate semantic element for the job, whenever possible. If you don't, it can cause confusion and usability issues for everyone, but particularly users with disabilities. Using correct semantics has a lot to do with user expectations — elements look and behave in certain ways, according to their functionality, and these common conventions are expected by users.

As an example, a screen reader user can't navigate a page via heading elements if the developer hasn't appropriately used heading elements to markup the content. By the same token, a heading loses its visual purpose if you style it so it doesn't look like a heading.

Bottom line, you can update the styling of a page feature to fit in your design, but don't change it so much that it no longer looks or behaves as expected. The following sections summarize the main HTML features to consider.

#### "Standard" text content structure

Headings, paragraphs, lists — the core text content of your page:

```html
<h1>Heading</h1>

<p>Paragraph</p>

<ul>
  <li>My list</li>
  <li>has two items.</li>
</ul>
```

Some typical CSS might look like this:

```css
h1 {
  font-size: 5rem;
}

p,
li {
  line-height: 1.5;
  font-size: 1.6rem;
}
```

You should:

* Select sensible font sizes, line heights, letter spacing, etc. to make your text logical, legible, and comfortable to read.
* Make sure your headings stand out from your body text, typically big and bold like the default styling. Your lists should look like lists.
* Your text color should contrast well with your background color.

See HTML text fundamentals and Styling text for more information.

#### Emphasized text

Inline markup that confers specific emphasis to the text that it wraps:

```html
<p>The water is <em>very hot</em>.</p>

<p>
  Water droplets collecting on surfaces is called <strong>condensation</strong>.
</p>
```

You might want to add some simple coloring to your emphasized text:

```css
strong,
em {
  color: #a60000;
}
```

You will however rarely need to style emphasis elements in any significant way. The standard conventions of bold and italic text are very recognizable, and changing the style can cause confusion. For more on emphasis, see Emphasis and importance.

#### Abbreviations

An element that allows an abbreviation, acronym, or initialization to be associated with its expansion:

```html
<p>
  Web content is marked up using Hypertext Markup Language, or
  <abbr>HTML</abbr>.
</p>
```

Again, you might want to style it in some simple way:

```css
abbr {
  color: #a60000;
}
```

The recognized styling convention for abbreviations is a dotted underline, and it is unwise to significantly deviate from this. For more on abbreviations, see Abbreviations.

#### Links

Hyperlinks — the way you get to new places on the web:

```html
<p>Visit the <a href="https://www.mozilla.org">Mozilla homepage</a>.</p>
```

Some very simple link styling is shown below:

```css
a {
  color: #ff0000;
}

a:hover,
a:visited,
a:focus {
  color: #a60000;
  text-decoration: none;
}

a:active {
  color: #000000;
  background-color: #a60000;
}
```

The standard link conventions are underlined and a different color (default: blue) in their standard state, another color variation when the link has previously been visited (default: purple), and yet another color when the link is activated (default: red). In addition, the mouse pointer changes to a pointer icon when links are moused over, and the link receives a highlight when focused (e.g. via tabbing) or activated. The following image shows the highlight in both Firefox (a dotted outline) and Chrome (a blue outline):

![Screenshot of a list of links in Firefox browser. The list contains 4 items. The second list item is highlighted using a blue dotted outline when it is focussed via tabbing.](/en-US/docs/Learn/Accessibility/CSS_and_JavaScript/focus-highlight-firefox.png)

![Screenshot of a list of links in Chrome browser. The list contains 4 items. The third list item is highlighted using a blue outline when it is focussed via tabbing.](/en-US/docs/Learn/Accessibility/CSS_and_JavaScript/focus-highlight-chrome.png)

You can be creative with link styles, as long as you keep giving users feedback when they interact with the links. Something should definitely happen when states change, and you shouldn't get rid of the pointer cursor or the outline — both are very important accessibility aids for those using keyboard controls.

#### Form elements

Elements to allow users to input data into websites:

```html
<div>
  <label for="name">Enter your name</label>
  <input type="text" id="name" name="name" />
</div>
```

You can see some good example CSS in our form-css.html example (see it live also).

Most of the CSS you'll write for forms will be for sizing the elements, lining up labels and inputs, and getting them looking neat and tidy.

You shouldn't however deviate too much from the expected visual feedback form elements receive when they are focused, which is basically the same as links (see above). You could style form focus/hover states to make this behavior more consistent across browsers or fit in better with your page design, but don't get rid of it altogether — again, people rely on these clues to help them know what is going on.

#### Tables

Tables for presenting tabular data.

You can see a good, simple example of table HTML and CSS in our table-css.html example (see it live also).

Table CSS generally serves to make the table fit better into your design and look less ugly. It is a good idea to make sure the table headers stand out (normally using bold), and use zebra striping to make different rows easier to parse.

### Color and color contrast

When choosing a color scheme for your website, make sure that the text (foreground) color contrasts well with the background color. Your design might look cool, but it is no good if people with visual impairments like color blindness can't read your content.

There is an easy way to check whether your contrast is large enough to not cause problems. There are a number of contrast checking tools online that you can enter your foreground and background colors into, to check them. For example WebAIM's Color Contrast Checker is simple to use, and provides an explanation of what you need to conform to the WCAG criteria around color contrast.

**Note:** A high contrast ratio will also allow anyone using a smartphone or tablet with a glossy screen to better read pages when in a bright environment, such as sunlight.

Another tip is to not rely on color alone for signposts/information, as this will be no good for those who can't see the color. Instead of marking required form fields in red, for example, mark them with an asterisk and in red.

### Hiding things

There are many instances where a visual design will require that not all content is shown at once. For example, in our Tabbed info box example (see source code) we have three panels of information, but we are positioning them on top of one another and providing tabs that can be clicked to show each one (it is also keyboard accessible — you can alternatively use Tab and Enter/Return to select them).

![Three tab interface with Tab 1 selected and only its contents are displayed. The contents of other tabs are hidden. If a tab is selected, then it's text-color changes from black to white and the background-color changes from orange-red to saddle brown.](/en-US/docs/Learn/Accessibility/CSS_and_JavaScript/tabbed-info-box.png)

Screen reader users don't care about any of this — they are happy with the content as long as the source order makes sense, and they can get to it all. Absolute positioning (as used in this example) is generally seen as one of the best mechanisms of hiding content for visual effect because it doesn't stop screen readers from getting to it.

On the other hand, you shouldn't use `visibility``:hidden` or `display``:none`, because they do hide content from screen readers. Unless of course, there is a good reason why you want this content to be hidden from screen readers.

**Note:** Invisible Content Just for Screen Reader Users has a lot more useful detail surrounding this topic.

### Accept that users can override styles

It is possible for users to override your styles with their own custom styles, for example:

* See Sarah Maddox's How to use a custom style sheet (CSS) with Firefox for a useful guide covering how to do this manually in Firefox.
* It is probably easier to do it using an extension. For example, the Stylus extension is available for Firefox, with Stylish being a Chrome equivalent.

Users might do this for a variety of reasons. A visually impaired user might want to make the text bigger on all websites they visit, or a user with severe color deficiency might want to put all websites in high contrast colors that are easy for them to see. Whatever the need, you should be comfortable with this, and make your designs flexible enough so that such changes will work in your design. As an example, you might want to make sure your main content area can handle bigger text (maybe it will start to scroll to allow it all to be seen), and won't just hide it, or break completely.

JavaScript
----------

JavaScript can also break accessibility, depending on how it is used.

Modern JavaScript is a powerful language, and we can do so much with it these days, from simple content and UI updates to fully-fledged 2D and 3D games. There is no rule that says all content has to be 100% accessible to all people — you just need to do what you can, and make your apps as accessible as possible.

Simple content and functionality is arguably easy to make accessible — for example text, images, tables, forms and push button that activate functions. As we looked at in our HTML: A good basis for accessibility article, the key considerations are:

* Good semantics: Using the right element for the right job. For example, making sure you use headings and paragraphs, and `<button>` and `<a>` elements
* Making sure content is available as text, either directly as text content, good text labels for form elements, or text alternatives, e.g. alt text for images.

We also looked at an example of how to use JavaScript to build in functionality where it is missing — see Building keyboard accessibility back in. This is not ideal — really you should just use the right element for the right job — but it shows that it is possible in situations where for some reason you can't control the markup that is used. Another way to improve accessibility for non-semantic JavaScript-powered widgets is to use WAI-ARIA to provide extra semantics for screen reader users. The next article will also cover this in detail.

Complex functionality like 3D games are not so easy to make accessible — a complex 3D game created using WebGL will be rendered on a `<canvas>` element, which has no facility at this time to provide text alternatives or other information for severely visually impaired users to make use of. It is arguable that such a game doesn't really have this group of people as a part of its main target audience, and it would be unreasonable to expect you to make it 100% accessible to blind people. However, you could implement keyboard controls so it is usable by non-mouse users, and make the color scheme contrasting enough to be usable by those with color deficiencies.

### The problem with too much JavaScript

The problem often comes when people rely on JavaScript too much. Sometimes you'll see a website where everything has been done with JavaScript — the HTML has been generated by JavaScript, the CSS has been generated by JavaScript, etc. This has all kinds of accessibility and other issues associated with it, so it is not advised.

As well as using the right element for the right job, you should also make sure you are using the right technology for the right job! Think carefully about whether you need that shiny JavaScript-powered 3D information box, or whether plain old text would do. Think carefully about whether you need a complex non-standard form widget, or whether a text input would do. And don't generate all your HTML content using JavaScript if at all possible.

### Keeping it unobtrusive

You should keep **unobtrusive JavaScript** in mind when creating your content. The idea of unobtrusive JavaScript is that it should be used wherever possible to enhance functionality, not build it in entirely — basic functions should ideally work without JavaScript, although it is appreciated that this is not always an option. But again, a large part of it is using built-in browser functionality where possible.

Good example uses of unobtrusive JavaScript include:

* Providing client-side form validation, which alerts users to problems with their form entries quickly, without having to wait for the server to check the data. If it isn't available, the form will still work, but validation might be slower.
* Providing custom controls for HTML `<video>`s that are accessible to keyboard-only users, along with a direct link to the video that can be used to access it if JavaScript is not available (the default `<video>` browser controls aren't keyboard accessible in most browsers).

As an example, we've written a quick and dirty client-side form validation example — see form-validation.html (also see the demo live). Here you'll see a simple form; when you try to submit the form with one or both fields left empty, the submit fails, and an error message box appears to tell you what is wrong.

This kind of form validation is unobtrusive — you can still use the form absolutely fine without the JavaScript being available, and any sensible form implementation will have server-side validation active as well, because it is too easy for malicious users to bypass client-side validation (for example, by turning JavaScript off in the browser). The client-side validation is still really useful for reporting errors — users can know about mistakes they make instantly, rather than having to wait for a round trip to the server and a page reload. This is a definite usability advantage.

**Note:** Server-side validation has not been implemented in this simple demo.

We've made this form validation pretty accessible too. We've used `<label>` elements to make sure the form labels are unambiguously linked to their inputs, so screen readers can read them out alongside:

```html
<label for="name">Enter your name:</label>
<input type="text" name="name" id="name" />
```

We only do the validation when the form is submitted — this is so that we don't update the UI too often and potentially confuse screen reader (and possibly other) users:

```js
form.onsubmit = validate;

function validate(e) {
  errorList.innerHTML = "";
  for (let i = 0; i < formItems.length; i++) {
    const testItem = formItems[i];
    if (testItem.input.value === "") {
      errorField.style.left = "360px";
      createLink(testItem);
    }
  }

  if (errorList.innerHTML !== "") {
    e.preventDefault();
  }
}
```

**Note:** In this example, we are hiding and showing the error message box using absolute positioning rather than another method such as visibility or display, because it doesn't interfere with the screen reader being able to read content from it.

Real form validation would be much more complex than this — you'd want to check that the entered name actually looks like a name, the entered age is actually a number and is realistic (e.g. nonnegative and less than 4 digits). Here we've just implemented a simple check that a value has been filled in to each input field (`if (testItem.input.value === '')`).

When the validation has been performed, if the tests pass then the form is submitted. If there are errors (`if (errorList.innerHTML !== '')`) then we stop the form submitting (using `preventDefault()`), and display any error messages that have been created (see below). This mechanism means that the errors will only be shown if there are errors, which is better for usability.

For each input that doesn't have a value filled in when the form is submitted, we create a list item with a link and insert it in the `errorList`.

```js
function createLink(testItem) {
  const listItem = document.createElement("li");
  const anchor = document.createElement("a");

  const name = testItem.input.name;
  anchor.textContent = `${name} field is empty: fill in your ${name}.`;
  anchor.href = `#${name}`;
  listItem.appendChild(anchor);
  errorList.appendChild(listItem);
}
```

Each link serves a dual purpose — it tells you what the error is, plus you can click on it/activate it to jump straight to the input element in question and correct your entry.

In addition, the `errorField` is placed at the top of the source order (although it is positioned differently in the UI using CSS), meaning that users can find out exactly what's wrong with their form submissions and get to the input elements in question by going back up to the start of the page.

As a final note, we have used some WAI-ARIA attributes in our demo to help solve accessibility problems caused by areas of content constantly updating without a page reload (screen readers won't pick this up or alert users to it by default):

```html
<div class="errors" role="alert" aria-relevant="all">
  <ul></ul>
</div>
```

We will explain these attributes in our next article, which covers WAI-ARIA in much more detail.

**Note:** Some of you will probably be thinking about the fact that HTML forms have built-in validation mechanisms like the `required`, `min`/`minlength`, and `max`/`maxlength` attributes (see the `<input>` element reference for more information). We didn't end up using these in the demo because cross-browser support for them is patchy (for example IE10 and above only).

**Note:** WebAIM's Usable and Accessible Form Validation and Error Recovery provides some further useful information about accessible form validation.

### Other JavaScript accessibility concerns

There are other things to be aware of when implementing JavaScript and thinking about accessibility. We will add more as we find them.

#### mouse-specific events

As you will be aware, most user interactions are implemented in client-side JavaScript using event handlers, which allow us to run functions in response to certain events happening. Some events can have accessibility issues. The main example you'll come across is mouse-specific events like mouseover, mouseout, dblclick, etc. Functionality that runs in response to these events will not be accessible using other mechanisms, like keyboard controls.

To mitigate such problems, you should double up these events with similar events that can be activated by other means (so-called device-independent event handlers) — focus and blur would provide accessibility for keyboard users.

Let's look at an example that highlights when this could be useful. Maybe we want to provide a thumbnail image that shows a larger version of the image when it is moused over or focused (like you'd see on an e-commerce product catalog.)

We've made a very simple example, which you can find at mouse-and-keyboard-events.html (see also the source code). The code features two functions that show and hide the zoomed-in image; these are run by the following lines that set them as event handlers:

```js
imgThumb.onmouseover = showImg;
imgThumb.onmouseout = hideImg;

imgThumb.onfocus = showImg;
imgThumb.onblur = hideImg;
```

The first two lines run the functions when the mouse pointer hovers over and stops hovering over the thumbnail, respectively. This won't allow us to access the zoomed view by keyboard though — to allow that, we've included the last two lines, which run the functions when the image is focused and blurred (when focus stops). This can be done by tabbing over the image, because we've included `tabindex="0"` on it.

The click event is interesting — it sounds mouse-dependent, but most browsers will activate onclick event handlers after Enter/Return is pressed on a link or form element that has focus, or when such an element is tapped on a touchscreen device. This doesn't work by default however when you allow a non-default-focusable event to have focus using tabindex — in such cases you need to detect specifically when that exact key is pressed (see Building keyboard accessibility back in).

Test your skills!
-----------------

You've reached the end of this article, but can you remember the most important information? You can find some further tests to verify that you've retained this information before you move on — see Test your skills: CSS and JavaScript accessibility.

Summary
-------

We hope this article has given you a good amount of detail and understanding about the accessibility issues surrounding CSS and JavaScript use on web pages.

Next up, WAI-ARIA!

* Previous
* Overview: Accessibility
* Next


What is accessibility? - Learn web development

What is accessibility?
======================

* Overview: Accessibility
* Next

This article starts the module off with a good look at what accessibility is — this overview includes what groups of people we need to consider and why, what tools different people use to interact with the web, and how we can make accessibility part of our web development workflow.

|  |  |
| --- | --- |
| Prerequisites: | A basic understanding of HTML and CSS. |
| Objective: |
 To gain familiarity with accessibility, including what it is, and how it
 affects you as a web developer.
  |

So what is accessibility?
-------------------------

Accessibility is the practice of making your websites usable by as many people as possible. We traditionally think of this as being about people with disabilities, but the practice of making sites accessible also benefits other groups such as those using mobile devices, or those with slow network connections.

You might also think of accessibility as treating everyone the same, and giving them equal opportunities, no matter what their ability or circumstances. Just as it is wrong to exclude someone from a physical building because they are in a wheelchair (modern public buildings generally have wheelchair ramps or elevators), it is also not right to exclude someone from a website because they have a visual impairment. We are all different, but we are all human, and therefore have the same human rights.

Accessibility is the right thing to do. Providing accessible sites is part of the law in some countries, which can open up some significant markets that otherwise would not be able to use your services or buy your products.

Building accessible sites benefits everyone:

* Semantic HTML, which improves accessibility, also improves SEO, making your site more findable.
* Caring about accessibility demonstrates good ethics and morals, which improves your public image.
* Other good practices that improve accessibility also make your site more usable by other groups, such as mobile phone users or those on low network speed. In fact, everyone can benefit from many such improvements.
* Did we mention it is also the law in some places?
What kinds of disability are we looking at?
-------------------------------------------

People with disabilities are just as diverse as people without disabilities, and so are their disabilities. The key lesson here is to think beyond your own computer and how you use the web, and start learning about how others use it — *you are not your users*. The main types of disability to consider are explained below, along with any special tools they use to access web content (known as **assistive technologies**, or **ATs**).

**Note:** The World Health Organization's Disability and health fact sheet states that "Over a billion people, about 15% of the world's population, have some form of disability", and "Between 110 million and 190 million adults have significant difficulties in functioning."

### People with visual impairments

People with visual impairments include people with blindness, low-level vision, and color blindness. Many people with visual impairments use screen magnifiers that are either physical magnifiers or software zoom capabilities. Most browsers and operating systems these days have zoom capabilities. Some users will rely on screen readers, which is software that reads digital text aloud. Some screen reader examples include:

* Paid commercial products, like JAWS (Windows) and Dolphin Screen Reader (Windows).
* Free products, like NVDA (Windows), ChromeVox (Chrome), and Orca (Linux).
* Software built into the operating system, like VoiceOver (macOS, iPadOS, iOS), Narrator (Windows), ChromeVox (on ChromeOS), and TalkBack (Android).

It is a good idea to familiarize yourself with screen readers; you should also set up a screen reader and play around with it, to get an idea of how it works. See our cross-browser testing screen readers guide for more details on using them. The below video also provides a brief example of what the experience is like.

In terms of statistics, the World Health Organization estimates that "285 million people are estimated to be visually impaired worldwide: 39 million are blind and 246 million have low vision." (see Visual impairment and blindness). That's a large and significant population of users to just miss out on because your site isn't coded properly — almost the same size as the population of the United States of America.

### People with hearing impairments

Deaf and hard-of-hearing (DHH) people have various levels of hearing loss ranging from mild to profound. Although some do use AT (see Assistive Devices for People with Hearing, Voice, Speech, or Language Disorders), they are not widespread.

To provide access, textual alternatives must be provided. Videos should be manually captioned, and transcripts should be provided for audio content. Furthermore, due to high levels of language deprivation in DHH populations, text simplification should be considered.

Deaf and hard-of-hearing people also represent a significant userbase — "466 million people worldwide have disabling hearing loss", says the World Health Organization's Deafness and hearing loss fact sheet.

### People with mobility impairments

These people have disabilities concerning movement, which might involve purely physical issues (such as loss of limb or paralysis), or neurological/genetic disorders that lead to weakness or loss of control in limbs. Some people might have difficulty making the exact hand movements required to use a mouse, while others might be more severely affected, perhaps being significantly paralyzed to the point where they need to use a head pointer to interact with computers.

This kind of disability can also be a result of old age, rather than any specific trauma or condition, and it could also result from hardware limitations — some users might not have a mouse.

The way this usually affects web development work is the requirement that controls be accessible by the keyboard — we'll discuss keyboard accessibility in later articles in the module, but it is a good idea to try out some websites using just the keyboard to see how you get on. Can you use the Tab key to move between the different controls of a web form, for example? You can find more details about keyboard controls in our Cross browser testing Using native keyboard accessibility section.

In terms of statistics, a significant number of people have mobility impairments. The US Centers for Disease Control and Prevention Disability and Functioning (Non-institutionalized Adults 18 Years and Over) reports the USA "Percent of adults with any physical functioning difficulty: 16.1%".

### People with cognitive impairments

Cognitive impairment refers to a broad range of disabilities, from people with intellectual disabilities who have the most-limited capabilities, to all of us as we age and have difficulty thinking and remembering. The range includes people with mental illnesses, such as depression and schizophrenia. It also includes people with learning disabilities, such as dyslexia and attention deficit hyperactivity disorder. Importantly, though there is a lot of diversity within clinical definitions of cognitive impairments, people with them experience a common set of functional problems. These include difficulty with understanding content, remembering how to complete tasks, and confusion caused by inconsistent webpage layouts.

A good foundation of accessibility for people with cognitive impairments includes:

* Delivering content in more than one way, such as by text-to-speech or by video.
* Easily understood content, such as text written using plain-language standards.
* Focusing attention on important content.
* Minimizing distractions, such as unnecessary content or advertisements.
* Consistent webpage layout and navigation.
* Familiar elements, such as underlined links blue when not visited and purple when visited.
* Dividing processes into logical, essential steps with progress indicators.
* Website authentication as easy as possible without compromising security.
* Making forms easy to complete, such as with clear error messages and simple error recovery.
### Notes

* Designing with cognitive accessibility will lead to good design practices. They will benefit everyone.
* Many people with cognitive impairments also have physical disabilities. Websites must conform to the W3C's Web Content Accessibility Guidelines, including cognitive accessibility guidelines.
* The W3C's Cognitive and Learning Disabilities Accessibility Task Force produces web accessibility guidelines for people with cognitive impairments.
* WebAIM has a Cognitive page of relevant information and resources.
* The United States Centers for Disease Control estimate that, as of 2018, 1 in 4 US citizens have a disability and, of them, cognitive impairment is the most common for young people.
* In the US, some intellectual disabilities have historically been referred to as "mental retardation." Many now consider this term disparaging, so its use should be avoided.
* In the UK, some intellectual disabilities are referred to as "learning disabilities" or "learning difficulties".
Implementing accessibility into your project
--------------------------------------------

A common accessibility myth is that accessibility is an expensive "added extra" to implement on a project. This myth actually *can* be true if either:

* You are trying to "retrofit" accessibility onto an existing website that has significant accessibility issues.
* You have only started to consider accessibility and uncovered related issues in the late stages of a project.

If however, you consider accessibility from the start of a project, the cost of making most content accessible should be fairly minimal.

When planning your project, factor accessibility testing into your testing regime, just like testing for any other important target audience segment (e.g., target desktop or mobile browsers). Test early and often, ideally running automated tests to pick up on programmatically detectable missing features (such as missing image alternative text or bad link text — see Element relationships and context) and doing some testing with disabled user groups to see how well more complex site features work for them. For example:

* Is my date picker widget usable by people using screen readers?
* If content updates dynamically, do visually impaired people know about it?
* Are my UI buttons accessible to both keyboard and touch interface users?

You can and should keep a note of potential problem areas in your content that will need work to make it accessible, make sure it is tested thoroughly, and think about solutions/alternatives. Text content (as you'll see in the next article) is easy, but what about your multimedia content, and your whizzy 3D graphics? You should look at your project budget and think about what solutions you have available to make such content accessible. Having all your multimedia content transcribed is one option which, while expensive, is possible.

Also, be realistic. "100% accessibility" is an unobtainable ideal — you will always come across some kind of edge case that results in a certain user finding certain content difficult to use — but you should do as much as you can. If you are planning to include a whizzy 3D pie chart graphic made using WebGL, you might want to include a data table as an accessible alternative representation of the data. Or, you might want to just include the table and get rid of the 3D pie chart — the table is accessible by everyone, quicker to code, less CPU-intensive, and easier to maintain.

On the other hand, if you are working on a gallery website showing interesting 3D art, it would be unreasonable to expect every piece of art to be perfectly accessible to visually impaired people, given that it is an entirely visual medium.

To show that you care and have thought about accessibility, publish an accessibility statement on your site that details what your policy is toward accessibility, and what steps you have taken toward making the site accessible. If someone does notify you that your site has an accessibility problem, start a dialog with them, be empathetic, and take reasonable steps to try to fix the problem.

**Note:** Our Handling common accessibility problems article covers accessibility specifics that should be tested in more detail.

To summarize:

* Consider accessibility from the start of a project, and test early and often. Just like any other bug, an accessibility problem becomes more expensive to fix the later it is discovered.
* Bear in mind that a lot of accessibility best practices benefit everyone, not just users with disabilities. For example, lean semantic markup is not only good for screen readers, but it is also fast to load and performant. This benefits everyone, especially those on mobile devices and/or slow connections.
* Publish an accessibility statement on your site and engage with people having problems.
Accessibility guidelines and the law
------------------------------------

There are numerous checklists and sets of guidelines available for basing accessibility tests on, which might seem overwhelming at first glance. Our advice is to familiarize yourself with the basic areas in which you need to take care, as well as understanding the high-level structures of the guidelines that are most relevant to you.

* For a start, the W3C has published a large and very detailed document that includes very precise, technology-agnostic criteria for accessibility conformance. These are called the Web Content Accessibility Guidelines (WCAG), and they are not a short read by any means. The criteria are split up into four main categories, which specify how implementations can be made perceivable, operable, understandable, and robust. The best place to get a light introduction and start learning is WCAG at a Glance. There is no need to learn all of the WCAG criteria — be aware of the major areas of concern, and use a variety of techniques and tools to highlight any areas that don't conform to the WCAG criteria (see below for more).
* Your country may also have specific legislation governing the need for websites serving their population to be accessible — for example EN 301 549 in the EU, Section 508 of the Rehabilitation Act in the US, Federal Ordinance on Barrier-Free Information Technology in Germany, the Accessibility Regulations 2018 in the UK, Accessibilità in Italy, the Disability Discrimination Act in Australia, etc. The W3C keeps a list of Web Accessibility Laws & Policies by country.

So while the WCAG is a set of guidelines, your country will probably have laws governing web accessibility, or at least the accessibility of services available to the public (which could include websites, television, physical spaces, etc.) It is a good idea to find out what your laws are. If you make no effort to check that your content is accessible, you could be legally liable if people complain.

This sounds serious, but really you just need to consider accessibility as the main priority of your web development practices, as outlined above. If in doubt, get advice from a qualified lawyer. We're not going to offer any more advice than this, because we're not lawyers.

Accessibility APIs
------------------

Web browsers make use of special **accessibility APIs** (provided by the underlying operating system) that expose information useful for assistive technologies (ATs) — ATs mostly tend to make use of semantic information, so this information doesn't include things like styling information, or JavaScript. This information is structured in a tree of information called the **accessibility tree**.

Different operating systems have different accessibility APIs available:

* Windows: MSAA/IAccessible, UIAExpress, IAccessible2
* macOS: NSAccessibility
* Linux: AT-SPI
* Android: Accessibility framework
* iOS: UIAccessibility

Where the native semantic information provided by the HTML elements in your web apps falls down, you can supplement it with features from the WAI-ARIA specification, which add semantic information to the accessibility tree to improve accessibility. You can learn a lot more about WAI-ARIA in our WAI-ARIA basics article.

Summary
-------

This article should have given you a useful high-level overview of accessibility, shown you why it's important, and looked at how you can fit it into your workflow. You should now also have a thirst to learn about the implementation details that can make sites accessible, and we'll start on that in the next section, looking at why HTML is a good basis for accessibility.

* Overview: Accessibility
* Next
See also
--------

* WCAG
    + Perceivable
    + Operable
    + Understandable
    + Robust
* Google Chrome released an auto-captioning extension


Accessible multimedia - Learn web development

Accessible multimedia
=====================

* Previous
* Overview: Accessibility
* Next

Another category of content that can create accessibility problems is multimedia. Video, audio, and image content need to be given proper textual alternatives so that they can be understood by assistive technologies and their users. This article shows how.

|  |  |
| --- | --- |
| Prerequisites: |
 A basic understanding of HTML, CSS, JavaScript, and an understanding of
 what accessibility is.
  |
| Objective: |
 To understand the accessibility issues behind multimedia, and how to
 overcome them.
  |

Multimedia and accessibility
----------------------------

So far in this module, we have looked at a variety of content and what needs to be done to ensure its accessibility, ranging from simple text content to data tables, images, native controls such as form elements and buttons, and even more complex markup structures (with WAI-ARIA attributes).

This article on the other hand looks at another general class of content that arguably isn't as easy to ensure accessibility for — multimedia. Images, audio tracks, videos, `<canvas>` elements, etc., aren't as easily understood by screen readers or navigated by the keyboard, and we need to give them a helping hand.

But don't despair — here we will help you navigate through the techniques available for making multimedia more accessible.

Simple images
-------------

We already covered simple text alternatives for HTML images in our HTML: A good basis for accessibility article — you can refer back to there for the full details. In short, you should ensure that where possible visual content has an alternative text available for screen readers to pick up and read to their users.

For example:

```html
<img
 src="dinosaur.png"
 alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth." />
```

Accessible audio and video controls
-----------------------------------

Implementing controls for web-based audio/video shouldn't be a problem, right? Let's investigate.

### The problem with native HTML controls

HTML video and audio instances even come with a set of inbuilt controls that allow you to control the media straight out of the box. For example (see `native-controls.html` source code and live):

```html
<audio controls>
  <source src="viper.mp3" type="audio/mp3" />
  <source src="viper.ogg" type="audio/ogg" />
  <p>
    Your browser doesn't support HTML audio. Here is a
    <a href="viper.mp3">link to the audio</a> instead.
  </p>
</audio>

<br />

<video controls>
  <source src="rabbit320.mp4" type="video/mp4" />
  <source src="rabbit320.webm" type="video/webm" />
  <p>
    Your browser doesn't support HTML video. Here is a
    <a href="rabbit320.mp4">link to the video</a> instead.
  </p>
</video>
```

The controls attribute provides play/pause buttons, seek bar, etc. — the basic controls you'd expect from a media player. It looks like so in Firefox and Chrome:

![Screenshot of Video Controls in Firefox](/en-US/docs/Learn/Accessibility/Multimedia/native-controls-firefox.png)

![Screenshot of Video Controls in Chrome](/en-US/docs/Learn/Accessibility/Multimedia/native-controls-chrome.png)

However, there are problems with these controls:

* They are not keyboard-accessible in most browsers, i.e. you can't tab between the controls inside the native player. Opera and Chrome provide this to some degree, but it still isn't ideal.
* Different browsers give the native controls differing styling and functionality, and they aren't stylable, meaning that they can't be easily made to follow a site style guide.

To remedy this, we can create our own custom controls. Let's look at how.

### Creating custom audio and video controls

HTML video and audio share an API — HTML Media Element — which allows you to map custom functionality to buttons and other controls — both of which you define yourself.

Let's take the video example from above and add custom controls to them.

#### Basic setup

First, grab a copy of our custom-controls-start.html, custom-controls.css, rabbit320.mp4, and rabbit320.webm files and save them in a new directory on your hard drive.

Create a new file called main.js and save it in the same directory.

First of all, let's look at the HTML for the video player, in the HTML:

```html
<section class="player">
  <video controls>
    <source src="rabbit320.mp4" type="video/mp4" />
    <source src="rabbit320.webm" type="video/webm" />
    <p>
      Your browser doesn't support HTML video. Here is a
      <a href="rabbit320.mp4">link to the video</a> instead.
    </p>
  </video>

  <div class="controls">
    <button class="playpause">Play</button>
    <button class="stop">Stop</button>
    <button class="rwd">Rwd</button>
    <button class="fwd">Fwd</button>
    <div class="time">00:00</div>
  </div>
</section>
```

#### JavaScript basic setup

We've inserted some simple control buttons below our video. These controls of course won't do anything by default; to add functionality, we will use JavaScript.

We will first need to store references to each of the controls — add the following to the top of your JavaScript file:

```js
const playPauseBtn = document.querySelector(".playpause");
const stopBtn = document.querySelector(".stop");
const rwdBtn = document.querySelector(".rwd");
const fwdBtn = document.querySelector(".fwd");
const timeLabel = document.querySelector(".time");
```

Next, we need to grab a reference to the video/audio player itself — add this line below the previous lines:

```js
const player = document.querySelector("video");
```

This holds a reference to a `HTMLMediaElement` object, which has several useful properties and methods available on it that can be used to wire up functionality to our buttons.

Before moving on to creating our button functionality, let's remove the native controls so they don't get in the way of our custom controls. Add the following, again at the bottom of your JavaScript:

```js
player.removeAttribute("controls");
```

Doing it this way round rather than just not including the controls attribute in the first place has the advantage that if our JavaScript fails for any reason, the user still has some controls available.

#### Wiring up our buttons

First, let's set up the play/pause button. We can get this to toggle between play and pause with a simple conditional function, like the following. Add it to your code, at the bottom:

```js
playPauseBtn.onclick = () => {
  if (player.paused) {
    player.play();
    playPauseBtn.textContent = "Pause";
  } else {
    player.pause();
    playPauseBtn.textContent = "Play";
  }
};
```

Next, add this code to the bottom, which controls the stop button:

```js
stopBtn.onclick = () => {
  player.pause();
  player.currentTime = 0;
  playPauseBtn.textContent = "Play";
};
```

There is no `stop()` function available on `HTMLMediaElement`s, so instead we `pause()` it, and at the same time set the `currentTime` to 0.

Next, our rewind and fast-forward buttons — add the following blocks to the bottom of your code:

```js
rwdBtn.onclick = () => {
  player.currentTime -= 3;
};

fwdBtn.onclick = () => {
  player.currentTime += 3;
  if (player.currentTime >= player.duration || player.paused) {
    player.pause();
    player.currentTime = 0;
    playPauseBtn.textContent = "Play";
  }
};
```

These are very simple, just adding or subtracting 3 seconds to the `currentTime` each time they are clicked. In a real video player, you'd probably want a more elaborate seeking bar, or similar.

Note that we also check to see if the `currentTime` is more than the total media `duration` or if the media is not playing when the `fwdBtn` is pressed. If either condition is true, we stop the video to avoid the user interface going wrong if they attempt to fast forward when the video is not playing or fast forward past the end of the video.

Last of all, add the following to the end of the code, to control the time elapsed display:

```js
player.ontimeupdate = () => {
  const minutes = Math.floor(player.currentTime / 60);
  const seconds = Math.floor(player.currentTime - minutes \* 60);
  const minuteValue = minutes < 10 ? `0${minutes}` : minutes;
  const secondValue = seconds < 10 ? `0${seconds}` : seconds;

  const mediaTime = `${minuteValue}:${secondValue}`;
  timeLabel.textContent = mediaTime;
};
```

Each time the time updates (once per second), we fire this function. It works out the number of minutes and seconds from the given currentTime value (which is in seconds), adds a leading 0 if either the minute or second value is less than 10, and then creates the display readout and adds it to the time label.

#### Further reading

This gives you a basic idea of how to add custom player functionality to video/audio player instances. For more information on how to add more complex features to video/audio players, see:

* Audio and video delivery
* Video player styling basics
* Creating a cross-browser video player

We've also created an advanced example to show how you could create an object-oriented system that finds every video and audio player on the page (no matter how many there are) and adds our custom controls to it. See custom-controls-oojs (also see the source code).

Audio transcripts
-----------------

To provide deaf people with access to audio content, you need to create text transcripts. These can either be included on the same page as the audio in some way or included on a separate page and linked to.

In terms of actually creating the transcript, your options are:

* Commercial services — You could pay a professional to do the transcription, see for example companies like Scribie, Casting Words, or Rev. Look around and ask for advice to make sure you find a reputable company that you'll be able to work with effectively.
* Community/grassroots/self transcription — If you are part of an active community or team in your workplace, then you could ask them for help with doing the translations. You could even have a go at doing them yourself.
* Automated services — There are AI services available, like Trint or Transcribear. Upload a video/audio file to the site, and it automatically transcribes it for you. On YouTube, you can choose to generate automated captions/transcripts. Depending on how clear the spoken audio is, the resulting transcript quality will vary greatly.

As with most things in life, you tend to get what you pay for; different services will vary in accuracy and time taken to produce the transcript. If you pay a reputable company or AI service to do the transcription, you will probably get it done rapidly and to a high quality. If you don't want to pay for it, you are likely to get it done at a lower quality, and/or slowly.

It is not OK to publish an audio resource but promise to publish the transcript later on — such promises often aren't kept, which will erode trust between you and your users. If the audio you are presenting is something like a face to face meeting or live spoken performance, it would be acceptable to take notes during the performance, publish them in full along with the audio, then seek help in cleaning up the notes afterward.

### Transcript examples

If you use an automated service, then you'll probably have to use the user interface that the tool provides. For example, take a look at our Wait, ARIA Roles Have Categories? video and choose the three-dot menu (. . .) *> Show Transcript*. You'll see the transcript come up in a separate panel.

If you are creating your own user interface to present your audio and associated transcript, you can do it however you like, but it might make sense to include it in a showable/hideable panel; see our audio-transcript-ui example (also see the source code).

### Audio descriptions

On occasions where visuals are accompanying your audio, you'll need to provide audio descriptions of some kind to describe that extra content.

In many cases, this will take the form of video, in which case you can implement captions using the techniques described in the next section of the article.

However, there are some edge cases. You might for example have an audio recording of a meeting that refers to an accompanying resource such as a spreadsheet or chart. In such cases, you should make sure that the resources are provided along with the audio + transcript, and specifically link to them in the places where they are referred to in the transcript. This of course will help all users, not just people who are deaf.

**Note:** An audio transcript will in general help multiple user groups. As well as giving deaf users access to the information contained in the audio, think about a user with a low bandwidth connection, who would find downloading the audio inconvenient. Think also about a user in a noisy environment like a pub or bar, who is trying to access the information but can't hear it over the noise.

Video text tracks
-----------------

To make video accessible for the deaf, visually impaired, or other groups of users (such as those on low bandwidth, or who don't understand the language the video is recorded in), you need to include text tracks along with your video content.

**Note:** Text tracks are also useful for potentially any user, not just those with disabilities. For example, some users may not be able to hear the audio because they are in noisy environments (like a crowded bar when a sports game is being shown) or might not want to disturb others if they are in a quiet place (like a library).

This is not a new concept — television services have had closed captioning available for quite a long time:

![Frame from an old-timey cartoon with closed captioning "Good work, Goldie. Keep it up!"](/en-US/docs/Learn/Accessibility/Multimedia/closed-captions.png)

Many countries offer English films with subtitles written in their own native languages, and different language subtitles are often available on DVDs, as shown below:

![An English film with German subtitles "Emo, warum erkennst du nicht die Schonheit dieses Ortes?"](/en-US/docs/Learn/Accessibility/Multimedia/subtitles_german.png)

There are different types of text tracks for different purposes. The main ones you'll come across are:

* Captions — There for the benefit of deaf users who can't hear the audio track, including the words being spoken, and contextual information such as who spoke the words, if the people were angry or sad, and what mood the music is currently creating.
* Subtitles — Include translations of the audio dialog, for users that don't understand the language being spoken.
* Descriptions — These include descriptions for visually impaired people who can't see the video, for example, what the scene looks like.
* Chapter titles — Chapter markers intended to help the user navigate the media resource
### Implementing HTML video text tracks

Text tracks for displaying with HTML video need to be written in WebVTT, a text format containing multiple strings of text along with metadata such as what time in the video you want each text string to be displayed, and even limited styling/positioning information. These text strings are called cues.

A typical WebVTT file will look something like this:
```

WEBVTT

1
00:00:22.230 --> 00:00:24.606
This is the first subtitle.

2
00:00:30.739 --> 00:00:34.074
This is the second.

…
```

To get this displayed along with the HTML media playback, you need to:

* Save it as a .vtt file in a sensible place.
* Link to the .vtt file with the `<track>` element. `<track>` should be placed within `<audio>` or `<video>`, but after all `<source>` elements. Use the `kind` attribute to specify whether the cues are subtitles, captions, or descriptions. Furthermore, use `srclang` to tell the browser what language you have written the subtitles in.

Here's an example:

```html
<video controls>
  <source src="example.mp4" type="video/mp4" />
  <source src="example.webm" type="video/webm" />
  <track kind="subtitles" src="subtitles\_en.vtt" srclang="en" />
</video>
```

This will result in a video that has subtitles displayed, kind of like this:

![Video player with standard controls such as play, stop, volume, and captions on and off. The video playing shows a scene of a man holding a spear-like weapon, and a caption reads "Esta hoja tiene pasado oscuro."](/en-US/docs/Learn/Accessibility/Multimedia/video-player-with-captions.png)

For more details, see Adding captions and subtitles to HTML video. You can find the example that goes along with this article on GitHub, written by Ian Devlin (see the source code too.) This example uses JavaScript to allow users to choose between different subtitles. Note that to turn the subtitles on, you need to press the "CC" button and select an option — English, Deutsch, or Español.

**Note:** Text tracks and transcriptions also help you with SEO, since search engines especially thrive on text. Text tracks even allow search engines to link directly to a spot partway through the video.

Test your skills!
-----------------

You've reached the end of this article, but can you remember the most important information?

We've not written a new set of assessments for this article, because there are already assessments available in our HTML Multimedia and embedding module that test your knowledge of the information presented here. If you haven't already, go and try out the assessments at Test your skills: HTML images and Test your skills: Multimedia and embedding.

Summary
-------

This chapter has provided a summary of accessibility concerns for multimedia content, along with some practical solutions.

It is not always easy to make multimedia accessible. If for example, you are dealing with an immersive 3D game or virtual reality app, it is quite difficult to provide text alternatives for such an experience, and you might argue that visually impaired users are not really in the target audience bracket for such apps.

You can however make sure that such an app has good enough color contrast and clear presentation so it is perceivable to those with low vision/color blindness, and also make it keyboard accessible. Remember that accessibility is about doing as much as you can, rather than striving for 100% accessibility all the time, which is often impossible.

* Previous
* Overview: Accessibility
* Next


Test your skills: WAI-ARIA - Learn web development

Test your skills: WAI-ARIA
==========================

The aim of this skill test is to assess whether you've understood our WAI-ARIA basics article.

**Note:** You can try solutions in the interactive editors on this page or in an online editor such as CodePen, JSFiddle, or Glitch.

If you get stuck, you can reach out to us in one of our communication channels.

WAI-ARIA 1
----------

In our first ARIA task, we present you with a section of non-semantic markup, which is obviously meant to be a list. Assuming you are not able to change the elements used, how can you allow screen reader users to recognize this as a list?

Try updating the live code below to recreate the finished example:

Download the starting point for this task to work in your own editor or in an online editor.

WAI-ARIA 2
----------

In our second WAI-ARIA task, we present a simple search form, and we want you to add in a couple of WAI-ARIA features to improve its accessibility:

1. How can you allow the search form to be called out as a separate landmark on the page by screen readers, to make it easily findable?
2. How can you give the search input a suitable label, without explicitly adding a visible text label to the DOM?

Try updating the live code below to recreate the finished example:

Download the starting point for this task to work in your own editor or in an online editor.

WAI-ARIA 3
----------

For this final WAI-ARIA task, we return to an example we previously saw in the CSS and JavaScript skill test. As before, we have a simple app that presents a list of animal names. Clicking one of the animal names causes a further description of that animal to appear in a box below the list. Here, we are starting with a mouse- and keyboard-accessible version.

The problem we have now is that when the DOM changes to show a new description, screen readers cannot see what has changed. Can you update it so that description changes are announced by the screen reader?

Download the starting point for this task to work in your own editor or in an online editor.


Test your skills: CSS and JavaScript accessibility - Learn web development

Test your skills: CSS and JavaScript accessibility
==================================================

The aim of this skill test is to assess whether you've understood our CSS and JavaScript accessibility best practices article.

**Note:** You can try solutions in the interactive editors on this page or in an online editor such as CodePen, JSFiddle, or Glitch.

If you get stuck, you can reach out to us in one of our communication channels.

CSS accessibility 1
-------------------

In the first task you are presented with a list of links. However, their accessibility is pretty bad — there is no way to really tell that they are links, or to tell which one the user is focussed on.

We'd like you to assume that the existing ruleset with the `a` selector is supplied by some CMS, and that you can't change it — instead, you need to create new rules to make the links look and behave like links, and for the user to be able to tell where they are in the list.

Try updating the live code below to recreate the finished example:

Download the starting point for this task to work in your own editor or in an online editor.

CSS accessibility 2
-------------------

In this next task you are presented with a simple bit of content — just headings and paragraphs. There are accessibility issues with the colors and sizing of the text; we'd like you to:

1. Explain what the problems are, and what the guidelines are that state the acceptable values for color and sizing.
2. Select new values for the color and font-size that fix the problem.
3. Update the CSS with these new values to fix the problem.
4. Test the code to make sure the problem is now fixed. Explain what tools or methods you used to select the new values and test the code.

Try updating the live code below to recreate the finished example:

Download the starting point for this task to work in your own editor or in an online editor.

JavaScript accessibility 1
--------------------------

In our final task here, you have some JavaScripting to do. We have a simple app that presents a list of animal names. Clicking one of the animal names causes a further description of that animal to appear in a box below the list.

But it is not very accessible — in its current state you can only operate it with the mouse. We'd like you to add to the HTML and JavaScript to make it keyboard accessible too.

Download the starting point for this task to work in your own editor or in an online editor.


Design and accessibility - Learn web development

Design and accessibility
========================

This section lists questions related to aesthetics, page structure, accessibility techniques, etc.

How do I start to design my website?

This article covers the all-important first step of every project: define what you want to accomplish with it.

What do common web layouts contain?

 When designing pages for your website, it's good to have an idea of the most common layouts. This article runs
 through some typical web layouts, looking at the parts that make up each one.

What is accessibility?

This article introduces the basic concepts behind web accessibility.

How can we design for all types of users?

 This article provides basic techniques to help you design websites for any kind of user — quick accessibility wins,
 and other such things.

What HTML features promote accessibility?

 This article describes specific features of HTML that can be used to make a webpage more accessible to people with
 different disabilities.


Web mechanics - Learn web development

Web mechanics
=============

This section covers questions relating to general knowledge of the web ecosystem and how it works.

How does the Internet work?

 The **Internet** is the backbone of the web, the technical infrastructure that makes the web possible.
 At its most basic, the internet is a massive network of computers communicating with each other. This article
 discusses how it works, in broad terms.

What is the difference between webpage, website, web server, and search engine?

 In this article we describe various web-related concepts: webpages, websites, web servers, and search engines. These
 terms are often a source of confusion for newcomers to the web, or are used incorrectly. Let's discover what they
 actually mean!

What are hyperlinks?

In this article, we'll go over what hyperlinks are and why they matter.

What is a URL?

 With Hypertext and HTTP, URL is a key concept when it comes to the Internet. It is
 the mechanism used by browsers to retrieve any published resource on the web.

What is a domain name?

 Domain names are a key component of the Internet infrastructure. They provide a human-readable address for any web
 server available on the Internet.

What is a web server?

 The term "web server" can refer to the hardware or software that serves websites to clients across the web — or both
 of them working together. In this article we go over how web servers work, and why they're important.


Tools and setup - Learn web development

Tools and setup
===============

This section lists questions related to the tools/software you can use to build websites.

What software do I need to build a website?

In this article we explain which software components you need to edit, upload, or view a website.

How much does it cost to do something on the web?

 When you're launching a website, you may spend nothing or your costs may go through the roof. In this article we
 discuss how much everything costs and what you get for what you pay (or don't pay).

What text editors are available?

 In this article we highlight some things to think about when choosing and installing a text editor for web
 development.

What are browser developer tools?

 Every browser features a set of devtools for debugging HTML, CSS, and other web code. This article explains how to
 use the basic functions of your browser's devtools.

How do you make sure your website works properly?

 So you've published your website online — very good! But are you sure it works properly? This article provides some
 basic troubleshooting steps.

How do you set up a local testing server?

This article explains how to set up a simple local testing server on your machine, and the basics of how to use it.

How do you upload files to a web server?

This article shows how to publish your site online with FTP tools — one of the most common ways to get a website online so others can access it from their computers.

How do I use GitHub Pages?

This article provides a basic guide to publishing content using GitHub's gh-pages feature.

How do you host your website on Google App Engine?

Looking for a place to host your website? Here's a step-by-step guide to hosting your website on Google App Engine.

What tools are available to debug and improve website performance?

 This set of articles shows you how to use the Developer Tools in Firefox to debug and improve performance of your
 website, using the tools to check memory usage, the JavaScript call tree, the number of DOM nodes being rendered, and
 more.


How do you upload your files to a web server? - Learn web development

How do you upload your files to a web server?
=============================================

This article shows you how to publish your site online using file transfer tools.

|  |  |
| --- | --- |
| Prerequisites: |
 You must know
 what a web server is
 and
 how domain names work. You must also know how to
 set up a basic environment
 and how to
 write a simple webpage.
  |
| Objective: |
 Learn how to push files to a server using the various file transfer
 tools available.
  |

Summary
-------

If you have built a simple web page (see HTML basics for an example), you will probably want to put it online, on a web server. In this article we'll discuss how to do that, using various available options such as SFTP clients, RSync and GitHub.

SFTP
----

There are several SFTP clients out there. Our demo covers FileZilla, since it's free and available for Windows, macOS and Linux. To install FileZilla go to the FileZilla downloads page, click the big Download button, then install from the installer file in the usual way.

**Note:** Of course there are lots of other options. See Publishing tools for more information.

Open the FileZilla application; you should see something like this:

![Screenshot of the user interface of Filezilla FTP application. Host input has focus.](/en-US/docs/Learn/Common_questions/Tools_and_setup/Upload_files_to_a_web_server/filezilla-ui.png)

### Logging in

For this example, we'll suppose that our hosting provider (the service that will host our HTTP web server) is a fictitious company "Example Hosting Provider" whose URLs look like this: `mypersonalwebsite.examplehostingprovider.net`.

We have just opened an account and received this info from them:

>
> Congratulations for opening an account at Example Hosting Provider.
>
>
> Your account is: `demozilla`
>
>
> Your website will be visible at `demozilla.examplehostingprovider.net`
>
>
> To publish to this account, please connect through SFTP with the following credentials:
>
>
> * SFTP server: `sftp://demozilla.examplehostingprovider.net`
> * Username: `demozilla`
> * Password: `quickbrownfox`
> * Port: `5548`
> * To publish on the web, put your files into the `Public/htdocs` directory.
>
>
>

Let's first look at `http://demozilla.examplehostingprovider.net/` — as you can see, so far there is nothing there:

![Our demozilla personal website, seen in a browser: it's empty](/en-US/docs/Learn/Common_questions/Tools_and_setup/Upload_files_to_a_web_server/demozilla-empty.png)

**Note:** Depending on your hosting provider, most of the time you'll see a page saying something like "This website is hosted by [Hosting Service]." when you first go to your web address.

To connect your SFTP client to the distant server, follow these steps:

1. Choose *File > Site Manager…* from the main menu.
2. In the *Site Manager* window, press the *New Site* button, then fill in the site name as **demozilla** in the provided space.
3. Fill in the SFTP server your host provided in the *Host:* field.
4. In the *Logon Type:* drop down, choose *Normal*, then fill in your provided username and password in the relevant fields.
5. Fill in the correct port and other information.

Your window should look something like this:

![Screenshot of default landing page of a fictitious website when the file directory is empty](/en-US/docs/Learn/Common_questions/Tools_and_setup/Upload_files_to_a_web_server/site-manager.png)

Now press *Connect* to connect to the SFTP server.

Note: Make sure your hosting provider offers SFTP (Secure FTP) connection to your hosting space. FTP is inherently insecure, and you shouldn't use it.

### Here and there: local and remote view

Once connected, your screen should look something like this (we've connected to an example of our own to give you an idea):

![SFTP client displaying website contents once it has been connected to the SFTP server. Local files are on the left. Remote files are on the right.](/en-US/docs/Learn/Common_questions/Tools_and_setup/Upload_files_to_a_web_server/connected.png)

Let's examine what you're seeing:

* On the center left pane, you see your local files. Navigate into the directory where you store your website (e.g. `mdn`).
* On the center right pane, you see remote files. We are logged into our distant FTP root (in this case, `users/demozilla`)
* You can ignore the bottom and top panes for now. Respectively, these are a log of messages showing the connection status between your computer and the SFTP server, and a live log of every interaction between your SFTP client and the server.
### Uploading to the server

Our example host instructions told us "To publish on the web, put your files into the `Public/htdocs` directory." You need to navigate to the specified directory in your right pane. This directory is effectively the root of your website — where your `index.html` file and other assets will go.

Once you've found the correct remote directory to put your files in, to upload your files to the server you need to drag-and-drop them from the left pane to the right pane.

### Are they really online?

So far, so good, but are the files really online? You can double-check by going back to your website (e.g. `http://demozilla.examplehostingprovider.net/`) in your browser:

![Here we go: our website is live!](/en-US/docs/Learn/Common_questions/Tools_and_setup/Upload_files_to_a_web_server/here-we-go.png)

And our website is live!

Rsync
-----

Rsync is a local-to-remote file synchronizing tool, which is generally available on most Unix-based systems (like macOS and Linux), but Windows versions exist too.

It is seen as a more advanced tool than SFTP, because by default it is used on the command line. A basic command looks like this:

```bash
rsync [-options] SOURCE user@x.x.x.x:DESTINATION
```

* `-options` is a dash followed by a one or more letters, for example `-v` for verbose error messages, and `-b` to make backups. You can see the full list at the rsync man page (search for "Options summary").
* `SOURCE` is the path to the local file or directory that you want to copy files over from.
* `user@` is the credentials of the user on the remote server you want to copy files over to.
* `x.x.x.x` is the IP address of the remote server.
* `DESTINATION` is the path to the location you want to copy your directory or files to on the remote server.

You'd need to get such details from your hosting provider.

For more information and further examples, see How to Use Rsync to Copy/Sync Files Between Servers.

Of course, it is a good idea to use a secure connection, as with FTP. In the case of Rsync, you specify SSH details to make the connection over SSH, using the `-e` option. For example:

```bash
rsync [-options] -e "ssh [SSH DETAILS GO HERE]" SOURCE user@x.x.x.x:DESTINATION
```

You can find more details of what is needed at How To Copy Files With Rsync Over SSH.

### Rsync GUI tools

GUI tools are available for Rsync (for those who are not as comfortable using the command line). Acrosync is one such tool, and it is available for Windows and macOS.

Again, you would have to get the connection credentials from your hosting provider, but this way you'd have a GUI to enter them in.

GitHub
------

GitHub allows you to publish websites via GitHub pages (gh-pages).

We've covered the basics of using this in the Publishing your website article from our Getting started with the Web guide, so we aren't going to repeat it all here.

However, it is worth knowing that you can also host a website on GitHub, but use a custom domain with it. See Using a custom domain with GitHub Pages for a detailed guide.

Other methods to upload files
-----------------------------

The FTP protocol is one well-known method for publishing a website, but not the only one. Here are a few other possibilities:

* **Web interfaces**. An HTML interface acting as front-end for a remote file upload service. Provided by your hosting service.
* **WebDAV**. An extension of the HTTP protocol to allow more advanced file management.


How do you set up a local testing server? - Learn web development

How do you set up a local testing server?
=========================================

This article explains how to set up a simple local testing server on your machine, and the basics of how to use it.

|  |  |
| --- | --- |
| Prerequisites: |
 You need to first know
 how the Internet works, and
 what a Web server is.
  |
| Objective: | You will learn how to set up a local testing server. |

Local files vs. remote files
----------------------------

Throughout most of the learning area, we tell you to just open your examples directly in a browser — this can be done by double-clicking the HTML file, dragging and dropping it into the browser window, or choosing *File* > *Open…* and navigating to the HTML file. There are many ways to achieve this.

If the web address path starts with `file://` followed by the path to the file on your local hard drive, a local file is being used. In contrast, if you view one of our examples hosted on GitHub (or an example on some other remote server), the web address will start with `http://` or `https://`, to show that the file has been received via HTTP.

The problem with testing local files
------------------------------------

Some examples won't run if you open them as local files. This can be due to a variety of reasons, the most likely being:

* **They feature asynchronous requests**. Some browsers (including Chrome) will not run async requests (see Fetching data from the server) if you just run the example from a local file. This is because of security restrictions (for more on web security, read Website security).
* **They feature a server-side language**. Server-side languages (such as PHP or Python) require a special server to interpret the code and deliver the results.
* **They include other files**. Browsers commonly treat requests to load resources using the `file://` schema as cross-origin requests.
 So if you load a local file that includes other local files, this may trigger a CORS error.
Running a simple local HTTP server
----------------------------------

To get around the problem of async requests, we need to test such examples by running them through a local web server.

### Using an extension in your code editor

If you only need HTML, CSS and JavaScript, and no server-side language, the easiest way may be to check for extensions in your code editor. As well as automating installation and set-up for your local HTTP server, they also integrate nicely with your code editors. Testing local files in an HTTP server may be one click away.

For VSCode, you can check the following free extension:

* `vscode-preview-server`. You can check it on its home page.
### Using Python

Another way to achieve this is to use Python's `http.server` module.

**Note:** Older versions of Python (up to version 2.7) provided a similar module named `SimpleHTTPServer`. If you are using Python 2.x, you can follow this guide by replacing all uses of `http.server` with `SimpleHTTPServer`. However, we recommend you use the latest version of Python.

To do this:

1. Install Python. If you are using Linux or macOS, it should be available on your system already. If you are a Windows user, you can get an installer from the Python homepage and follow the instructions to install it:
    * Go to python.org
    * Under the Download section, click the link for Python "3.xxx".
    * At the bottom of the page, click the *Windows Installer* link to download the installer file.
    * When it has downloaded, run it.
    * On the first installer page, make sure you check the "Add Python 3.xxx to PATH" checkbox.
    * Click *Install*, then click *Close* when the installation has finished.
2. Open your command prompt (Windows) / terminal (macOS/ Linux). To check if Python is installed, enter the following command:

```bash
python -V
# If the above fails, try:
python3 -V
# Or, if the "py" command is available, try:
py -V
```

3. This should return a version number. If this is OK, navigate to the directory that contains the website code you want to test, using the `cd` command.

```bash
# include the directory name to enter it, for example
cd Desktop
# use two dots to jump up one directory level if you need to
cd ..
```

4. Enter the command to start up the server in that directory:

```bash
# If Python version returned above is 3.X
# On Windows, try "python -m http.server" or "py -3 -m http.server"
python3 -m http.server
# If Python version returned above is 2.X
python -m SimpleHTTPServer
```

5. By default, this will run the contents of the directory on a local web server, on port 8000. You can go to this server by going to the URL `localhost:8000` in your web browser. Here you'll see the contents of the directory listed — click the HTML file you want to run.

**Note:** If you already have something running on port 8000, you can choose another port by running the server command followed by an alternative port number, e.g. `python3 -m http.server 7800` (Python 3.x) or `python -m SimpleHTTPServer 7800` (Python 2.x). You can then access your content at `localhost:7800`.

Running server-side languages locally
-------------------------------------

Python's `http.server` (or `SimpleHTTPServer` for Python 2) module is useful, but it is merely a *static* file server; it doesn't know how to run code written in languages such as Python, PHP or JavaScript. To handle them, you'll need something more — exactly what you'll need depends on the server-side language you are trying to run. Here are a few examples:

* To run Python server-side code, you'll need to use a Python web framework. There are many popular Python web frameworks, such as Django (a guide is available), Flask, and Pyramid.
* To run Node.js (JavaScript) server-side code, you'll need to use raw node or a framework built on top of it. Express is a good choice — see Express Web Framework (Node.js/JavaScript).
* To run PHP server-side code, launch PHP's built-in development server:

```bash
cd path/to/your/php/code
php -S localhost:8000
```


How do I use GitHub Pages? - Learn web development

How do I use GitHub Pages?
==========================

GitHub is a "social coding" site. It allows you to upload code repositories for storage in the Git **version control system.** You can then collaborate on code projects, and the system is open-source by default, meaning that anyone in the world can find your GitHub code, use it, learn from it, and improve on it. You can do that with other people's code too! This article provides a basic guide to publishing content using GitHub's gh-pages feature.

Publishing content
------------------

GitHub is a very important and useful community to get involved in, and Git/GitHub is a very popular version control system — most tech companies now use it in their workflow. GitHub has a very useful feature called GitHub Pages, which allows you to publish website code live on the Web.

### Basic GitHub setup

1. First of all, install Git on your machine. This is the underlying version control system software that GitHub works on top of.
2. Next, sign up for a GitHub account. It's simple and easy.
3. Once you've signed up, log in to github.com with your username and password.
### Preparing your code for upload

You can store any code you like in a GitHub repository, but to use the GitHub Pages feature to full effect, your code should be structured as a typical website, e.g. with the primary entry point being an HTML file called `index.html`.

The other thing you need to do before moving on is to initialise your code directory as a Git repository. To do this:

1. Point the command line to your `test-site` directory (or whatever you called the directory containing your website). For this, use the `cd` command (i.e. "**c**hange **d**irectory"). Here's what you'd type if you've put your website in a directory called `test-site` on your desktop:

```bash
cd Desktop/test-site
```

2. When the command line is pointing inside your website directory, type the following command, which tells the `git` tool to turn the directory into a git repository:

```bash
git init
```

#### An aside on command line interfaces

The best way to upload your code to GitHub is via the command line — this is a window where you type in commands to do things like create files and run programs, rather than clicking inside a user interface. It will look something like this:

![Terminal/command prompt opened. No command has been entered.](/en-US/docs/Learn/Common_questions/Tools_and_setup/Using_GitHub_pages/command-line.png)

**Note:** You could also consider using a Git graphical user interface to do the same work, if you feel uncomfortable with the command line.

Every operating system comes with a command line tool:

* **Windows**: **Command Prompt** can be accessed by pressing the Windows key, typing *Command Prompt*, and choosing it from the list that appears. Note that Windows has its own command conventions differing from Linux and macOS, so the commands below may vary on your machine.
* **OS X**: **Terminal** can be found in *Applications > Utilities*.
* **Linux**: Usually you can pull up a terminal with *Ctrl + Alt + T*. If that doesn't work, look for **Terminal** in an app bar or menu.

This may seem a bit scary at first, but don't worry — you'll soon get the hang of the basics. You tell the computer to do something in the terminal by typing in a command and hitting Enter, as seen above.

### Creating a repo for your code

1. Next, you need to create a new repo for your files to go in. Click Plus (+) in the top right of the GitHub homepage, then choose *New Repository*.
2. On this page, in the *Repository name* box, enter a name for your code repository, for example *my-repository*.
3. Also fill in a description to say what your repository is going to contain. Your screen should look like this:

 ![New repository page opened in browser, repository owner input and the repository name are filled, same for the optional description input. The public check-box is selected, the private check-box is not, same goes for the initialize this repository with a readme.](/en-US/docs/Learn/Common_questions/Tools_and_setup/Using_GitHub_pages/create-new-repo.png)
4. Click *Create repository*; this should bring you to the following page:

 ![The repository page is opened in browser, below the GitHub header composed of search bar and navigation links to the repository's pull request, issues and gist. Next to the navigation links, a bell notification and a link to your account. Below, the name of the owner's repository follow by a slash with the repository's name. Below a horizontal navigation bar composed of different tabs relating to your repository, the code tab selected displaying a documentation explaining how to create a repository or how to push from using command line.](/en-US/docs/Learn/Common_questions/Tools_and_setup/Using_GitHub_pages/github-repo.png)
### Uploading your files to GitHub

1. On the current page, you are interested in the section *…or push an existing repository from the command line*. You should see two lines of code listed in this section. Copy the whole of the first line, paste it into the command line, and press Enter. The command should look something like this:

```bash
git remote add origin https://github.com/chrisdavidmills/my-repository.git
```

2. Next, type the following two commands, pressing Enter after each one. These prepare the code for uploading to GitHub, and ask Git to manage these files.

```bash
git add --all
git commit -m 'adding my files to my repository'
```

3. Finally, push the code up to GitHub by going to the GitHub web page you're on and entering into the terminal the second of the two commands we saw the *…or push an existing repository from the command line* section:

```bash
git push -u origin main
```

4. Now you need to turn GitHub pages on for your repository. To do this, from the homepage of your repository choose *Settings*, then select *Pages* from the sidebar on the left. Underneath *Source*, choose the "main" branch. The page should refresh.
5. Go to the GitHub Pages section again, and you should see a line of the form "Your site is ready to be published at `https://xxxxxx`."
6. If you click on this URL, you should go to a live version of your example, provided the home page is called `index.html` — it goes to this entry point by default. If your site's entry point is called something else, for example `myPage.html`, you'll need to go to `https://xxxxxx/myPage.html`.
### Further GitHub knowledge

If you want to make more changes to your test site and upload those to GitHub, you need to make the change to your files just like you did before. Then, you need to enter the following commands (pressing Enter after each one) to push those changes to GitHub:

```bash
git add --all
git commit -m 'another commit'
git push
```

You can replace *another commit* with a more suitable message to describe what change you just made.

We have barely scratched the surface of Git. To learn more, check out our Git and GitHub page.


What software do I need to build a website? - Learn web development

What software do I need to build a website?
===========================================

In this article, we lay out which software components you need when you're editing, uploading, or viewing a website.

|  |  |
| --- | --- |
| Prerequisites: |
 You should already know
 the difference between webpages, websites, web servers, and search
engines. |
| Objective: |
 Learn which software components you need if you want to edit, upload, or
 view a website.
  |

Summary
-------

You can download most of the programs you need for web development for free. We'll provide a few links in this article.

You'll need tools to:

* Create and edit webpages
* Upload files to your web server
* View your website

Nearly all operating systems by default include a text editor and a browser, which you can use to view websites. As a result, you usually only need to acquire software for transferring files to your web server.

Active Learning
---------------

*There is no active learning available yet. Please, consider contributing.*

Dig deeper
----------

### Creating and editing webpages

To create and edit a website, you need a text editor. Text editors create and modify unformatted text files. Other formats, like **RTF**, let you add formatting, like bold or underline. Those formats are not suitable for writing web pages. You should put some thought into which text editor you use, since you'll be working with it extensively while you're building the website.

All desktop operating systems come with a basic text editor. These editors are all straightforward, but lack special features for webpage coding. If you want something a bit fancier, there are plenty of third-party tools available. Third-party editors often come with extra features, including syntax coloring, auto-completion, collapsible sections, and code search. Here is a short list of editors:

| Operating system | Built-in editor | Third-party editor |
| --- | --- | --- |
| Windows | * Notepad
 | * Notepad++
* Visual Studio Code
* Web Storm
* Brackets
* ShiftEdit
* Sublime Text
 |
| Mac OS | * TextEdit
 | * TextWrangler
* Visual Studio Code
* Brackets
* ShiftEdit
* Sublime Text
 |
| Linux | * Vi
 (All UNIX)
* GEdit
 (Gnome)
* Kate
 (KDE)
* LeafPad
 (Xfce)
 | * Emacs
* Vim
* Visual Studio Code
* Brackets
* ShiftEdit
* Sublime Text
 |
| ChromeOS |  | * ShiftEdit
 |

Here is a screenshot of an advanced text editor:

![Screenshot of Notepad++.](/en-US/docs/Learn/Common_questions/Tools_and_setup/What_software_do_I_need/notepadplusplus.png)

Here is a screenshot of an online text editor:

![Screenshot of ShiftEdit](/en-US/docs/Learn/Common_questions/Tools_and_setup/What_software_do_I_need/shiftedit.png)

### Uploading files on the Web

When your website is ready for public viewing, you'll have to upload your webpages to your web server. You can buy space on a server from various providers (see How much does it cost to do something on the web?). Once you settle on which provider to use, the provider will email you the access information, usually in the form of an SFTP URL, username, password, and other information needed to connect to their server. Bear in mind that (S)FTP is now somewhat old-fashioned, and other uploading systems are starting to become popular, such as RSync and Git/GitHub.

**Note:** FTP is inherently insecure. You should make sure your hosting provider allows use of a secure connection, e.g. SFTP or RSync over SSH.

Uploading files to a web server is a very important step while creating a website, so we cover it in detail in a separate article. For now, here's a short list of free basic (S)FTP clients:

| Operating system | FTP software |
| --- | --- |
| Windows | * WinSCP
* Moba Xterm
 | * FileZilla (All OS)
 |
| Linux | * Nautilus/Files
 (Gnome)
* Dolphin (KDE)
 |
| Mac OS | * Cyberduck
 |
| ChromeOS | * ShiftEdit (All OS)
 |  |

### Browsing websites

As you already know, you need a web browser to view websites. There are dozens of browser options for your personal use, but when you're developing a website you should test it at least with the following major browsers, to make sure your site works for most people:

* Mozilla Firefox
* Google Chrome
* Apple Safari

If you're targeting a specific group (e.g., technical platform or country), you may have to test the site with additional browsers, like Opera, Konqueror.

 Testing gets complicated because some browsers only run on certain operating systems. Apple Safari runs on iOS and macOS, while Internet Explorer runs only on Windows. It's best to take advantage of services like Browsershots or Browserstack. Browsershots furnishes screenshots of your website as it will look in various browsers. Browserstack gives you full remote access to virtual machines, so you can test your site in the most common environments and on different operating systems. Alternatively, you can set up your own virtual machines, but that takes some expertise.
 See Strategies for carrying out testing: Putting together a testing lab for more information.

By all means run some tests on a real device, especially on real mobile devices. Mobile device simulation is a new, evolving technology and less reliable than desktop simulation. Mobile devices cost money, of course, so we suggest taking a look at the Open Device Lab initiative. You can also share devices if you want to test on many platforms without spending too much.

Next steps
----------

* Some of this software is free, but not all of it. Find out how much it costs to do something on the web.
* If you'd like to learn more about text editors, read our article about how to choose and install a text editor.
* If you're wondering how to publish your website on the web, look at "How to upload files to a web server".