From 17c5065c7677b6af8f4cab866005087a2f099d43 Mon Sep 17 00:00:00 2001 From: Joe Knox Date: Tue, 5 Mar 2019 17:11:24 -0800 Subject: [PATCH] 120 Skiplinks (#303) * Adds skiplinks functionality and styles * refactor sr only classes * removed old skipnav component and updated skiplinks focus index --- core/css/decanter.css | 93 +++++++++++++------ core/scss/components/index.scss | 2 +- .../components/site-search/_site-search.scss | 2 +- .../scss/components/skiplinks/_skiplinks.scss | 31 +++++++ .../{skipnav => skiplinks}/index.scss | 2 +- core/scss/components/skipnav/_skipnav.scss | 16 ---- core/scss/core/helpers/_sr-only-element.scss | 19 ++++ core/scss/core/helpers/_sr-only-text.scss | 13 +++ core/scss/core/helpers/_sr-only.scss | 13 --- core/scss/core/helpers/index.scss | 3 +- core/scss/elements/input/_input.scss | 2 +- .../mixins/accessibility/_skiplinks.scss | 57 ++++++++++++ .../mixins/accessibility/_skipnav.scss | 29 ------ .../mixins/accessibility/_sr-only.scss | 22 ----- .../utilities/mixins/accessibility/index.scss | 3 +- core/templates/components/skiplinks/link.twig | 17 ++++ .../components/skiplinks/skiplinks.json | 5 + .../components/skiplinks/skiplinks.twig | 42 +++++++++ .../components/skiplinks/target.twig | 16 ++++ .../templates/components/skipnav/skipnav.json | 3 - .../templates/components/skipnav/skipnav.twig | 1 - core/templates/elements/input/input.twig | 4 +- kss/builder/decanter/kss-assets/css/kss.css | 3 + kss/builder/decanter/scss/_skiplinks.scss | 7 ++ kss/builder/decanter/scss/kss.scss | 1 + 25 files changed, 286 insertions(+), 120 deletions(-) create mode 100644 core/scss/components/skiplinks/_skiplinks.scss rename core/scss/components/{skipnav => skiplinks}/index.scss (76%) delete mode 100644 core/scss/components/skipnav/_skipnav.scss create mode 100644 core/scss/core/helpers/_sr-only-element.scss create mode 100644 core/scss/core/helpers/_sr-only-text.scss delete mode 100644 core/scss/core/helpers/_sr-only.scss create mode 100644 core/scss/utilities/mixins/accessibility/_skiplinks.scss delete mode 100644 core/scss/utilities/mixins/accessibility/_skipnav.scss delete mode 100644 core/scss/utilities/mixins/accessibility/_sr-only.scss create mode 100644 core/templates/components/skiplinks/link.twig create mode 100644 core/templates/components/skiplinks/skiplinks.json create mode 100644 core/templates/components/skiplinks/skiplinks.twig create mode 100644 core/templates/components/skiplinks/target.twig delete mode 100644 core/templates/components/skipnav/skipnav.json delete mode 100644 core/templates/components/skipnav/skipnav.twig create mode 100644 kss/builder/decanter/scss/_skiplinks.scss diff --git a/core/css/decanter.css b/core/css/decanter.css index 156395f8a..570e73ec3 100644 --- a/core/css/decanter.css +++ b/core/css/decanter.css @@ -1525,15 +1525,31 @@ template { src: url("https://www-media.stanford.edu/assets/fonts/stanford.woff") format("woff"), url("https://www-media.stanford.edu/assets/fonts/stanford.ttf") format("truetype"); font-weight: 300; } -.su-sr-only { +.su-sr-only-element { border: 0; - clip: rect(0, 0, 0, 0); + clip: rect(1px, 1px, 1px, 1px); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); height: 1px; overflow: hidden; + padding: 0; position: absolute; white-space: nowrap; - width: 1px; - padding: 0; } + width: 1px; } + .su-sr-only-element:active, .su-sr-only-element:focus { + clip: auto; + -webkit-clip-path: none; + clip-path: none; + height: auto; + overflow: visible; + position: static; + white-space: inherit; + width: auto; } + +.su-sr-only-text { + overflow: hidden; + text-indent: 101%; + white-space: nowrap; } html { -webkit-box-sizing: border-box; @@ -1636,13 +1652,15 @@ fieldset { [type="checkbox"], [type="radio"] { border: 0; - clip: rect(0, 0, 0, 0); + clip: rect(1px, 1px, 1px, 1px); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); height: 1px; overflow: hidden; + padding: 0; position: absolute; white-space: nowrap; - width: 1px; - padding: 0; } + width: 1px; } .lt-ie9 [type=checkbox], .lt-ie9 [type=radio] { border: 0; @@ -8168,13 +8186,15 @@ a { .su-site-search__sr-label { border: 0; - clip: rect(0, 0, 0, 0); + clip: rect(1px, 1px, 1px, 1px); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); height: 1px; overflow: hidden; + padding: 0; position: absolute; white-space: nowrap; - width: 1px; - padding: 0; } + width: 1px; } .su-site-search__submit { padding: 0; @@ -8201,22 +8221,41 @@ a { outline: #aaa solid 3px; outline: -webkit-focus-ring-color auto 5px; } -.su-skipnav { - background: transparent; - color: #2e2d29; - left: 0; +.su-skiplinks { + padding: 0; + background-color: #2e2d29; + color: #ffffff; + font-family: "Source Sans Pro", "Helvetica Neue", "Helvetica", "Arial", sans-serif; + font-size: .75em; + font-weight: 400; + left: .8em; + min-height: 1px; position: absolute; - top: -4.2rem; - -webkit-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; - z-index: 100; - padding: 1rem 1.5rem; } - .su-skipnav:focus { - background: #ffffff; - left: 0; - outline: 0; - position: absolute; - top: 0; - -webkit-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; } + text-decoration: none; + top: -500px; + -webkit-transition-duration: .25s; + transition-duration: .25s; + -webkit-transition-property: top; + transition-property: top; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; } + @media print { + .su-skiplinks { + display: none; } } + .su-skiplinks, .su-skiplinks:hover, .su-skiplinks:visited { + color: #ffffff; + height: 1px; + overflow: hidden; + white-space: nowrap; + width: 1px; } + .su-skiplinks:active, .su-skiplinks:focus { + padding: 0.4em 0.8em; + border: 1px solid #4d4f53; + border-radius: 3px; + height: auto; + left: .8em; + position: fixed; + top: .8em; + width: auto; + z-index: 11222; } /*# sourceMappingURL=decanter.css.map */ \ No newline at end of file diff --git a/core/scss/components/index.scss b/core/scss/components/index.scss index 253e7e668..6a6178b5f 100644 --- a/core/scss/components/index.scss +++ b/core/scss/components/index.scss @@ -20,4 +20,4 @@ 'main-nav/index', 'quote/index', 'site-search/index', - 'skipnav/index'; + 'skiplinks/index'; diff --git a/core/scss/components/site-search/_site-search.scss b/core/scss/components/site-search/_site-search.scss index a233df43f..f5d454e54 100644 --- a/core/scss/components/site-search/_site-search.scss +++ b/core/scss/components/site-search/_site-search.scss @@ -30,7 +30,7 @@ } .su-site-search__sr-label { - @include sr-only; + @include hide-visually; } .su-site-search__submit { diff --git a/core/scss/components/skiplinks/_skiplinks.scss b/core/scss/components/skiplinks/_skiplinks.scss new file mode 100644 index 000000000..7da694350 --- /dev/null +++ b/core/scss/components/skiplinks/_skiplinks.scss @@ -0,0 +1,31 @@ +@charset "UTF-8"; + +// +// Skiplinks +// +// For providing a link at the top of the page which jumps +// the user down to an anchor or target at the beginning of the main content. +// +// Gives screen readers and keyboard users the same capability of going directly +// to the main content as sighted, mouse users. +// of the main content. Learn more at https://webaim.org/techniques/skipnav. +// +// To test this component's functionality, place your cursor on "Example" and click. +// Then, press the tab key. The Skiplinks link will slide into view at the top +// lefthand corner of the screen. Press the return key (or click on the link) to +// skip to the targeted element. +// +// Markup:
+// Skip to main content +//
+//
+//

Main Content

+//
+// +// +// +// Style guide: Components.Skiplinks +// +.su-skiplinks { + @include skiplinks; +} diff --git a/core/scss/components/skipnav/index.scss b/core/scss/components/skiplinks/index.scss similarity index 76% rename from core/scss/components/skipnav/index.scss rename to core/scss/components/skiplinks/index.scss index a4ec58466..90bfb7096 100644 --- a/core/scss/components/skipnav/index.scss +++ b/core/scss/components/skiplinks/index.scss @@ -5,4 +5,4 @@ /// @import - 'skipnav'; + 'skiplinks'; diff --git a/core/scss/components/skipnav/_skipnav.scss b/core/scss/components/skipnav/_skipnav.scss deleted file mode 100644 index c8113b215..000000000 --- a/core/scss/components/skipnav/_skipnav.scss +++ /dev/null @@ -1,16 +0,0 @@ -@charset "UTF-8"; - -// -// Skipnav -// -// For providing a link at the top of the page which jumps -// the user down to an anchor or target at the beginning -// of the main content. Learn more at https://webaim.org/techniques/skipnav. -// -// Markup: ../../templates/components/skipnav/skipnav.twig -// -// Style guide: Components.Skipnav -// -.su-skipnav { - @include skipnav; -} diff --git a/core/scss/core/helpers/_sr-only-element.scss b/core/scss/core/helpers/_sr-only-element.scss new file mode 100644 index 000000000..fa05c50bc --- /dev/null +++ b/core/scss/core/helpers/_sr-only-element.scss @@ -0,0 +1,19 @@ +@charset "UTF-8"; + +// +// Screen Reader Only Element +// +// Hides an element visually while still allowing the content to be accessible +// to assistive technology (e.g. screen readers). Passing "unhide" will reverse +// the affects of the hiding, which is handy for showing the element on focus. +// +// Style guide: Core.Helpers.sr-only-element +// +.su-sr-only-element { + @include hide-visually; + + &:active, + &:focus { + @include hide-visually("unhide"); + } +} diff --git a/core/scss/core/helpers/_sr-only-text.scss b/core/scss/core/helpers/_sr-only-text.scss new file mode 100644 index 000000000..20bd239f9 --- /dev/null +++ b/core/scss/core/helpers/_sr-only-text.scss @@ -0,0 +1,13 @@ +@charset "UTF-8"; + +// +// Screen Reader Only Text +// +// Hides the text in an element, commonly used to show an image instead. +// Some elements will need block-level styles applied. +// +// Style guide: Core.Helpers.sr-only +// +.su-sr-only-text { + @include hide-text; +} diff --git a/core/scss/core/helpers/_sr-only.scss b/core/scss/core/helpers/_sr-only.scss deleted file mode 100644 index e1bd4eac2..000000000 --- a/core/scss/core/helpers/_sr-only.scss +++ /dev/null @@ -1,13 +0,0 @@ -@charset "UTF-8"; - -// -// @sr-only -// -// Hides piece of content from the screen but keeps in the DOM for screen -// readers. -// -// Style guide: Core.Helpers.sr-only -// -.su-sr-only { - @include sr-only; -} diff --git a/core/scss/core/helpers/index.scss b/core/scss/core/helpers/index.scss index 49d4e98d3..b22fb86a0 100644 --- a/core/scss/core/helpers/index.scss +++ b/core/scss/core/helpers/index.scss @@ -5,4 +5,5 @@ /// @import - 'sr-only'; + 'sr-only-element', + 'sr-only-text'; diff --git a/core/scss/elements/input/_input.scss b/core/scss/elements/input/_input.scss index e57f02c13..a25a12847 100644 --- a/core/scss/elements/input/_input.scss +++ b/core/scss/elements/input/_input.scss @@ -74,7 +74,7 @@ fieldset { [type=radio] { // The actual input element is only visible to screen readers, because // all visual styling is done via the label. - @include sr-only; + @include hide-visually; .lt-ie9 & { border: 0; diff --git a/core/scss/utilities/mixins/accessibility/_skiplinks.scss b/core/scss/utilities/mixins/accessibility/_skiplinks.scss new file mode 100644 index 000000000..d08152fdb --- /dev/null +++ b/core/scss/utilities/mixins/accessibility/_skiplinks.scss @@ -0,0 +1,57 @@ +@charset "UTF-8"; + +// +// @skiplinks +// +// For providing a link at the top of the page which jumps +// the user down to an anchor or target at the beginning of the main content. +// +// Gives screen readers and keyboard users the same capability of going directly +// to the main content as sighted, mouse users. +// of the main content. Learn more at https://webaim.org/techniques/skipnav. +// +// Style guide: Mixins.Accessibility.skiplinks +// +@mixin skiplinks { + @media print { + display: none; + } + + @include padding(0); + background-color: $color-black; + color: $color-white; + font-family: $font-sans; + font-size: .75em; + font-weight: 400; + left: .8em; + min-height: 1px; + position: absolute; + text-decoration: none; + top: -500px; + transition-duration: .25s; + transition-property: top; + transition-timing-function: ease-in-out; + + &, + &:hover, + &:visited { + color: $color-white; + height: 1px; + overflow: hidden; + white-space: nowrap; + width: 1px; + } + + &:active, + &:focus { + @include padding(.4em .8em); + border: 1px solid $color-cool-grey; + border-radius: $border-radius; + height: auto; + left: .8em; + position: fixed; + top: .8em; + width: auto; + z-index: 11222; + } +} diff --git a/core/scss/utilities/mixins/accessibility/_skipnav.scss b/core/scss/utilities/mixins/accessibility/_skipnav.scss deleted file mode 100644 index d07082a59..000000000 --- a/core/scss/utilities/mixins/accessibility/_skipnav.scss +++ /dev/null @@ -1,29 +0,0 @@ -@charset "UTF-8"; - -// -// @skipnav -// -// Skip to navigation helper. -// -// Style guide: Mixins.Accessibility.skipnav -// -@mixin skipnav { - background: transparent; - color: $color-black; - left: 0; - position: absolute; - top: -4.2rem; - transition: all 0.2s ease-in-out; - z-index: 100; - - @include padding(1rem 1.5rem); - - &:focus { - background: $color-white; - left: 0; - outline: 0; - position: absolute; - top: 0; - transition: all 0.2s ease-in-out; - } -} diff --git a/core/scss/utilities/mixins/accessibility/_sr-only.scss b/core/scss/utilities/mixins/accessibility/_sr-only.scss deleted file mode 100644 index 7b6cb3d1b..000000000 --- a/core/scss/utilities/mixins/accessibility/_sr-only.scss +++ /dev/null @@ -1,22 +0,0 @@ -@charset "UTF-8"; - -// -// @sr-only -// -// Screen reader only content hiding helper. -// -// See https://a11yproject.com/posts/how-to-hide-content/ -// -// Style guide: Mixins.Accessibility.sr-only -// -@mixin sr-only { - border: 0; - clip: rect(0, 0, 0, 0); - height: 1px; - overflow: hidden; - position: absolute; - white-space: nowrap; - width: 1px; - - @include padding(0); -} diff --git a/core/scss/utilities/mixins/accessibility/index.scss b/core/scss/utilities/mixins/accessibility/index.scss index a88d8b1bc..e4af287aa 100644 --- a/core/scss/utilities/mixins/accessibility/index.scss +++ b/core/scss/utilities/mixins/accessibility/index.scss @@ -10,5 +10,4 @@ @import 'accessibly-hidden', - 'skipnav', - 'sr-only'; + 'skiplinks'; diff --git a/core/templates/components/skiplinks/link.twig b/core/templates/components/skiplinks/link.twig new file mode 100644 index 000000000..c46329dce --- /dev/null +++ b/core/templates/components/skiplinks/link.twig @@ -0,0 +1,17 @@ +{# +/** + * Skip Links Component + * Link element + * + * The link element of the Skip Links component should be included at the very top of your pages' markup, + * before the nav and other header elements. It should be the first focusable element on the page. + * + * Available variables: + * - attributes: Additional HTML attributes for the link. + * - modifier_class: Additional CSS class(es) to change look or behavior of the link. + * - link_text: The text for the link when in focus - defaults to 'Skip to main content' + * - target_id: The id of the element in the page to skip to, which must match the id + * of the

in _target.twig - defaults to 'su-main-content-1891' + */ +#} +{{ link_text|default('Skip to main content') }} diff --git a/core/templates/components/skiplinks/skiplinks.json b/core/templates/components/skiplinks/skiplinks.json new file mode 100644 index 000000000..00d31d738 --- /dev/null +++ b/core/templates/components/skiplinks/skiplinks.json @@ -0,0 +1,5 @@ +{ + "target_id": "main-content", + "target_text": "Main Content", + "link_text": "Skip to main content" +} diff --git a/core/templates/components/skiplinks/skiplinks.twig b/core/templates/components/skiplinks/skiplinks.twig new file mode 100644 index 000000000..699cdae63 --- /dev/null +++ b/core/templates/components/skiplinks/skiplinks.twig @@ -0,0 +1,42 @@ +{# +/** + * Skip Links Component + * + * Accessibility feature to allow passing over the nav and going directly to the content. + * + * Note that this component has 2 pieces: + * - the link + * - the target the link jumps to + * These are provided in separate twig files for your convenience. To implement the Skip Links + * component in your project, you should not include this .twig file; instead, you should + * include the _link.twig and _target.twig files separately at the appropriate respecetive + * places in your markup. + * + * Available variables: + * - attributes: Additional HTML attributes for the link. + * - modifier_class: Additional CSS class(es) to change look or behavior of the link. + * - link_text: The text for the link when in focus - defaults to 'Skip to main content' + * - target_id: The id of the element in the page to skip to - defaults to 'su-main-content-1891' + * - target_text: The text to be read by the screenreader when the user clicks the skiplink - defaults to 'Main Content' + */ +#} +
+ {% include "@decanter/components/skiplinks/link.twig" with + { + "target_id": target_id, + "link_text": link_text, + "attributes": attributes, + "modifier_class": modifier_class + } + only + %} +
+
+ {% include "@decanter/components/skiplinks/target.twig" with + { + "target_id": target_id, + "target_text": target_text + } + only + %} +
diff --git a/core/templates/components/skiplinks/target.twig b/core/templates/components/skiplinks/target.twig new file mode 100644 index 000000000..be3d89781 --- /dev/null +++ b/core/templates/components/skiplinks/target.twig @@ -0,0 +1,16 @@ +{# +/** + * Skip Links Component + * Target element + * + * The target element of the Skip Links component should be included at the very top of your pages' main content, + * after the nav and other header elements. + * + * Available variables: + * - target_id: The id of the element in the page to skip to, which must match the href + * of the in _link.twig - defaults to 'su-main-content-1891' + * - target_text: The text to be read by the screenreader when the user clicks the + * skiplink - defaults to 'Main Content' + */ +#} +

{{ target_text|default('Main Content') }}

diff --git a/core/templates/components/skipnav/skipnav.json b/core/templates/components/skipnav/skipnav.json deleted file mode 100644 index 0db3279e4..000000000 --- a/core/templates/components/skipnav/skipnav.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - -} diff --git a/core/templates/components/skipnav/skipnav.twig b/core/templates/components/skipnav/skipnav.twig deleted file mode 100644 index 79cdbd6e1..000000000 --- a/core/templates/components/skipnav/skipnav.twig +++ /dev/null @@ -1 +0,0 @@ -
{{ text|default('Skip to main navigation') }} diff --git a/core/templates/elements/input/input.twig b/core/templates/elements/input/input.twig index e0901e209..25209007b 100644 --- a/core/templates/elements/input/input.twig +++ b/core/templates/elements/input/input.twig @@ -1,6 +1,6 @@

Checkboxes

- Stanford Presidents + Stanford Presidents
  • @@ -23,7 +23,7 @@

    Radio Buttons

    - Stanford Provosts + Stanford Provosts
    • diff --git a/kss/builder/decanter/kss-assets/css/kss.css b/kss/builder/decanter/kss-assets/css/kss.css index cb7919319..58a4c41ef 100644 --- a/kss/builder/decanter/kss-assets/css/kss.css +++ b/kss/builder/decanter/kss-assets/css/kss.css @@ -1866,6 +1866,9 @@ ol.linenums { font-weight: normal; color: #56554d; } +#kssref-components-skiplinks .kss-modifier__example { + z-index: 11222; } + .kss-toolbar { margin: 6px 0 24px; display: inline-block; diff --git a/kss/builder/decanter/scss/_skiplinks.scss b/kss/builder/decanter/scss/_skiplinks.scss new file mode 100644 index 000000000..f385d35ae --- /dev/null +++ b/kss/builder/decanter/scss/_skiplinks.scss @@ -0,0 +1,7 @@ +@charset "UTF-8"; + +#kssref-components-skiplinks { + .kss-modifier__example { + z-index: 11222; + } +} diff --git a/kss/builder/decanter/scss/kss.scss b/kss/builder/decanter/scss/kss.scss index e06b6e863..5224e47ba 100644 --- a/kss/builder/decanter/scss/kss.scss +++ b/kss/builder/decanter/scss/kss.scss @@ -53,4 +53,5 @@ 'prettify', 'print', 'sidebar', + 'skiplinks', 'toolbar';