Accessibility / Markdown Parsing

DANA 325 U D T G W C K E M X S A Q L R B H J P F O N V I

Objectives

  • Description, code sample, and example from your code presented in markdown. (1 Point)

  • Description, code sample, and example from your code presented in markdown. (1 Point)

  • Description, code sample, and example from your code presented in markdown. (1 Point)

  • Description, code sample, and example from your code presented in markdown. (1 Point)

  • Description, code sample, and example from your code presented in markdown. (1 Point)

  • Description, code sample, and example from your code presented in markdown. (1 Point)

  • Description, code sample, and example from your code presented in markdown. (1 Point)

Please watch the videos under Resources before class.

You objective is to create a page that demonstrates at least 7 leassons learned in regards to acessibility.

Your page should be hosted under /accessiblility.

To get you started here is an example of how this could look like:

Always use labels for form inputs

A label can be separate from a form input. In this case the label should be linked with the form input via id and for:

<label for="user_name">Name</label>
<input type="text" name="user[name]" id="user_name">

A label can also wrap a form input. In this case the id and for attributes are not needed. But everything within <label> </label> is considered part of the label.

<label>
Name
<input type="text" name="user[name]">
</label>

Here is an example from my code that correctly uses a label:

def input(%{type: "select"} = assigns) do
~H"""
<div class={@wrapper_class}>
<.label :if={@label} for={@id} class="block mb-2">{@label}</.label>
<select
id={@id}
name={@name}
class={[
"bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white phx-no-feedback:focus:ring-blue-500 phx-no-feedback:focus:border-blue-500 phx-no-feedback:dark:focus:ring-blue-500 phx-no-feedback:dark:focus:border-blue-500",
@errors == [] &&
"focus:ring-blue-500 focus:border-blue-500 dark:focus:ring-blue-500 dark:focus:border-blue-500",
@errors != [] &&
"focus:ring-red-500 focus:border-red-500 dark:focus:ring-red-500 dark:focus:border-red-500"
]}
multiple={@multiple}
{@rest}
>
<option :if={@prompt} value="">{@prompt}</option>
{Phoenix.HTML.Form.options_for_select(@options, @value)}
</select>
<.error :for={msg <- @errors}>{msg}</.error>
</div>
"""
end

You should be independently research 7 more accessibility "rules" and describe them with a code snippet and a paragraph as well as an example from your code base! Don't forget a heading.

To format code a little better we will be using markdown.

Getting formatted markdown to show

Have you ever wondered how i make code snippets appear formatted like on the course website? We are going to learn this now.

Lets start by adding a new dependency in mix.ex:

{:mdex, "~> 0.2"},

After refetching our dependencies, wew also want to create a new live view (and an appropriate route to it in the router.ex):

defmodule AppWeb.AccessibilityLive do
use AppWeb, :live_view
@impl true
def render(assigns) do
~H"""
<article class="mt-4 format dark:format-invert max-w-full">
{@page_content}
</article>
"""
end
@impl true
def mount(_params, _session, socket) do
# get markdown content from file
case File.read(Path.join([:code.priv_dir(:app), "accessibility.md"])) do
{:ok, content} ->
content =
content
|> MDEx.to_html!(render: [unsafe_: true], features: [sanitize: false])
|> raw()
{:ok, assign(socket, :page_content, content)}
{:error, _} ->
{:ok, socket
|> put_flash(:error, "Page content could not be loaded.")
|> assign(:page_content, nil)}
end
end
end

This will read the content of priv/accessibility.md, format it into markdown and ensure it is not santitized (so we can display the content as actual HTML). Finally it will assign it to page_content. In case the file doesn't exist or can't load for any other reason an error message should display.

All that is left to do is add a accessibility.md file in our /priv folder. Here is a starting template:

### Accessibility Concern 1 (TODO: rename)
TODO: Description...
```elixir
# This would display formatted elixir code
IO.inspect("Hello World")
```. TODO: change this line to simply: ```
TODO: More description...
```heex
# This would display formatted embedded elixir and html code
<span>{@content}</span>
```. TODO: change this line to simply: ```
#### Sample from my code
TODO: add a sample from my own code
### Accessibility Concern 2 (TODO: rename)
### Accessibility Concern 3 (TODO: rename)
### Accessibility Concern 4 (TODO: rename)
### Accessibility Concern 5 (TODO: rename)
### Accessibility Concern 6 (TODO: rename)
### Accessibility Concern 7 (TODO: rename)

This should display the same syntax-highlighted code and text that you observe on the course website.

Formatting HTML Content

The Flowbite Library has a section Typography. This allows us to apply a format class which automatically updates all html elements inside the container. For example:

<article class="format">
<h1></h1>
</article>

To enable this we will need to add the flowbite library as a npm dependency. Run the following commands:

cd assets
npm install flowbite flowbite-typography
cd ..

If you don't have npm/node installed in your system yet (WSL or OS Mac) do a quick internet research on how to install it.

Afterwards make the following change to your tailwind.config.js file:

plugins: [
require('flowbite-typography'), // <= ADD THIS
// ...
Copyright © 2025 Alexander Fuchsberger, Bucknell University. All rights reserved.