Huesos
Style
Guide

Repositoire

GitHub

Preview

Button

Applies to <input>, <button> or <a>. Without the .button class, only a reset is applied.

You can define a separate appearance for every button state (default and hover). We decided to decouple both states in order to give more room for custom styling and combinations, instead of enforcing a default hover state for every different style.

These are the available strategies:

  • outline - Colored outline and text, background transparent.
  • background - Background solid, text contrasted against the background.
  • split - Background lightened, font darkened, based on same color.
  • split-inverse - Inverse of split.

Use this values to define a $button-strategy-defaultand a $button-strategy-hover.

Some common examples are:

/* Button with outline that fills with color on hover (default) */  
$button-strategy-default: 'outline';
$button-strategy-hover: 'background';
/* Button with solid background that darkens on hover */
$button-strategy-default: 'background';
$button-strategy-hover: 'split-inverse';
/* Button with split colors that are set to inverse on hover */
$button-strategy-default: 'split';
$button-strategy-hover: 'split-inverse';

Disabled buttons

Instead of using a custom .button--disabled class, disable buttons by usign the global .disabled helper class.

This class is configured to detect context and apply the correct disabling properties.

Alternative buttons.

Alternative strategies can be created by populating the $button-alternative-strategies map with combinations of default and hover values.

We provide a commented example on _config.scss

$button-alternative-strategies: (
    split : (
        default : 'split', 
        hover : 'split-inverse'
    ),
);

The generated classes will take the following format: .button--#{variant}--#{strategy}. For example, the split strategy consisting of split as default and split-inverse as hover becomes .button--primary--split for the primary variant, .button--error--split por the error variant and so on…

Setting $button-alternative-strategies to a falsy value avoids the programatic generation of classes and avoids bloating your css.

Why a .button class?

Styling all posible combinations of <input>, <a class="button"> and <button> elements, their variations and their adjacent / sibling selectors results on a unnecesarily bloated css.

A Bootstrap-like approach where the .button class simply ensures a global reset and every modifier applies a style allows for better customization.

Example

<!-- Default -->
<div class="mb">
    <button class="button ">Unstyled button</button>
    <a href="#" class="button ">Unstyled button</a>
    <input type="submit" class="button " value="Unstyled button" />
</div>

<!-- Primary -->
<div class="mb">
    <button class="button button--primary">Primary</button>
    <a href="#" class="button button--primary">Primary</a>
    <input type="submit" class="button button--primary" value="Primary" />
</div>

<!-- Secondary -->
<div class="mb">
    <button class="button button--secondary">Secondary</button>
    <a href="#" class="button button--secondary">Secondary</a>
    <input type="submit" class="button button--secondary" value="Secondary" />
</div>

<!-- Success -->
<div class="mb">
    <button class="button button--success">Success</button>
    <a href="#" class="button button--success">Success</a>
    <input type="submit" class="button button--success" value="Success" />
</div>

<!-- Warning -->
<div class="mb">
    <button class="button button--warning">Warning</button>
    <a href="#" class="button button--warning">Warning</a>
    <input type="submit" class="button button--warning" value="Warning" />
</div>

<!-- Error -->
<div class="mb">
    <button class="button button--error">Error</button>
    <a href="#" class="button button--error">Error</a>
    <input type="submit" class="button button--error" value="Error" />
</div>

<!-- Disabled -->
<div class="mb">
    <button class="button button--primary disabled">Disabled</button>
    <a href="#" class="button button--primary disabled">Disabled</a>
    <input type="submit" class="button button--primary disabled" value="Disabled" />
</div>

Assets

  • Filesystem Path: src/components/elements/button/_button.scss
  • Size: 1.4 KB
  • Content:
    // Explicit overrides for link buttons
    // This need to be set before the global button
    a.button {
    	@include kill-link();
    }
    
    // Global reset
    .button {
    	@include form-reset-button();
    	@include ritmo-font-size($button-font-size, $base-line-multi);
    	text-transform: uppercase;
    	letter-spacing: 0.05rem;
    	vertical-align:bottom;
    	font-weight: $button-weight;
    	font-family: $button-font-family;
    
    	// Icons inside buttons
    	.icon {
    		@include ritmo-font-size($h6-font-size);
    		height: $h6-font-size;
    		line-height:1;
    		svg {
    			fill:currentColor;
    		}
    	}
    }
    
    
    // Adjacent buttons
    .button + .button {
    	margin-left:$gutter / 4;
    }
    
    // $button-states map states to colors
    @each $key, $value in $button-states {
    	.button--#{$key} {
    		@include style-button($value);
    	}
    	a.button--#{$key} {
    		@include style-link-button($value);
    	}
    }
    
    // Button alternative styles
    @if $button-alternative-strategies {
    	@each $strategy, $states in $button-alternative-strategies {
    		@each $key, $value in $button-states {
    			.button--#{$key}--#{$strategy} {
    				@include style-button($value, map-get($states, default), map-get($states, hover));
    			}
    			a.button--#{$key}--#{$strategy} {
    				@include style-link-button($value, map-get($states, default), map-get($states, hover));
    			}
    		}
    	}
    }
    
    
    .button.disabled {
    	opacity: $disabled-opacity;
    	cursor: arrow;
    	pointer-events:none;
    	&:hover, 
    	&:focus {
            cursor: arrow;
    	}
    }