Tessa Kelly
Engineer at NoRedInk
@t_kelly9
Tessa Kelly
Engineer at NoRedInk
@t_kelly9
Follow along with these slides at:
slides.com/tessak/elm/live
Web Content Accessibility Guidelines
Accessible Rich Internet Applications
W3C Candidate Recommendation
https://www.w3.org/TR/wai-aria-1.1
https://slides.com/tessak/elm/live
(just in case)
tesk9/elm-html-a11y
-- elm-lang/html design patterns
import Html
import Html.Attributes
-- tesk9/elm-html-a11y design patterns
import Html.A11y
import Html.Attributes.A11y
-- elm-lang/html design patterns
img : List (Html.Attribute msg) -> List (Html msg) -> Html msg
-- tesk9/elm-html-a11y design patterns
img : String -> List (Html.Attribute msg) -> Html msg
decorativeImg : List (Html.Attribute msg) -> Html msg
-- tesk9/elm-html-a11y design patterns
autoCompleteInline : Attribute msg
autoCompleteList : Attribute msg
autoCompleteBoth : Attribute msg
tesk9/accessible-html
-- tesk9/elm-html-a11y design patterns
import Html.A11y
import Html.Attributes.A11y
-- tesk9/accessible-html design patterns
import Accessibility
import Accessibility.Aria
import Accessibility.Key
import Accessibility.Landmark
import Accessibility.Live
import Accessibility.Role
import Accessibility.Style
-- elm-lang/html design patterns
img : List (Html.Attribute msg) -> List (Html msg) -> Html msg
-- tesk9/elm-html-a11y design patterns
img : String -> List (Html.Attribute msg) -> Html msg
-- tesk9/accessible-html design patterns
img : String -> List (Html.Attribute Never) -> Html msg
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
main : Platform.Program Basics.Never Bool Bool
...
view : Bool -> Html Bool
view showTooltip =
div [ class "tooltip-container" ]
[ div
[ class "inexplicable-content"
, onMouseEnter True
, onMouseLeave False
]
[]
, if showTooltip then
div [ class "tooltip" ]
[ text "Rainbow linear gradient nonsense!!!" ]
else
text ""
]
https://ellie-app.com/8Sm5LkL4Qa1/0
import Accessibility
import Accessibility.Aria exposing (describedBy)
import Accessibility.Role exposing (toolTip)
view showTooltip =
div [ class "tooltip-container" ]
[ div
[ class "inexplicable-content"
, describedBy [ "awesome-tooltip-numbah-1" ]
, onMouseEnter True
, onMouseLeave False
]
[]
, if showTooltip then
div
[ id "awesome-tooltip-numbah-1"
, class "tooltip"
, toolTip
]
[ text "Rainbow linear gradient nonsense!!!" ]
else
text ""
]
https://ellie-app.com/8c6ts4XVwa1/1
import Accessibility.Role exposing (progressBar)
import Accessibility.Widget exposing (valueMax, valueMin, valueNow)
import Html.Attributes exposing (..)
div
[ progressBar
, valueMin 0
, valueMax 100
, valueNow 30
, style
[ ( "width", "160px" )
, ( "height", "10px" )
, ( "background-color", "gray" )
]
]
[ div
[ style
[ ( "width", "30%" )
, ( "height", "100%" )
, ( "background-color", "blue" )
]
]
[]
]
import Html exposing (..)
import Html.Attributes exposing (..)
progressBarElement : Html msg
progressBarElement =
progress [ value "30", Html.Attributes.max "100" ] []
import Accessibility.Key exposing (escape, onKeyDown, space, tabbable)
view showTooltip =
div [ class "tooltip-container" ]
[ div
[ class "inexplicable-content"
, tabbable True
, describedBy [ "awesome-tooltip-numbah-1" ]
, onFocus True
, onBlur False
, onKeyDown [ space True, escape False ]
, onMouseEnter True
, onMouseLeave False
]
[]
, if showTooltip then
div
[ id "awesome-tooltip-numbah-1"
, class "tooltip"
, toolTip
]
[ text "Rainbow linear gradient nonsense!!!" ]
else
text ""
]
https://ellie-app.com/gQVkWBbWya1/0
https://ellie-app.com/bLyG86crKa1/1
https://ellie-app.com/bLyG86crKa1/2
import Html exposing (Html, div)
import Html.Attributes exposing (class, tabindex)
main : Html msg
main =
div
[ class "container" ]
[ div [ class "tabbable-div", tabindex 1 ] []
, div [ class "tabbable-div", tabindex 2 ] []
, div [ class "tabbable-div", tabindex 3 ] []
, div [ class "tabbable-div", tabindex 4 ] []
, div [ class "tabbable-div", tabindex 4 ] []
, div [ class "tabbable-div", tabindex 3 ] []
, div [ class "tabbable-div", tabindex 2 ] []
, div [ class "tabbable-div", tabindex 1 ] []
]
-- module Accessibility.Role
tab : Attribute msg
tabList : Attribute msg
tabPanel : Attribute msg
-- module Accessibility.Key
tabbable : Attribute msg
onKeyDown : List (Json.Decoder msg) -> Attribute msg
left : msg -> Json.Decoder msg
right : msg -> Json.Decoder msg
-- module Accessibility.Aria
controls : String -> Html.Attribute msg
labelledBy : String -> Html.Attribute msg
labeledBy : String -> Html.Attribute msg
-- module Accessibility.Widget
selected : Bool -> Html.Attribute msg
import Accessibility exposing (Html, div, text)
import Accessibility.Aria exposing (controls, labelledBy)
import Accessibility.Key
exposing
( left
, onKeyDown
, right
, tabbable
)
import Accessibility.Role exposing (tab, tabList, tabPanel)
import Accessibility.Widget exposing (selected)
import Html.Attributes exposing (hidden, id)
import Html.Events exposing (onClick)
-- A tab:
div
[ id "tab-0", controls "panel-0", tab, tabbable True ]
[ text "Tab 0" ]
-- That tab's associated panel:
div
[ id "panel-0", labelledBy "tab-0", tabPanel ]
[ text "Panel 0" ]
[ div [ tabList ]
[ div
[ id "tab-0", controls "panel-0", tab, tabbable True ]
[ text "Tab 0" ]
, div
[ id "tab-1", controls "panel-1", tab, tabbable True ]
[ text "Tab 1" ]
, div
[ id "tab-2", controls "panel-2", tab, tabbable True ]
[ text "Tab 2" ]
]
, div [ id "panel-0", labelledBy "tab-0", tabPanel ]
[ text "Panel 0" ]
, div [ id "panel-1", labelledBy "tab-1", tabPanel ]
[ text "Panel 1" ]
, div [ id "panel-2", labelledBy "tab-2", tabPanel ]
[ text "Panel 2" ]
]
https://ellie-app.com/4bVqFGffMa1/0
-- module Accessibility
tabList : List (Attribute Never) -> List (Html msg) -> Html msg
tab : List (Attribute msg) -> List (Html msg) -> Html msg
tabPanel : List (Attribute Never) -> List (Html msg) -> Html msg
[ div [ tabList ]
[ div
[ id "tab-0", controls "panel-0", tab, tabbable True ]
[ text "Tab 0" ]
, div
[ id "tab-1", controls "panel-1", tab, tabbable True ]
[ text "Tab 1" ]
, div
[ id "tab-2", controls "panel-2", tab, tabbable True ]
[ text "Tab 2" ]
]
, div [ id "panel-0", labelledBy "tab-0", tabPanel ]
[ text "Panel 0" ]
, div [ id "panel-1", labelledBy "tab-1", tabPanel ]
[ text "Panel 1" ]
, div [ id "panel-2", labelledBy "tab-2", tabPanel ]
[ text "Panel 2" ]
]
[ tabList []
[ tab [ id "tab-0", controls "panel-0" ] [ text "Tab 0" ]
, tab [ id "tab-1", controls "panel-1" ] [ text "Tab 1" ]
, tab [ id "tab-2", controls "panel-2" ] [ text "Tab 2" ]
]
, tabPanel [ id "panel-0", labelledBy "tab-0" ]
[ text "Panel 0" ]
, tabPanel [ id "panel-1", labelledBy "tab-1" ]
[ text "Panel 1" ]
, tabPanel [ id "panel-2", labelledBy "tab-2" ]
[ text "Panel 2" ]
]
type Msg
= Left
| Right
| ById Int
viewTab : ( Int, Bool ) -> Html Msg
viewTab (tabId, isCurrent) =
tab
[ id ("tab-" ++ toString tabId)
, controls ("panel-" ++ toString tabId)
, selected isCurrent
, onClick (ById tabId)
, onKeyDown [ right Right, left Left ]
]
[ text ("Tab " ++ toString tabId) ]
type Msg
= Left
| Right
| ById Int
viewTab : ( Int, Bool ) -> Html Msg
viewPanel : ( Int, Bool ) -> Html Msg
viewPanel ( panelId, isCurrent ) =
tabPanel
[ id ("panel-" ++ toString panelId)
, labelledBy ("tab-" ++ toString panelId)
, hidden (not isCurrent)
]
[ text ("Panel " ++ toString panelId) ]
https://ellie-app.com/4bVqFGffMa1/1
[aria-selected="true"] {
border: 1px solid purple;
background-color: pink;
}
By Lucarelli (Own work) [GFDL (http://www.gnu.org/copyleft/fdl.html), via Wikimedia Commons
https://commons.wikimedia.org/wiki/File%3AGatto_Piccolo_3.jpg
tesk9/accessible-html
tesk9/accessible-html
@t_kelly9