Skip to content
This repository has been archived by the owner on Sep 13, 2024. It is now read-only.

Add hide-visually mixin #818

Merged
merged 1 commit into from
Jan 30, 2016
Merged

Add hide-visually mixin #818

merged 1 commit into from
Jan 30, 2016

Conversation

tysongach
Copy link
Contributor

Hides an element visually while still allowing the content to be accessible to assistive technology.

A great use-case is one I recently came across on Administrate: thoughtbot/administrate#416

  • Need tests

@conchan
Copy link
Contributor

conchan commented Jan 20, 2016

👍 Good call

@creuter
Copy link

creuter commented Jan 20, 2016

👍

@creuter
Copy link

creuter commented Jan 20, 2016

We should have a designer talk on accessibility some Friday.

@LkeMitchll
Copy link

This has some applicability, such as 'skip to content' actions e.g. 'tabbing' on the gov.uk site. Perhaps that means there's a case for a unhide-visually mixin?

Have you considered using aria-label on elements that simply require a label?

@tysongach
Copy link
Contributor Author

@LkeMitchll Great points; thanks!

So, unhide-visually would easily “undo” the hiding, and a good time for that might be on :focus.

@LkeMitchll
Copy link

Yea, exactly. It saves having to build some JS or resorting to using display: hidden. It may also be useful when using the @media speech type.

Although if you think there's a better name for it that might be good. 'Unhide' feels a little weird. Not sure.

@heycorwin
Copy link

@tysongach The clip property has been deprecated in favor of clip-path

@tysongach
Copy link
Contributor Author

@corwinharrell Ah, yes! Thanks for bringing that up. I looked into it, but failed to mention that in my original PR comment.

clip is indeed deprecated (https://developer.mozilla.org/en-US/docs/Web/CSS/clip), but it still has insanely good support.

clip-path is the newer property and is intended to replace clip, but it still doesn’t have great support (http://caniuse.com/#feat=css-clip-path). It also doesn’t have as quite of a clear syntax, though it is more powerful.

We could add another line to the mixin, to also include clip-path, in the event that clip gets deprecated in a browser:

@mixin hide-visually {
  border: 0;
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: circle(1px at 1px 1px); // add this
  height: 1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  width: 1px;
}

@ckundo
Copy link

ckundo commented Jan 20, 2016

👍 to @LkeMitchll for a show-on-focus mixin to complement this (especially for skip to content links).

@tysongach tysongach changed the title Add hide-visually mixin [WIP] Add hide-visually mixin Jan 24, 2016
@tysongach
Copy link
Contributor Author

Okay!

So, I added clip-path—per my comment above—to be a bit more future-friendly and account for when browsers decide to drop the now-deprecated clip property.

Regarding “un-hiding” content on :active/:focus, I came up with two approaches:

  1. Use two mixins. For example, something like hide-visually and unhide-visually:

    @mixin hide-visually {
      …
    }
    
    @mixin unhide-visually {
      …
    }
    
    // example use
    .hide-visually {
      @include hide-visually;
    
      &:active,
      &:focus {
        @include unhide-visually;
      }
    }

    http://codepen.io/tysongach/pen/dGmpyw?editors=1100

  2. Use one mixin which defaults to hiding, but you can pass it an argument to unhide:

    @mixin hide-visually($toggle: hide) {
      @if $toggle == "hide" {
        …
      } @elseif $toggle == "unhide" {
        …
      }
    }
    
    // example use
    .hide-visually {
      @include hide-visually;
    
      &:active,
      &:focus {
        @include hide-visually(unhide);
      }
    }
    

    http://codepen.io/tysongach/pen/XXEjKE?editors=1100

Personally, I like Option 2 because it means we don’t have to maintain two mixins which are highly connected to each other (one “undoes” the other’s styles). I also think Option 2 is generally gives more awareness to what is going on (again, one “undoes” the hiding).

I also purposely didn’t bake the :active/:focus pseudo-class selectors into the mixin because I think it limits the possibilities for where this mixin can be used, and it also makes it a bit more unclear as to what the mixin is outputting (which, if we did include these selectors, would be quite a bit).

I went ahead and pushed Option 2 here to this PR, but I’m happy to have a discussion and hear people’s thoughts!

@tysongach tysongach added this to the 5.0.0 milestone Jan 25, 2016
@if $toggle == "hide" {
border: 0;
clip: rect(1px, 1px, 1px, 1px);
clip-path: circle(1px at 1px 1px);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a specific reason that you're using rect() for older browsers and circle() for newer ones?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LkeMitchll The variation between the two annoyed me (ha!), but it’s because clip only accepts rect(), and clip-path doesn’t even have rect() as an available value. clip-path accepts a handful of values, which you can find here: https://developer.mozilla.org/en-US/docs/Web/CSS/clip-path#Syntax

I was actually speaking with @georgebrock just last night about swapping this for a polygon() is it can do a single x/y pair as the value. I’m gonna test that now…

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tysongach Thanks for the heads up on that. That's a strangely awkward syntax. You're right polygon() seems to be closest to the rect() syntax.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely…

So, using clip-path’s polygon() to achieve the same thing as the old clip property would look like this:

clip-path: polygon(0 0, 1px 0, 1px 1px, 0 1px);

http://codepen.io/tysongach/pen/bEvLEY

I think I prefer the terseness of circle().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m now wondering if we should use percentages rather than pixels in the clip-path, though:

clip-path: circle(1% at 1% 1%);

Because currently, we are clipping down to 1px, and since the height and width are also set to 1px, the end result will always be a box with the dimensions of 1px by 1px.

If we use percentages for the clipping, it would clip 1/100th of the 1px box, therefore hiding more.

This all begs the question, where did the 1px values come from originally? I also assume we can’t do zero values because of some reason?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to this (see bottom of article) It's because if the element was 0px it would not be detected by VoiceOver (and presumably other speech services). But I don't see why using a percentage would hurt.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that makes sense. Same reason they don’t pick up display: none;

Thanks!

@LkeMitchll
Copy link

@tysongach I agree on option 2, plus it appears to follow a similar convention to backface-visibility(visible).

@tysongach tysongach changed the title [WIP] Add hide-visually mixin Add hide-visually mixin Jan 26, 2016
@tysongach tysongach force-pushed the tg-hide-visually branch 2 times, most recently from 67ea7d5 to 5c575c3 Compare January 26, 2016 20:51
@tysongach tysongach force-pushed the tg-hide-visually branch 2 times, most recently from 029805c to 802f690 Compare January 30, 2016 15:56
Hides an element visually while still allowing the content
to be accessible to assistive technology, e.g. screen readers
@tysongach tysongach merged commit 98f9473 into master Jan 30, 2016
@tysongach tysongach deleted the tg-hide-visually branch January 30, 2016 16:01
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants