diff --git a/docs/pages/badge.md b/docs/pages/badge.md
index 0ed430cd4f..0b321daace 100644
--- a/docs/pages/badge.md
+++ b/docs/pages/badge.md
@@ -47,7 +47,7 @@ Badges can be colored with the same classes used for buttons and other component
An icon can be used in place of text. We're using the [Foundation icon font](http://zurb.com/playground/foundation-icon-fonts-3) here, but any icon fonts or image-based icons will work fine.
```html_example
-
+
```
diff --git a/docs/pages/button.md b/docs/pages/button.md
index 9a081d1f16..1b5fc15dcc 100644
--- a/docs/pages/button.md
+++ b/docs/pages/button.md
@@ -53,11 +53,12 @@ Give a button additional meaning by adding a coloring class, or `.disabled` to c
```html_example
-Secondary Color
-Success Color
-Alert Color
-Warning Color
-Disabled Button
+Primary
+Secondary
+Success
+Alert
+Warning
+Disabled
```
---
diff --git a/scss/_global.scss b/scss/_global.scss
index 4ed320ab38..cb97530236 100644
--- a/scss/_global.scss
+++ b/scss/_global.scss
@@ -23,11 +23,11 @@ $global-lineheight: 1.5 !default;
/// Colors used for buttons, callouts, links, etc. There must always be a color called `primary`.
/// @type Map
$foundation-palette: (
- primary: #2199e8,
- secondary: #777,
+ primary: #1779ba,
+ secondary: #767676,
success: #3adb76,
warning: #ffae00,
- alert: #ec5840,
+ alert: #cc4b37,
) !default;
/// Color used for light gray UI items.
diff --git a/scss/components/_accordion.scss b/scss/components/_accordion.scss
index 3678f66075..e3ba3a9b1c 100644
--- a/scss/components/_accordion.scss
+++ b/scss/components/_accordion.scss
@@ -20,7 +20,7 @@ $accordion-title-font-size: rem-calc(12) !default;
/// Default text color for items in a Menu.
/// @type Color
-$accordion-item-color: foreground($accordion-background, $primary-color) !default;
+$accordion-item-color: $primary-color !default;
/// Default background color on hover for items in a Menu.
/// @type Color
@@ -40,16 +40,18 @@ $accordion-content-border: 1px solid $light-gray !default;
/// Default text color of tab content.
/// @type Color
-$accordion-content-color: foreground($accordion-content-background, $body-font-color) !default;
+$accordion-content-color: $body-font-color !default;
/// Default padding for tab content.
/// @type Number | List
$accordion-content-padding: 1rem !default;
/// Adds styles for an accordion container. Apply this to the same element that gets `data-accordion`.
-@mixin accordion-container {
+@mixin accordion-container (
+ $background: $accordion-background
+) {
margin-#{$global-left}: 0;
- background: $accordion-background;
+ background: $background;
list-style-type: none;
}
@@ -65,26 +67,32 @@ $accordion-content-padding: 1rem !default;
}
/// Adds styles for the title of an accordion item. Apply this to the link within an accordion item.
-@mixin accordion-title {
+@mixin accordion-title (
+ $padding: $accordion-item-padding,
+ $font-size: $accordion-title-font-size,
+ $color: $accordion-item-color,
+ $border: $accordion-content-border,
+ $background-hover: $accordion-item-background-hover
+) {
position: relative;
display: block;
- padding: $accordion-item-padding;
+ padding: $padding;
- border: $accordion-content-border;
+ border: $border;
border-bottom: 0;
- font-size: $accordion-title-font-size;
+ font-size: $font-size;
line-height: 1;
- color: $accordion-item-color;
+ color: $color;
:last-child:not(.is-active) > & {
- border-bottom: $accordion-content-border;
+ border-bottom: $border;
border-radius: 0 0 $global-radius $global-radius;
}
&:hover,
&:focus {
- background-color: $accordion-item-background-hover;
+ background-color: $background-hover;
}
@if $accordion-plusminus {
@@ -103,18 +111,23 @@ $accordion-content-padding: 1rem !default;
}
/// Adds styles for accordion content. Apply this to the content pane below an accordion item's title.
-@mixin accordion-content {
+@mixin accordion-content (
+ $padding: $accordion-content-padding,
+ $border: $accordion-content-border,
+ $background: $accordion-content-background,
+ $color: $accordion-content-color
+) {
display: none;
- padding: $accordion-content-padding;
+ padding: $padding;
- border: $accordion-content-border;
+ border: $border;
border-bottom: 0;
- background-color: $accordion-content-background;
+ background-color: $background;
- color: $accordion-content-color;
+ color: $color;
:last-child > &:last-child {
- border-bottom: $accordion-content-border;
+ border-bottom: $border;
}
}
diff --git a/scss/components/_badge.scss b/scss/components/_badge.scss
index 487f0d7696..768f649f24 100644
--- a/scss/components/_badge.scss
+++ b/scss/components/_badge.scss
@@ -12,7 +12,11 @@ $badge-background: $primary-color !default;
/// Default text color for badges.
/// @type Color
-$badge-color: foreground($badge-background) !default;
+$badge-color: $white !default;
+
+/// Alternate text color for badges.
+/// @type Color
+$badge-color-alt: $black !default;
/// Default padding inside badges.
/// @type Number
@@ -49,7 +53,7 @@ $badge-font-size: 0.6rem !default;
@if $name != primary {
&.#{$name} {
background: $color;
- color: foreground($color);
+ color: color-pick-contrast($color, ($badge-color, $badge-color-alt));
}
}
}
diff --git a/scss/components/_button.scss b/scss/components/_button.scss
index ecb0d34555..01686a6efb 100644
--- a/scss/components/_button.scss
+++ b/scss/components/_button.scss
@@ -30,7 +30,7 @@ $button-background-hover: scale-color($button-background, $lightness: -15%) !def
/// @type List
$button-color: $white !default;
-/// Font color for buttons, if the background is light.
+/// Alternative font color for buttons.
/// @type List
$button-color-alt: $black !default;
@@ -114,7 +114,7 @@ $button-transition: background-color 0.25s ease-out, color 0.25s ease-out !defau
$background-hover-lightness: $button-background-hover-lightness
) {
@if $color == auto {
- $color: foreground($background, $button-color-alt, $button-color);
+ $color: color-pick-contrast($background, ($button-color, $button-color-alt));
}
@if $background-hover == auto {
diff --git a/scss/components/_label.scss b/scss/components/_label.scss
index 28bbc0ba21..5f26e91f47 100644
--- a/scss/components/_label.scss
+++ b/scss/components/_label.scss
@@ -12,7 +12,11 @@ $label-background: $primary-color !default;
/// Default text color for labels.
/// @type Color
-$label-color: foreground($label-background) !default;
+$label-color: $white !default;
+
+/// Alternate text color for labels.
+/// @type Color
+$label-color-alt: $black !default;
/// Default font size for labels.
/// @type Number
@@ -50,7 +54,7 @@ $label-radius: $global-radius !default;
@if $name != primary {
&.#{$name} {
background: $color;
- color: foreground($color);
+ color: color-pick-contrast($color, ($label-color, $label-color-alt));
}
}
}
diff --git a/scss/components/_orbit.scss b/scss/components/_orbit.scss
index 1ff7001860..9b43fcdd45 100644
--- a/scss/components/_orbit.scss
+++ b/scss/components/_orbit.scss
@@ -96,7 +96,7 @@ $orbit-control-zindex: 10 !default;
padding: $orbit-caption-padding;
background-color: $orbit-caption-background;
- color: foreground($orbit-caption-background);
+ color: color-pick-contrast($orbit-caption-background);
}
/// Adds base styles for the next/previous buttons in an Orbit slider. These styles are shared between the `.orbit-next` and `.orbit-previous` classes in the default CSS.
diff --git a/scss/components/_pagination.scss b/scss/components/_pagination.scss
index 288041f708..7b18a3136d 100644
--- a/scss/components/_pagination.scss
+++ b/scss/components/_pagination.scss
@@ -40,7 +40,7 @@ $pagination-item-background-current: $primary-color !default;
/// Text color of the pagination item for the current page.
/// @type Color
-$pagination-item-color-current: foreground($pagination-item-background-current) !default;
+$pagination-item-color-current: $white !default;
/// Text color of a disabled pagination item.
/// @type Color
@@ -66,16 +66,24 @@ $pagination-mobile-current-item: false !default;
$pagination-arrows: true !default;
/// Adds styles for a pagination container. Apply this to a `
`.
-@mixin pagination-container {
+@mixin pagination-container (
+ $margin-bottom: $pagination-margin-bottom,
+ $font-size: $pagination-font-size,
+ $spacing: $pagination-item-spacing,
+ $radius: $pagination-radius,
+ $color: $pagination-item-color,
+ $padding: $pagination-item-padding,
+ $background-hover: $pagination-item-background-hover
+) {
@include clearfix;
margin-#{$global-left}: 0;
- margin-bottom: $pagination-margin-bottom;
+ margin-bottom: $margin-bottom;
// List item
li {
- margin-#{$global-right}: $pagination-item-spacing;
- border-radius: $pagination-radius;
- font-size: $pagination-font-size;
+ margin-#{$global-right}: $spacing;
+ border-radius: $radius;
+ font-size: $font-size;
@if $pagination-mobile-items {
display: inline-block;
@@ -104,28 +112,35 @@ $pagination-arrows: true !default;
a,
button {
display: block;
- padding: $pagination-item-padding;
+ padding: $padding;
border-radius: $global-radius;
- color: $pagination-item-color;
+ color: $color;
&:hover {
- background: $pagination-item-background-hover;
+ background: $background-hover;
}
}
}
/// Adds styles for the current pagination item. Apply this to an ``.
-@mixin pagination-item-current {
- padding: $pagination-item-padding;
- background: $pagination-item-background-current;
- color: $pagination-item-color-current;
+@mixin pagination-item-current (
+ $padding: $pagination-item-padding,
+ $background-current: $pagination-item-background-current,
+ $color-current: $pagination-item-color-current
+) {
+ padding: $padding;
+ background: $background-current;
+ color: $color-current;
cursor: default;
}
/// Adds styles for a disabled pagination item. Apply this to an ``.
-@mixin pagination-item-disabled {
- padding: $pagination-item-padding;
- color: $pagination-item-color-disabled;
+@mixin pagination-item-disabled (
+ $padding: $pagination-item-padding,
+ $color: $pagination-item-color-disabled
+) {
+ padding: $padding;
+ color: $color;
cursor: not-allowed;
&:hover {
@@ -134,10 +149,13 @@ $pagination-arrows: true !default;
}
/// Adds styles for an ellipsis for use in a pagination list.
-@mixin pagination-ellipsis {
- padding: $pagination-item-padding;
+@mixin pagination-ellipsis (
+ $padding: $pagination-item-padding,
+ $color: $pagination-ellipsis-color
+) {
+ padding: $padding;
content: '\2026';
- color: $pagination-ellipsis-color;
+ color: $color;
}
@mixin foundation-pagination {
diff --git a/scss/components/_tabs.scss b/scss/components/_tabs.scss
index c79928491d..f2b61d07cd 100644
--- a/scss/components/_tabs.scss
+++ b/scss/components/_tabs.scss
@@ -14,10 +14,18 @@ $tab-margin: 0 !default;
/// @type Color
$tab-background: $white !default;
-/// active background color of a tab bar.
+/// Font color of tab item.
+/// @type Color
+$tab-color: $primary-color !default;
+
+/// Active background color of a tab bar.
/// @type Color
$tab-background-active: $light-gray !default;
+/// Active font color of tab item.
+/// @type Color
+$tab-background-active-color: $primary-color !default;
+
/// Font size of tab items.
/// @type Number
$tab-item-font-size: rem-calc(12) !default;
@@ -43,18 +51,22 @@ $tab-content-border: $light-gray !default;
/// Default text color of tab content.
/// @type Color
-$tab-content-color: foreground($tab-background, $primary-color) !default;
+$tab-content-color: $body-font-color !default;
/// Default padding for tab content.
/// @type Number | List
$tab-content-padding: 1rem !default;
/// Adds styles for a tab container. Apply this to a ``.
-@mixin tabs-container {
+@mixin tabs-container (
+ $margin: $tab-margin,
+ $background: $tab-background,
+ $border-color: $tab-content-border
+) {
@include clearfix;
- margin: $tab-margin;
- border: 1px solid $tab-content-border;
- background: $tab-background;
+ margin: $margin;
+ border: 1px solid $border-color;
+ background: $background;
list-style-type: none;
}
@@ -68,44 +80,63 @@ $tab-content-padding: 1rem !default;
}
/// Adds styles for the links within a tab container. Apply this to the `- ` elements inside a tab container.
-@mixin tabs-title {
+@mixin tabs-title (
+ $padding: $tab-item-padding,
+ $font-size: $tab-item-font-size,
+ $color: $tab-color,
+ $color-active: $tab-background-active-color,
+ $background-hover: $tab-item-background-hover,
+ $background-active: $tab-background-active
+) {
float: #{$global-left};
> a {
display: block;
- padding: $tab-item-padding;
- font-size: $tab-item-font-size;
+ padding: $padding;
+ font-size: $font-size;
line-height: 1;
+ color: $color;
&:hover {
- background: $tab-item-background-hover;
+ background: $background-hover;
+ color: scale-color($color, $lightness: -14%);
}
&:focus,
&[aria-selected='true'] {
- background: $tab-background-active;
+ background: $background-active;
+ color: $color-active;
}
}
}
/// Adds styles for the wrapper that surrounds a tab group's content panes.
-@mixin tabs-content {
- border: 1px solid $tab-content-border;
+@mixin tabs-content (
+ $background: $tab-content-background,
+ $color: $tab-content-color,
+ $border-color: $tab-content-border
+) {
+ border: 1px solid $border-color;
border-top: 0;
- background: $tab-content-background;
+ background: $background;
+ color: $color;
transition: all 0.5s ease;
}
/// Augments a tab content container to have a vertical style, by shifting the border around. Use this in conjunction with `tabs-content()`.
-@mixin tabs-content-vertical {
- border: 1px solid $tab-content-border;
+@mixin tabs-content-vertical (
+ $border-color: $tab-content-border
+) {
+ border: 1px solid $border-color;
border-#{$global-left}: 0;
}
/// Adds styles for an individual tab content panel within the tab content container.
-@mixin tabs-panel {
+@mixin tabs-panel (
+ $padding: $tab-content-padding
+) {
display: none;
- padding: $tab-content-padding;
+ padding: $padding;
&[aria-hidden="false"] {
display: block;
@@ -138,7 +169,7 @@ $tab-content-padding: 1rem !default;
background: $primary-color;
> li > a {
- color: foreground($primary-color);
+ color: color-pick-contrast($primary-color);
&:hover,
&:focus {
diff --git a/scss/settings/_settings.scss b/scss/settings/_settings.scss
index 43057cb111..781267c0fd 100644
--- a/scss/settings/_settings.scss
+++ b/scss/settings/_settings.scss
@@ -49,11 +49,11 @@ $global-font-size: 100%;
$global-width: rem-calc(1200);
$global-lineheight: 1.5;
$foundation-palette: (
- primary: #2199e8,
- secondary: #777,
+ primary: #1779ba,
+ secondary: #767676,
success: #3adb76,
warning: #ffae00,
- alert: #ec5840,
+ alert: #cc4b37,
);
$light-gray: #e6e6e6;
$medium-gray: #cacaca;
@@ -197,12 +197,12 @@ $input-error-font-weight: $global-weight-bold;
$accordion-background: $white;
$accordion-plusminus: true;
$accordion-title-font-size: rem-calc(12);
-$accordion-item-color: foreground($accordion-background, $primary-color);
+$accordion-item-color: $primary-color;
$accordion-item-background-hover: $light-gray;
$accordion-item-padding: 1.25rem 1rem;
$accordion-content-background: $white;
$accordion-content-border: 1px solid $light-gray;
-$accordion-content-color: foreground($accordion-content-background, $body-font-color);
+$accordion-content-color: $body-font-color;
$accordion-content-padding: 1rem;
// 8. Accordion Menu
@@ -215,7 +215,8 @@ $accordionmenu-arrow-color: $primary-color;
// --------
$badge-background: $primary-color;
-$badge-color: foreground($badge-background);
+$badge-color: $white;
+$badge-color-alt: $black;
$badge-padding: 0.3em;
$badge-minwidth: 2.1em;
$badge-font-size: 0.6rem;
@@ -371,7 +372,8 @@ $form-button-radius: $global-radius;
// ---------
$label-background: $primary-color;
-$label-color: foreground($label-background);
+$label-color: $white;
+$label-color-alt: $black;
$label-font-size: 0.8rem;
$label-padding: 0.33333rem 0.5rem;
$label-radius: $global-radius;
@@ -443,7 +445,7 @@ $pagination-item-spacing: rem-calc(1);
$pagination-radius: $global-radius;
$pagination-item-background-hover: $light-gray;
$pagination-item-background-current: $primary-color;
-$pagination-item-color-current: foreground($pagination-item-background-current);
+$pagination-item-color-current: $white;
$pagination-item-color-disabled: $medium-gray;
$pagination-ellipsis-color: $black;
$pagination-mobile-items: false;
@@ -534,14 +536,16 @@ $show-header-for-stacked: false;
$tab-margin: 0;
$tab-background: $white;
+$tab-color: $primary-color;
$tab-background-active: $light-gray;
+$tab-background-active-color: $primary-color;
$tab-item-font-size: rem-calc(12);
$tab-item-background-hover: $white;
$tab-item-padding: 1.25rem 1.5rem;
$tab-expand-max: 6;
$tab-content-background: $white;
$tab-content-border: $light-gray;
-$tab-content-color: foreground($tab-background, $primary-color);
+$tab-content-color: $body-font-color;
$tab-content-padding: 1rem;
// 33. Thumbnail
diff --git a/scss/util/_color.scss b/scss/util/_color.scss
index ae23683b13..e247040725 100644
--- a/scss/util/_color.scss
+++ b/scss/util/_color.scss
@@ -2,28 +2,80 @@
// foundation.zurb.com
// Licensed under MIT Open Source
+@import 'math';
+
////
/// @group functions
////
-/// Checks the lightness of `$color`, and if it passes the `$threshold` of lightness, it returns the `$yes` color. Otherwise, it returns the `$no` color. Use this function to dynamically output a foreground color based on a given background color.
+/// Checks the luminance of `$color`.
///
-/// @param {Color} $color - Color to check the lightness of.
-/// @param {Color} $yes [$black] - Color to return if `$color` is light.
-/// @param {Color} $no [$white] - Color to return if `$color` is dark.
-/// @param {Percentage} $threshold [60%] - Threshold of lightness to check against.
+/// @param {Color} $color - Color to check the luminance of.
///
-/// @returns {Color} The $yes color or $no color.
-@function foreground($color, $yes: $black, $no: $white, $threshold: 60%) {
- @if $color == transparent {
- $color: $body-background;
+/// @returns {Number} The luminance of `$color`.
+@function color-luminance($color) {
+ // Adapted from: https://github.com/LeaVerou/contrast-ratio/blob/gh-pages/color.js
+ // Formula: http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
+ $rgba: red($color), green($color), blue($color);
+ $rgba2: ();
+
+ @for $i from 1 through 3 {
+ $rgb: nth($rgba, $i);
+ $rgb: $rgb / 255;
+
+ $rgb: if($rgb < 0.03928, $rgb / 12.92, pow(($rgb + 0.055) / 1.055, 2.4));
+
+ $rgba2: append($rgba2, $rgb);
}
- @if (lightness($color) > $threshold) {
- @return $yes;
+
+ @return 0.2126 * nth($rgba2, 1) + 0.7152 * nth($rgba2, 2) + 0.0722 * nth($rgba2, 3);
+}
+
+/// Checks the contrast ratio of two colors.
+///
+/// @param {Color} $color1 - First color to compare.
+/// @param {Color} $color2 - Second color to compare.
+///
+/// @returns {Number} The contrast ratio of the compared colors.
+@function color-contrast($color1, $color2) {
+ // Adapted from: https://github.com/LeaVerou/contrast-ratio/blob/gh-pages/color.js
+ // Formula: http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
+ $luminance1: color-luminance($color1) + 0.05;
+ $luminance2: color-luminance($color2) + 0.05;
+ $ratio: $luminance1 / $luminance2;
+
+ @if $luminance2 > $luminance1 {
+ $ratio: 1 / $ratio;
}
- @else {
- @return $no;
+
+ $ratio: round($ratio * 10) / 10;
+
+ @return $ratio;
+}
+
+/// Checks the luminance of `$base`, and returns the color from `$colors` (list of colors) that has the most contrast.
+///
+/// @param {Color} $color1 - First color to compare.
+/// @param {Color} $color2 - Second color to compare.
+///
+/// @returns {Number} The contrast ratio of the compared colors.
+@function color-pick-contrast($base, $colors: ($white, $black), $tolerance: 0) {
+ $contrast: color-contrast($base, nth($colors, 1));
+ $best: nth($colors, 1);
+
+ @for $i from 2 through length($colors) {
+ $current-contrast: color-contrast($base, nth($colors, $i));
+ @if ($current-contrast - $contrast > $tolerance) {
+ $contrast: color-contrast($base, nth($colors, $i));
+ $best: nth($colors, $i);
+ }
}
+
+ @if ($contrast < 3) {
+ @warn "Contrast ratio of #{$best} on #{$base} is pretty bad, just #{$contrast}";
+ }
+
+ @return $best;
}
/// Scales a color to be darker if it's light, or lighter if it's dark. Use this function to tint a color appropriate to its lightness.
diff --git a/scss/util/_math.scss b/scss/util/_math.scss
new file mode 100644
index 0000000000..ec261ade39
--- /dev/null
+++ b/scss/util/_math.scss
@@ -0,0 +1,63 @@
+// Foundation for Sites by ZURB
+// foundation.zurb.com
+// Licensed under MIT Open Source
+
+////
+/// @group functions
+////
+
+/// Finds the greatest common divisor of two integers.
+///
+/// @param {Number} $a - First number to compare.
+/// @param {Number} $b - Second number to compare.
+///
+/// @returns {Number} The greatest common divisor.
+@function gcd($a, $b) {
+ // From: http://rosettacode.org/wiki/Greatest_common_divisor#JavaScript
+ @if ($b != 0) {
+ @return gcd($b, $a % $b);
+ }
+ @else {
+ @return abs($a);
+ }
+}
+
+/// Handles decimal exponents by trying to convert them into a fraction and then use a nth-root-algorithm for parts of the calculation
+///
+/// @param {Number} $base - The base number.
+/// @param {Number} $exponent - The exponent.
+///
+/// @returns {Number} The product of the exponentiation.
+@function pow($base, $exponent, $prec: 12) {
+ @if (floor($exponent) != $exponent) {
+ $prec2 : pow(10, $prec);
+ $exponent: round($exponent * $prec2);
+ $denominator: gcd($exponent, $prec2);
+ @return nth-root(pow($base, $exponent / $denominator), $prec2 / $denominator, $prec);
+ }
+
+ $value: $base;
+ @if $exponent > 1 {
+ @for $i from 2 through $exponent {
+ $value: $value * $base;
+ }
+ }
+ @else if $exponent < 1 {
+ @for $i from 0 through -$exponent {
+ $value: $value / $base;
+ }
+ }
+
+ @return $value;
+}
+
+@function nth-root($num, $n: 2, $prec: 12) {
+ // From: http://rosettacode.org/wiki/Nth_root#JavaScript
+ $x: 1;
+
+ @for $i from 0 through $prec {
+ $x: 1 / $n * (($n - 1) * $x + ($num / pow($x, $n - 1)));
+ }
+
+ @return $x;
+}
diff --git a/scss/util/_util.scss b/scss/util/_util.scss
index c38b425474..6698812f45 100644
--- a/scss/util/_util.scss
+++ b/scss/util/_util.scss
@@ -2,6 +2,7 @@
// foundation.zurb.com
// Licensed under MIT Open Source
+@import 'math';
@import 'unit';
@import 'value';
@import 'color';
diff --git a/test/sass/_color.scss b/test/sass/_color.scss
index 3ae970bf54..854ca54b12 100755
--- a/test/sass/_color.scss
+++ b/test/sass/_color.scss
@@ -6,7 +6,7 @@
@include test-module('Color') {
@include test('Foreground (Black) [function]') {
- $test: foreground($white);
+ $test: color-pick-contrast($white);
$expect: $black;
@include assert-equal($test, $expect,
@@ -14,7 +14,7 @@
}
@include test('Foreground (White) [function]') {
- $test: foreground($black);
+ $test: color-pick-contrast($black);
$expect: $white;
@include assert-equal($test, $expect,