Add a link to skip to the main content
While people using screen readers already have keyboard shortcuts to jump to the <main> tag, there are people who navigate the page with the keyboard using just the tab key, and for them, this link provides a way to save time and start reading the main content instead of having to manually go through all the navigation links every time a new page is loaded. Note that we had to add an additional `width: 0` rule because Foundation's `element-invisible` would apply `1px` and the test checking for `visible: :hidden` would faile.
This commit is contained in:
22
app/assets/stylesheets/layout/skip_to_main_content.scss
Normal file
22
app/assets/stylesheets/layout/skip_to_main_content.scss
Normal file
@@ -0,0 +1,22 @@
|
||||
.skip-to-main-content {
|
||||
@include grid-column-gutter;
|
||||
|
||||
a {
|
||||
&:not(:focus) {
|
||||
@include element-invisible;
|
||||
width: 0 !important;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
@include body-colors;
|
||||
|
||||
$outline-size: $focus-inner-width + $focus-middle-width + $focus-outer-width;
|
||||
|
||||
padding: 0.4rem;
|
||||
position: absolute;
|
||||
$global-left: $outline-size;
|
||||
top: $outline-size;
|
||||
z-index: 1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<div class="skip-to-main-content">
|
||||
<%= link_to t("layouts.skip_to_main_content"), "#main" %>
|
||||
</div>
|
||||
2
app/components/layout/skip_to_main_content_component.rb
Normal file
2
app/components/layout/skip_to_main_content_component.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
class Layout::SkipToMainContentComponent < ApplicationComponent
|
||||
end
|
||||
@@ -7,6 +7,7 @@
|
||||
</head>
|
||||
|
||||
<body class="admin">
|
||||
<%= render Layout::SkipToMainContentComponent.new %>
|
||||
<%= render Layout::AdminHeaderComponent.new(current_user) %>
|
||||
|
||||
<div class="menu-and-content">
|
||||
@@ -22,7 +23,7 @@
|
||||
<% end %>
|
||||
</nav>
|
||||
|
||||
<main class="admin-content <%= yield(:main_class) %>">
|
||||
<main id="main" class="admin-content <%= yield(:main_class) %>">
|
||||
<%= label_tag :show_menu, t("admin.menu.admin"),
|
||||
"aria-hidden": true, class: "button hollow expanded" %>
|
||||
|
||||
|
||||
@@ -13,12 +13,13 @@
|
||||
<%= raw setting["html.per_page_code_head"] %>
|
||||
</head>
|
||||
<body class="<%= yield(:body_class) %> public">
|
||||
<%= render Layout::SkipToMainContentComponent.new %>
|
||||
<%= raw setting["html.per_page_code_body"] %>
|
||||
|
||||
<div class="wrapper <%= yield(:wrapper_class) %>">
|
||||
<%= render "layouts/header", with_subnavigation: true %>
|
||||
|
||||
<main class="public-content <%= yield(:main_class) %>">
|
||||
<main id="main" class="public-content <%= yield(:main_class) %>">
|
||||
<%= render "layouts/flash" %>
|
||||
<%= yield %>
|
||||
</main>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<%= raw setting["per_page_code_head"] %>
|
||||
</head>
|
||||
<body class="proposal-dashboard">
|
||||
<%= render Layout::SkipToMainContentComponent.new %>
|
||||
<%= raw setting["per_page_code_body"] %>
|
||||
|
||||
<h1 class="show-for-sr"><%= setting["org_name"] %></h1>
|
||||
@@ -26,7 +27,7 @@
|
||||
<%= render "dashboard/menu" %>
|
||||
</nav>
|
||||
|
||||
<main class="admin-content <%= yield(:main_class) %>">
|
||||
<main id="main" class="admin-content <%= yield(:main_class) %>">
|
||||
<%= label_tag :show_menu, t("admin.menu.admin"),
|
||||
"aria-hidden": true, class: "button hollow expanded" %>
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
</head>
|
||||
|
||||
<body class="auth-page">
|
||||
<%= render Layout::SkipToMainContentComponent.new %>
|
||||
<%= raw setting["html.per_page_code_body"] %>
|
||||
<div class="wrapper">
|
||||
<div class="auth-image small-12 medium-3 column"
|
||||
@@ -21,7 +22,7 @@
|
||||
<div class="small-12 medium-9 column">
|
||||
<div class="row">
|
||||
<div class="small-12 medium-9 large-7 small-centered column">
|
||||
<main class="auth-form margin <%= yield(:main_class) %>">
|
||||
<main id="main" class="auth-form margin <%= yield(:main_class) %>">
|
||||
<%= render "layouts/flash" %>
|
||||
|
||||
<%= yield %>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
</head>
|
||||
|
||||
<body class="admin">
|
||||
<%= render Layout::SkipToMainContentComponent.new %>
|
||||
<%= render Layout::AdminHeaderComponent.new(manager_logged_in) %>
|
||||
|
||||
<div class="menu-and-content">
|
||||
@@ -16,7 +17,7 @@
|
||||
<%= render "/management/menu" %>
|
||||
</nav>
|
||||
|
||||
<main class="admin-content">
|
||||
<main id="main" class="admin-content <%= yield(:main_class) %>">
|
||||
<%= label_tag :show_menu, t("admin.menu.admin"),
|
||||
"aria-hidden": true, class: "button hollow expanded" %>
|
||||
|
||||
|
||||
@@ -228,6 +228,7 @@ en:
|
||||
zero: "You don't have new notifications"
|
||||
notifications: Notifications
|
||||
sdg: "SDG"
|
||||
skip_to_main_content: "Skip to main content"
|
||||
notifications:
|
||||
index:
|
||||
empty_notifications: You don't have new notifications.
|
||||
|
||||
@@ -228,6 +228,7 @@ es:
|
||||
zero: "No tienes notificaciones nuevas"
|
||||
notifications: Notificaciones
|
||||
sdg: "ODS"
|
||||
skip_to_main_content: "Saltar al contenido principal"
|
||||
notifications:
|
||||
index:
|
||||
empty_notifications: No tienes notificaciones nuevas.
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main class="error">
|
||||
<main id="main" class="error">
|
||||
<h1>403</h1>
|
||||
<h2>Access to this page has been disabled by the administrators.</h2>
|
||||
</main>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main class="error">
|
||||
<main id="main" class="error">
|
||||
<h1>404</h1>
|
||||
<h2>Not found.</h2>
|
||||
</main>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main class="error">
|
||||
<main id="main" class="error">
|
||||
<h1>422</h1>
|
||||
<h2>The change you wanted was rejected.</h2>
|
||||
</main>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main class="error">
|
||||
<main id="main" class="error">
|
||||
<h1>500</h1>
|
||||
<h2>Internal server error.</h2>
|
||||
</main>
|
||||
|
||||
@@ -62,6 +62,8 @@ module Capybara
|
||||
|
||||
unless url.match?("robots.txt") || url.match?("active_storage/representations")
|
||||
expect(page).to have_css "main", count: 1
|
||||
expect(page).to have_css "#main", count: 1
|
||||
expect(page).to have_css "main#main"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -183,4 +183,20 @@ describe "Home" do
|
||||
within(".header-card") { expect(page).not_to have_link }
|
||||
end
|
||||
end
|
||||
|
||||
describe "Link to skip to main content" do
|
||||
it "is visible on focus" do
|
||||
visit root_path
|
||||
|
||||
expect(page).to have_link "Skip to main content", visible: :hidden
|
||||
expect(page).to have_css "main"
|
||||
expect(page).not_to have_css "main:target"
|
||||
|
||||
page.execute_script("$('.skip-to-main-content a').focus()")
|
||||
sleep 0.01 until page.has_link?("Skip to main content", visible: :visible)
|
||||
click_link "Skip to main content"
|
||||
|
||||
expect(page).to have_css "main:target"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user