From aa0ca16dbe67a5e5c87dcc6e6797dd7f9d35037d Mon Sep 17 00:00:00 2001 From: Guy Gascoigne-Piggford Date: Fri, 25 Aug 2017 11:12:40 -0700 Subject: [PATCH] feat(buttons): change styles to match UX preferences == DETAILS Our style guide has focused down on three button styles only (generic, positive and negative), and this change set just updates that subset. In all cases, the hover and active styles are darker than the default state, the active and focus states all have outlines. See the image for details. Note that the focus outlines don't really play well with ButtonGroups, but we aren't using these at this point so I think that that can be deferred until a later date. For now, there are no outlines within button groups. Given how SUIR doesn't use outlines at all, there's not a lot of support for outlines that overlap adjacent elements. I think that this is fixable using z-index changes in the focus style but didn't feel that it was worth the time to dig in on this for a feature that we're not using. I've updated the Button example to remove the options that we weren't using since they were confusing developers who went and used them. I fixed a bunch of issues where hover styles didn't apply to focused buttons - this was an old bug that was hidden by the previous similarity of the styles. The bottom line is that there's a standard order in which to define the pseudo classes, (which is: Link, Visited, Focus, Hover, Active), and we weren't doing this, now we are. The final twist is using a sequence of box-shadows to achieve the focus outline. This seems to be a consistently cross-platform and cross-browser compatible way to get what we wanted, the alternatives either looked awful (IMNSHO) or were inconsistent between browsers or OSs. == TESTS Lots of exercising in the browser, the animation should show most of this. --- .../themes/tripwire/elements/button.overrides | 133 ++++++++++-------- .../themes/tripwire/elements/button.variables | 25 +++- .../themes/tripwire/elements/input.variables | 2 +- src/components/suir/button/Button.examples.md | 105 ++++++++------ 4 files changed, 167 insertions(+), 98 deletions(-) diff --git a/semantic/src/themes/tripwire/elements/button.overrides b/semantic/src/themes/tripwire/elements/button.overrides index 86c2963..b6530d2 100644 --- a/semantic/src/themes/tripwire/elements/button.overrides +++ b/semantic/src/themes/tripwire/elements/button.overrides @@ -4,55 +4,60 @@ .ui.button { - color: @grey; - border: 2px solid #A6A8AB; + color: @blue; + border: 2px solid @blue; background: @white; - border-radius: 0px; + border-radius: 2px; } +.ui.buttons .button:first-child, .ui.button.primary { border: 2px solid @primaryColor; } + .ui.button.primary:hover { border-color: @primaryColorHover; } -.ui.button:active, -.ui.active.button:active { +.ui.button:focus { border-color: @blue; - color: @white; - background: @blue; -} -.ui.active.button { - border-color: @blue; - color: @white; - background: @blue; + color: @blue; + background: @white; + box-shadow: @focusedButtonShadow; } -.ui.button:focus, .ui.button:hover { - border-color: @hoverBackgroundColor; - color: @white; -} -.ui.button:active { border-color: @blue; - color: @white; + color: @invertedTextColor; background: @blue; } + +.ui.button:active, +.ui.active.button:active, .ui.active.button { border-color: @blue; - color: @white; + color: @invertedTextColor; background: @blue; + box-shadow: @focusedButtonShadow; } + .ui.active.button:hover { border-color: @blue; - color: @white; + color: @invertedTextColor; background: @blue; } .ui.active.button:active { border-color: @blue; - color: @white; + color: @invertedTextColor; background: @blue; + box-shadow: @focusedButtonShadow; +} + +.ui.disabled.button { + background-color: @white; + border-color: @genericDisabledBorder; + color: @disabledText; + opacity: 100 !important; } /*--------------- @@ -64,44 +69,53 @@ .ui.positive.button { background-color: @blue; border-color: @blue; - color: @white; + color: @invertedTextColor; text-shadow: @positiveTextShadow; background-image: @coloredBackgroundImage; } + +.ui.buttons .ui.positive.button:first-child { + border-style: solid; + border-width: 2px; +} + .ui.positive.button { box-shadow: @coloredBoxShadow; } -.ui.positive.buttons .button:hover, -.ui.positive.button:hover { - background-color: @primaryColorHover; - border-color: @primaryColorHover; - color: @white; - text-shadow: @positiveTextShadow; -} .ui.positive.buttons .button:focus, .ui.positive.button:focus { - background-color: @primaryColorHover; - border-color: @primaryColorHover; - color: @white; + background-color: @blue; + border-color: @blue; + color: @invertedTextColor; text-shadow: @positiveTextShadow; + box-shadow: @focusedButtonShadow; } -.ui.positive.buttons .button:active, -.ui.positive.button:active { +.ui.positive.buttons .button:hover, +.ui.positive.button:hover { background-color: @primaryColorHover; border-color: @primaryColorHover; - color: @white; + color: @invertedTextColor; text-shadow: @positiveTextShadow; } +.ui.positive.buttons .button:active, +.ui.positive.button:active, .ui.positive.buttons .active.button, .ui.positive.buttons .active.button:active, .ui.positive.active.button, .ui.positive.button .active.button:active { background-color: @primaryColorHover; border-color: @primaryColorHover; - color: @white; + color: @invertedTextColor; text-shadow: @positiveTextShadow; + box-shadow: @focusedButtonShadow; } +.ui.positive.disabled.button { + background-color: @positiveDisabledBackground; + border-color: @positiveDisabledBackground; + color: @disabledText; + opacity: 100 !important; +} /*--------------- Negative @@ -111,43 +125,52 @@ .ui.negative.buttons .button, .ui.negative.button { background: @white; - color: @grey; - border: 2px solid #A6A8AB; + color: @negativeTextColor; + border: 2px solid @negativeBorder; text-shadow: @negativeTextShadow; background-image: @coloredBackgroundImage; } .ui.negative.button { box-shadow: @coloredBoxShadow; } -.ui.negative.buttons .button:hover, -.ui.negative.button:hover { - background: @secondaryColorHover; - color: @grey; - border: 2px solid @secondaryColorHover; - text-shadow: @negativeTextShadow; +.ui.buttons .ui.negative.button:first-child { + border: 2px solid @negativeBorder; } .ui.negative.buttons .button:focus, .ui.negative.button:focus { - background: @secondaryColorHover; - color: @grey; - border: 2px solid @secondaryColorHover; + background: @white; + color: @negativeTextColor; + border: 2px solid @negativeBorder; text-shadow: @negativeTextShadow; + background-image: @coloredBackgroundImage; + box-shadow: @focusedButtonShadow; } -.ui.negative.buttons .button:active, -.ui.negative.button:active { - background: @secondaryColorHover; - color: @grey; - border: 2px solid @secondaryColorHover; +.ui.negative.buttons .button:hover, +.ui.negative.button:hover, +.ui.buttons .ui.negative.button:hover:first-child { + background: @negativeInverted; + color: @invertedTextColor; + border: 2px solid @negativeInverted; text-shadow: @negativeTextShadow; } +.ui.negative.buttons .button:active, +.ui.negative.button:active, .ui.negative.buttons .active.button, .ui.negative.buttons .active.button:active, .ui.negative.active.button, .ui.negative.button .active.button:active { - background: @secondaryColorHover; - color: @grey; - border: 2px solid @secondaryColorHover; + background: #999999; + color: @invertedTextColor; + border: 2px solid @negativeInverted; text-shadow: @negativeTextShadow; + box-shadow: @focusedButtonShadow; +} + +.ui.negative.disabled.button { + background-color: @white; + border-color: @negativeDisabledBorder; + color: @disabledText; + opacity: 100 !important; } /*-------------- diff --git a/semantic/src/themes/tripwire/elements/button.variables b/semantic/src/themes/tripwire/elements/button.variables index 0a69898..e69381c 100644 --- a/semantic/src/themes/tripwire/elements/button.variables +++ b/semantic/src/themes/tripwire/elements/button.variables @@ -131,6 +131,21 @@ opacity @defaultDuration @defaultEasing ; +/* +note that this double box shadow is a pretty good copy of the webkit default: + outline: 5px auto @selectedSolidWhiteBorderColor 0; + +The alternative was +outline-color: @selectedSolidWhiteBorderColor; +outline-offset: 1px; +outline-style: solid; +outline-width: 2px; + +which ends out being a hard edged box rather than the slightly blurred outline +*/ + +@focusedButtonShadow: 0 0 0 1px @white, 0 0 1px 4px #bfbebe; + /*------------------- Types --------------------*/ @@ -315,6 +330,12 @@ @lightGreyTextShadow: @textShadow; +@disabledText: #ababab; +@genericDisabledBorder: #cccccc; +@negativeDisabledBorder: #cccccc; +@negativeBorder: #bdc3c7; +@negativeInverted: #999999; + /* Ordinality */ @primaryBackgroundImage: @coloredBackgroundImage; @primaryTextColor: @invertedTextColor; @@ -330,10 +351,10 @@ @positiveTextColor: @invertedTextColor; @positiveTextShadow: @invertedTextShadow; @positiveBoxShadow: @coloredBoxShadow; - +@positiveDisabledBackground: #ebebeb; @negativeBackgroundImage: @coloredBackgroundImage; -@negativeTextColor: @invertedTextColor; +@negativeTextColor: #454545; @negativeTextShadow: @invertedTextShadow; @negativeBoxShadow: @coloredBoxShadow; diff --git a/semantic/src/themes/tripwire/elements/input.variables b/semantic/src/themes/tripwire/elements/input.variables index 77a6be9..20f9f14 100644 --- a/semantic/src/themes/tripwire/elements/input.variables +++ b/semantic/src/themes/tripwire/elements/input.variables @@ -81,7 +81,7 @@ /* Error */ @errorBackground: @negativeBackgroundColor; -@errorColor: @negativeTextColor; +@errorColor: @invertedTextColor; @errorBorder: @negativeBorderColor; @errorBoxShadow: none; diff --git a/src/components/suir/button/Button.examples.md b/src/components/suir/button/Button.examples.md index 45c5888..846a1e3 100644 --- a/src/components/suir/button/Button.examples.md +++ b/src/components/suir/button/Button.examples.md @@ -1,69 +1,94 @@ -## Generic - - const Button = require('semantic-ui-react').Button; - - ## Positive Button const Button = require('semantic-ui-react').Button;
- + + +
## Negative Button const Button = require('semantic-ui-react').Button; - +
+ + + +
-## Primary Button +## Generic const Button = require('semantic-ui-react').Button;
- - - + + +
-## Secondary Button +## Button Groups const Button = require('semantic-ui-react').Button;
- - - +
+ + + + + +
+

+

+ + + + + +
+

+

+ + + + + +
+

+

+ + + + + +
-## Disabled Button +## Test const Button = require('semantic-ui-react').Button; - +
+
+ + +
+

+

+ + +
+

+

+ + +
+
+ ## Active Button