elyseholladay
8/22/2013 - 4:40 PM

button-semantics.scss : Displays alerts for non-semantic button/link elements. Usage: Include this at the end of your manifest file. Impor

button-semantics.scss : Displays alerts for non-semantic button/link elements. Usage: Include this at the end of your manifest file. Important: For dev use only - do not compile with production code.

(inspired by: @heydonworks article http://coding.smashingmagazine.com/2013/08/20/semantic-css-with-intelligent-selectors)

//
// House Keeping - Button Semantics
// --------------------------------------------------


// Alert Message Style
// ---------------------

@mixin house-keeping-alert() {
  display: block !important;
  padding: 0.5em 1em !important;
  background: #f00 !important;
  color: #fff !important;
  font-family: sans-serif !important;
  font-size: 16px !important;
  text-decoration: none!important;
  text-shadow: none!important;
}


// Buttons and Links
// ---------------------

// If it’s a hyperlink, it should have an href attribute.
a:not([href]):after {
  content: 'Do you mean for this to be a link or a button, because it does not link to anything!';
  @include house-keeping-alert();
}


// If it’s a hyperlink and has an href attribute, it should have a valid value.
a[href=""]:after, 
a[href$="#"]:after, 
a[href^="javascript"]:after {
  content: 'Do you mean for this link to be a button, because it does not go anywhere!';
  @include house-keeping-alert();
}


// If it uses a button class, it should be a button — at least in the accessibility layer.
.btn:not(button):not([role="button"]):not([type="button"]):not([type="submit"]):not([type="reset"]):after, 
.button:not(button):not([role="button"]):not([type="button"]):not([type="submit"]):not([type="reset"]):after, 
a[class*="btn"]:not([role="button"]):after,
a[class*="button"]:not([role="button"]):after,
[class*="btn"]:not([role="button"]):after,
[class*="button"]:not([role="button"]):after {
  content: 'If you are going to make it look like a button, make it a button, damn it!';
  @include house-keeping-alert();
}


// If it is an a element with role="button", then it should link to somewhere when JavaScript is off.
a[role="button"]:not([href*="/"]):not([href*="."]):not([href*="?"]):after {
  content: 'Either use a link fallback, or just use a button element.';
  @include house-keeping-alert();
}


// You can’t disable a hyperlink.
a.button[class*="disabled"]:after, 
a.btn.disabled:after,
a[class*="button"][class*="disabled"]:after {
  content: 'You cannot disable a hyperlink. Use a button element with type="disabled".';
  @include house-keeping-alert();
}


// Buttons in forms should have explicit types.
form button:not([type]):after {
  content: 'Is this a submit button, a reset button or what? Use type="submit", type="reset" or type="button"';
  @include house-keeping-alert();
}


// Both hyperlinks and buttons should have some sort of content or an ARIA label.
a:empty:not([aria-label]):not([aria-labelledby]):after, 
button:empty:not([aria-label]):not([aria-labelledby]):after, 
button:not([aria-label]):not([aria-labelledby]) img:only-child:not([alt]):after, 
a:not([aria-label]):not([aria-labelledby]) img:only-child:not([alt]):after {
   content: 'All buttons and links should have text content, an image with alt text or an ARIA label';
   @include house-keeping-alert();
}