<button class="acl-button acl-button--tertiary">
<span class="acl-button__label">Click here</span>
</button>
<h3 class="acl-typography--subtitle1">Tertiary Button With Loading Spinner</h3>
<button class="acl-button acl-button--tertiary acl-demo-button" data-enable-loading-spinner>
<span class="acl-button__label">Click here</span>
<span class="acl-button__spinner"><svg class="acl-loader__circular" width="24px" height="24px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg">
<circle class="acl-loader__circular-background" fill="none" stroke="#2888d6" stroke-width="9" cx="33" cy="33" r="26">
</circle>
<circle class="acl-loader__circular-path" fill="none" stroke="#FFF" stroke-width="9" cx="33" cy="33" r="26">
</circle>
</svg></span>
</button>
<button class="acl-button acl-button--outlined acl-demo-button-stop">
<span class="acl-button__label">Stop Loading Spinner</span>
</button>
<style>
.acl-demo-button-stop {
display: none;
}
.acl-demo-button-stop--show {
display: inline;
}
</style>
<script>
const demoButton = document.querySelector('.acl-demo-button');
const demoButtonStop = document.querySelector('.acl-demo-button-stop');
demoButton.addEventListener('click', () => {
demoButton.getAttribute('data-loading') ?
demoButton.removeAttribute('data-loading') :
demoButton.setAttribute('data-loading', true);
demoButtonStop.classList.add('acl-demo-button-stop--show');
}, false);
demoButtonStop.addEventListener('click', () => {
demoButton.getAttribute('data-loading') ?
demoButton.removeAttribute('data-loading') : '';
demoButtonStop.classList.remove('acl-demo-button-stop--show');
}, false);
</script>
<button class="acl-button acl-button--tertiary">
<span class="acl-button__label">Click here</span>
</button>
<h3 class="acl-typography--subtitle1">Tertiary Button With Loading Spinner</h3>
<button class="acl-button acl-button--tertiary acl-demo-button" data-enable-loading-spinner>
<span class="acl-button__label">Click here</span>
<span class="acl-button__spinner"><svg class="acl-loader__circular" width="24px" height="24px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg">
<circle class="acl-loader__circular-background" fill="none" stroke="#2888d6" stroke-width="9" cx="33" cy="33"
r="26">
</circle>
<circle class="acl-loader__circular-path" fill="none" stroke="#FFF" stroke-width="9" cx="33" cy="33" r="26">
</circle>
</svg></span>
</button>
<button class="acl-button acl-button--outlined acl-demo-button-stop">
<span class="acl-button__label">Stop Loading Spinner</span>
</button>
<style>
.acl-demo-button-stop {
display: none;
}
.acl-demo-button-stop--show {
display: inline;
}
</style>
<script>
const demoButton = document.querySelector('.acl-demo-button');
const demoButtonStop = document.querySelector('.acl-demo-button-stop');
demoButton.addEventListener('click', () => {
demoButton.getAttribute('data-loading') ?
demoButton.removeAttribute('data-loading') :
demoButton.setAttribute('data-loading', true);
demoButtonStop.classList.add('acl-demo-button-stop--show');
}, false);
demoButtonStop.addEventListener('click', () => {
demoButton.getAttribute('data-loading') ?
demoButton.removeAttribute('data-loading') : '';
demoButtonStop.classList.remove('acl-demo-button-stop--show');
}, false);
</script>
/* No context defined. */
@import '../elevation/mixins';
@import '../feature-targeting/functions';
@import '../feature-targeting/mixins';
@import '../ripple/mixins';
@import '../rtl/mixins';
@import '../theme/functions';
@import '../theme/mixins';
@import '../touch-target/mixins';
@import '../typography/mixins';
@import '../shape/mixins';
@import '../shape/functions';
@import '../density/functions';
@import './variables';
$acl-button-ripple-target: '.acl-button__ripple';
@mixin acl-button-core-styles($query: acl-feature-all()) {
@include acl-button-without-ripple($query);
@include acl-button-ripple($query);
}
@mixin acl-button-theme-baseline($query: acl-feature-all()) {
.acl-button {
@include acl-button-density($acl-button-density-scale, $query: $query);
}
}
// This API is intended for use by frameworks that may want to separate the ripple-related styles from the other
// button styles. It is recommended that most users use `acl-button-core-styles` instead.
@mixin acl-button-without-ripple($query: acl-feature-all()) {
$feat-color: acl-feature-create-target($query, color);
$feat-structure: acl-feature-create-target($query, structure);
@include acl-touch-target-wrapper($query);
// postcss-bem-linter: define button
.acl-button {
@include acl-button-base_($query);
@include acl-button-shape-radius(small, $query: $query);
@include acl-button-container-fill-color(transparent, $query);
// The icon CSS class overrides styles defined in the .material-icons CSS
// class, which is loaded separately so the order of CSS definitions is not
// guaranteed. Therefore, increase specifity by nesting this class to ensure
// overrides apply.
.acl-button__icon {
@include acl-feature-targets($feat-structure) {
@include acl-button__icon_;
}
}
.acl-button__touch {
@include acl-touch-target($query);
}
@include acl-button-ink-color(primary, $query);
}
.acl-button__label + .acl-button__icon {
@include acl-feature-targets($feat-structure) {
@include acl-button__icon-trailing_;
}
}
// stylelint-disable-next-line selector-no-qualifying-type
svg.acl-button__icon {
@include acl-feature-targets($feat-structure) {
@include acl-button__icon-svg_;
}
}
.acl-button--raised,
.acl-button--unelevated,
.acl-button--outlined {
.acl-button__icon {
@include acl-feature-targets($feat-structure) {
// Icons inside contained buttons have different styles due to increased button padding
@include acl-button__icon-contained_;
}
}
.acl-button__label + .acl-button__icon {
@include acl-feature-targets($feat-structure) {
@include acl-button__icon-contained-trailing_;
}
}
}
.acl-button--raised,
.acl-button--unelevated {
@include acl-button--filled_($query);
@include acl-button-container-fill-color(primary, $query);
@include acl-button-ink-color(on-primary, $query);
}
.acl-button--raised {
@include acl-button--raised_($query);
}
.acl-button--outlined {
@include acl-button--outlined_($query);
@include acl-button-outline-width($acl-button-outlined-border-width, $query: $query);
@include acl-button-outline-color(primary, $query);
}
.acl-button--touch {
@include acl-touch-target-component($component-height: $acl-button-height, $query: $query);
}
// postcss-bem-linter: end
}
// This API is intended for use by frameworks that may want to separate the ripple-related styles from the other
// button styles. It is recommended that most users use `acl-button-core-styles` instead.
@mixin acl-button-ripple($query: acl-feature-all()) {
$feat-structure: acl-feature-create-target($query, structure);
@include acl-ripple-common($query);
.acl-button {
@include acl-ripple-surface($query: $query, $ripple-target: $acl-button-ripple-target);
@include acl-ripple-radius-bounded($query: $query, $ripple-target: $acl-button-ripple-target);
@include acl-states($color: primary, $query: $query, $ripple-target: $acl-button-ripple-target);
#{$acl-button-ripple-target} {
@include acl-feature-targets($feat-structure) {
position: absolute;
// Ripple needs content-box as the box sizing and box-sizing: border-box
// is often set as a default, so we override that here.
box-sizing: content-box;
width: 100%;
height: 100%;
overflow: hidden;
}
}
// Ripple targets inside outlined buttons set their own `top`/`left`,
// depending on the border width.
&:not(.acl-button--outlined) #{$acl-button-ripple-target} {
@include acl-feature-targets($feat-structure) {
top: 0;
left: 0;
}
}
}
.acl-button--raised,
.acl-button--unelevated {
@include acl-states($color: on-primary, $query: $query, $ripple-target: $acl-button-ripple-target);
}
}
@mixin acl-button-filled-accessible($container-fill-color, $query: acl-feature-all()) {
$fill-tone: acl-theme-tone($container-fill-color);
@include acl-button-container-fill-color($container-fill-color, $query);
@if ($fill-tone == 'dark') {
@include acl-button-ink-color(text-primary-on-dark, $query);
@include acl-states($color: text-primary-on-dark, $query: $query, $ripple-target: $acl-button-ripple-target);
} @else {
@include acl-button-ink-color(text-primary-on-light, $query);
@include acl-states($color: text-primary-on-light, $query: $query, $ripple-target: $acl-button-ripple-target);
}
}
@mixin acl-button-container-fill-color($color, $query: acl-feature-all()) {
$feat-color: acl-feature-create-target($query, color);
// :not(:disabled) is used to support link styled as button
// as link does not support :enabled style
&:not(:disabled) {
@include acl-feature-targets($feat-color) {
@include acl-theme-prop(background-color, $color, $edgeOptOut: true);
}
}
}
@mixin acl-button-outline-color($color, $query: acl-feature-all()) {
$feat-color: acl-feature-create-target($query, color);
&:not(:disabled) {
@include acl-feature-targets($feat-color) {
@include acl-theme-prop(border-color, $color);
}
}
}
@mixin acl-button-icon-color($color, $query: acl-feature-all()) {
$feat-color: acl-feature-create-target($query, color);
&:not(:disabled) .acl-button__icon {
@include acl-feature-targets($feat-color) {
@include acl-theme-prop(color, $color);
}
}
}
@mixin acl-button-ink-color($color, $query: acl-feature-all()) {
$feat-color: acl-feature-create-target($query, color);
&:not(:disabled) {
@include acl-feature-targets($feat-color) {
@include acl-theme-prop(color, $color);
}
}
}
///
/// Sets density scale for button.
///
/// @param {Number | String} $density-scale - Density scale value for component. Supported density scale values `-3`,
/// `-2`, `-1`, `0`.
///
@mixin acl-button-density($density-scale, $query: acl-feature-all()) {
$height: acl-density-prop-value(
$density-config: $acl-button-density-config,
$density-scale: $density-scale,
$property-name: height,
);
@include acl-button-height($height, $query: $query);
@if $density-scale != 0 {
@include acl-button-touch-target-reset_($query: $query);
}
}
///
/// Resets touch target-related styles. This is called from the density mixin to
/// automatically remove the increased touch target, since dense components
/// don't have the same default a11y requirements.
/// @access private
///
@mixin acl-button-touch-target-reset_($query: acl-feature-all()) {
$feat-structure: acl-feature-create-target($query, structure);
@include acl-feature-targets($feat-structure) {
margin-top: 0;
margin-bottom: 0;
}
.acl-button__touch {
@include acl-feature-targets($feat-structure) {
display: none;
}
}
}
@mixin acl-button-height($height, $query: $query) {
$feat-structure: acl-feature-create-target($query, structure);
@include acl-feature-targets($feat-structure) {
height: $height;
}
}
@mixin acl-button-shape-radius(
$radius,
$rtl-reflexive: false,
$density-scale: $acl-button-density-scale,
$query: acl-feature-all()
) {
$height: acl-density-prop-value(
$density-config: $acl-button-density-config,
$density-scale: $density-scale,
$property-name: height,
);
$resolved-radius: acl-shape-resolve-percentage-radius($height, $radius);
@include acl-shape-radius($resolved-radius, $rtl-reflexive, $query: $query);
#{$acl-button-ripple-target} {
@include acl-shape-radius($resolved-radius, $rtl-reflexive, $query: $query);
}
}
@mixin acl-button-horizontal-padding($padding, $query: acl-feature-all()) {
$feat-structure: acl-feature-create-target($query, structure);
@include acl-feature-targets($feat-structure) {
// $padding should be a single value; enforce it by specifying all 4 sides in the output
padding: 0 $padding 0 $padding;
}
}
@mixin acl-button-outline-width(
$outline-width,
$padding: $acl-button-contained-horizontal-padding,
$query: acl-feature-all()
) {
$feat-structure: acl-feature-create-target($query, structure);
// Note: Adjust padding to maintain consistent width with non-outlined buttons
$padding-value: max($padding - $outline-width, 0);
@include acl-button-horizontal-padding($padding-value, $query);
@include acl-feature-targets($feat-structure) {
border-width: $outline-width;
}
#{$acl-button-ripple-target} {
@include acl-feature-targets($feat-structure) {
top: -$outline-width;
left: -$outline-width;
border: $outline-width solid transparent;
}
}
}
@mixin acl-button-base_($query) {
$feat-color: acl-feature-create-target($query, color);
$feat-structure: acl-feature-create-target($query, structure);
@include acl-typography(button, $query);
@include acl-button-horizontal-padding($acl-button-horizontal-padding, $query);
@include acl-feature-targets($feat-structure) {
display: inline-flex;
position: relative;
align-items: center;
justify-content: center;
box-sizing: border-box;
min-width: 64px;
border: none;
outline: none;
/* @alternate */
line-height: inherit;
user-select: none;
-webkit-appearance: none;
// Even though `visible` is the default, IE 11 computes the property as
// `hidden` in some cases, unless it's explicitly defined here.
overflow: visible;
vertical-align: middle;
}
&::-moz-focus-inner {
@include acl-feature-targets($feat-structure) {
padding: 0;
border: 0;
}
}
// postcss-bem-linter: ignore
&:active {
@include acl-feature-targets($feat-structure) {
outline: none;
}
}
&:hover {
@include acl-feature-targets($feat-structure) {
cursor: pointer;
}
}
&:disabled {
@include acl-feature-targets($feat-color) {
@include acl-theme-prop(background-color, transparent);
color: $acl-button-disabled-ink-color;
}
@include acl-feature-targets($feat-structure) {
cursor: default;
pointer-events: none;
}
}
}
@mixin acl-button__icon_ {
@include acl-rtl-reflexive-box(margin, right, 8px);
display: inline-block;
width: 18px;
height: 18px;
font-size: 18px;
vertical-align: top;
}
@mixin acl-button__icon-trailing_ {
@include acl-rtl-reflexive-box(margin, left, 8px);
}
@mixin acl-button__icon-svg_ {
fill: currentColor;
}
@mixin acl-button__icon-contained_ {
@include acl-rtl-reflexive-property(margin, -4px, 8px);
}
@mixin acl-button__icon-contained-trailing_ {
@include acl-rtl-reflexive-property(margin, 8px, -4px);
}
@mixin acl-button--outlined_($query) {
$feat-color: acl-feature-create-target($query, color);
$feat-structure: acl-feature-create-target($query, structure);
@include acl-feature-targets($feat-structure) {
border-style: solid;
}
&:disabled {
@include acl-feature-targets($feat-color) {
border-color: $acl-button-disabled-ink-color;
}
}
}
@mixin acl-button--filled_($query) {
$feat-color: acl-feature-create-target($query, color);
$feat-structure: acl-feature-create-target($query, structure);
@include acl-button-horizontal-padding($acl-button-contained-horizontal-padding, $query);
&:disabled {
@include acl-feature-targets($feat-color) {
background-color: rgba(acl-theme-prop-value(on-surface), 0.12);
color: $acl-button-disabled-ink-color;
}
}
}
@mixin acl-button--raised_($query) {
$feat-animation: acl-feature-create-target($query, animation);
$feat-color: acl-feature-create-target($query, color);
@include acl-elevation(2, $query: $query);
&:hover,
&:focus {
@include acl-elevation(4, $query: $query);
}
&:active {
@include acl-elevation(8, $query: $query);
}
&:disabled {
@include acl-elevation(0, $query: $query);
}
@include acl-feature-targets($feat-animation) {
transition: acl-elevation-transition-value();
}
}
@import '../density/variables';
@import '../theme/variables'; // for acl-theme-prop-value
$acl-button-height: 36px !default;
$acl-button-horizontal-padding: 8px !default;
$acl-button-contained-horizontal-padding: 16px !default;
$acl-button-minimum-height: 24px !default;
$acl-button-maximum-height: $acl-button-height !default;
$acl-button-density-scale: $acl-density-default-scale !default;
$acl-button-density-config: (
height: (
default: $acl-button-height,
maximum: $acl-button-maximum-height,
minimum: $acl-button-minimum-height,
),
) !default;
$acl-button-outlined-border-width: 1px !default;
$acl-button-shape-radius: small !default;
$acl-button-disabled-ink-color: rgba(acl-theme-prop-value(on-surface), 0.37) !default;
@import './mixins';
@include acl-button-core-styles;
@include acl-button-theme-baseline;
.acl-button {
@include acl-button-shape-radius(5px);
font-family: 'Open Sans';
font-size: 14px;
font-weight: 600;
line-height: 18px;
text-transform: unset;
letter-spacing: 0;
min-width: 105px;
position: relative;
&[data-loading] {
border-color: rgba(0, 0, 0, 0.07);
cursor: default;
pointer-events: none;
}
&[data-enable-loading-spinner] {
overflow: hidden;
&.acl-button__icon-label {
position: relative;
}
&.acl-button__spinner {
left: 50%;
margin-left: -16px;
margin-top: 1em;
}
}
&[data-enable-loading-spinner][data-loading] {
.acl-button__label,
.acl-button__icon-label {
opacity: 0;
top: -1em;
}
.acl-button__spinner {
opacity: 1;
margin-top: -14.5px;
}
}
&:hover {
background-color: RGBA(53, 195, 170, 0.12);
opacity: 1;
}
&:active {
background-color: RGBA(53, 195, 170, 0.29);
opacity: 1;
}
&__spinner {
position: absolute;
width: 25px;
height: 25px;
top: 50%;
margin-top: -14.5px;
opacity: 0;
}
&--raised {
border: 1px solid #2cbcb2;
background-color: #46ccc2;
box-shadow: none;
&:hover {
box-shadow: none;
background-color: RGBA(53, 195, 170, 0.8);
}
&:focus {
box-shadow: none;
}
&:active {
background-color: RGBA(53, 195, 170, 1);
}
}
&--raised-rounded {
border-radius: 30px;
}
&--raised-disabled {
border: 1px solid #f7f6fb !important;
background-color: #f7f6fb !important;
color: rgba(0, 0, 0, 0.25) !important;
box-shadow: none;
cursor: not-allowed !important;
&:hover {
box-shadow: none;
}
&:hover,
&:active {
opacity: 1;
}
}
&--outlined {
&:hover {
background-color: RGBA(53, 195, 170, 0.12);
opacity: 1;
}
&:active {
background-color: RGBA(53, 195, 170, 0.29);
opacity: 1;
}
}
&--outlined-disabled {
border: 1px solid #f7f6fb !important;
color: rgba(0, 0, 0, 0.25) !important;
cursor: not-allowed !important;
&:hover {
background-color: $white;
opacity: 1;
}
&:active {
background-color: $white;
opacity: 1;
}
}
&--front-icon {
margin-right: 7px;
}
&__icon-button {
width: 44px;
height: 44px;
background-color: $white;
display: flex;
justify-content: center;
align-items: center;
color: $teal;
box-shadow: 0 2px 8px 2px rgba(0, 0, 0, 0.15);
cursor: pointer;
border-radius: 5px;
border: none;
position: relative;
&[data-loading] {
border-color: rgba(0, 0, 0, 0.07);
cursor: default;
pointer-events: none;
}
&[data-enable-loading-spinner] {
&.acl-button__icon-spinner {
left: 50%;
margin-left: -14px;
margin-top: 1em;
}
}
&[data-enable-loading-spinner][data-loading] {
.acl-button__icon-label {
opacity: 0;
top: -1em;
}
.acl-button__icon-spinner {
opacity: 1;
margin-top: -14.5px;
}
}
i {
font-size: 18px;
}
&:hover {
background-color: $teal-darker;
color: $white;
}
&--basic {
box-shadow: none;
background-color: inherit;
i {
color: $grey;
user-select: none;
}
&:hover {
background-color: inherit;
i {
color: #707893;
}
}
}
&--white-icon {
box-shadow: none;
background-color: unset;
i {
color: $white;
user-select: none;
}
&:hover {
background-color: unset;
}
}
&--rounded {
border-radius: 50%;
user-select: none;
}
&--rounded-corners {
border-radius: 8px;
}
&--flat {
box-shadow: none;
}
&--background-colour {
&-none {
background-color: none;
}
&-light-teal {
background-color: #e4f8f6;
}
&-teal {
background-color: #2cbcb2;
}
&-orange {
background-color: #ff985a;
}
&-grey {
background-color: #707893;
}
&-purple {
background-color: #2200b7;
}
&-light-blue {
background-color: #2888d6;
}
&-dark-blue {
background-color: #43749e;
}
&-light-red {
background-color: #ffe7e7;
&:hover {
background-color: #ff3131;
color: $white;
}
}
}
&--icon-colour {
&-teal {
color: #2cbcb2;
}
&-orange {
color: #ff985a;
}
&-grey {
color: #707893;
}
&-purple {
color: #2200b7;
}
&-light-blue {
color: #2888d6;
}
&-dark-blue {
color: #43749e;
}
&-black {
color: $black;
}
&-white {
color: $white;
}
&-red {
color: #ff3131;
}
}
&--extra-small {
width: 24px;
height: 24px;
i {
font-size: 24px;
}
}
&--small {
width: 30px;
height: 30px;
i {
font-size: 28px;
}
}
&--medium {
width: 36px;
height: 36px;
i {
font-size: 26px;
user-select: none;
}
}
&--large {
width: 50px;
height: 50px;
i {
font-size: 32px;
}
}
}
&__icon-size {
&--xsmall {
i {
font-size: 17px;
}
}
}
&__icon-spinner {
position: absolute;
width: 28px;
height: 28px;
top: 50%;
margin-top: -13.5px;
opacity: 0;
&--extra-small {
width: 24px;
height: 24px;
}
}
&--tertiary {
height: 30px;
.acl-button__label {
background-color: #e5f7ff;
border-radius: 4px;
width: 100%;
height: 100%;
color: #2888d6;
display: flex;
justify-content: center;
align-items: center;
min-width: 105px;
font-size: 12px;
font-weight: 600;
letter-spacing: 0;
line-height: 17px;
text-align: center;
&:hover {
background-color: #dfedf9;
}
&:active {
background-color: #e5f7ff;
}
}
&:hover {
background-color: unset;
}
&:focus {
box-shadow: none;
}
&:active {
background-color: unset;
}
}
}
// Easing
.acl-button,
.acl-button__label,
.acl-button .acl-button__spinner,
.acl-button .acl-button__label,
.acl-button__icon .acl-button__icon-spinner,
.acl-button__icon .acl-button__icon-label {
-webkit-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all;
-moz-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all;
-ms-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all;
transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all;
}
Buttons allow users to take actions, and make choices, with a single tap.
npm install ..//button<button class="acl-button">
<div class="acl-button__ripple"></div>
<span class="acl-button__label">Button</span>
</button>NOTE: Examples here use the generic
<button>, but users can also apply theacl-buttonclass to<a>elements.
@import "../button/acl-button";The button will work without JavaScript, but you can enhance it to have a ripple effect by instantiating MDCRipple on the root element. See MDC Ripple for details.
import {MDCRipple} from '..//ripple';
const buttonRipple = new MDCRipple(document.querySelector('.acl-button'));See Importing the JS component for more information on how to import JavaScript.
To style a contained button, add the acl-button--raised class to the <button> element for a contained button with elevation, or the acl-button--unelevated class for a contained button flush with the surface.
To style an outlined button, add the class acl-button--outlined to the <button> element.
We recommend using Material Icons from Google Fonts:
<head>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
</head>However, you can also use SVG, Font Awesome, or any other icon library you wish.
To add an icon, add an element with the acl-button__icon class inside the button element and set the attribute aria-hidden="true". The icon is set to 18px to meet legibility requirements.
<button class="acl-button">
<div class="acl-button__ripple"></div>
<i class="material-icons acl-button__icon" aria-hidden="true">favorite</i>
<span class="acl-button__label">Button</span>
</button>It’s also possible to use an SVG icon:
<button class="acl-button">
<div class="acl-button__ripple"></div>
<svg class="acl-button__icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="...">
...
</svg>
<span class="acl-button__label">Button</span>
</button>Certain icons make more sense to appear after the button’s text label rather than before. This can be accomplished by
putting the icon markup after the acl-button__label element.
<button class="acl-button">
<div class="acl-button__ripple"></div>
<span class="acl-button__label">Button</span>
<i class="material-icons acl-button__icon" aria-hidden="true">favorite</i>
</button>NOTE: The
acl-button__labelelement is required in order for the trailing icon to be styled appropriately.
To disable a button, add the disabled attribute directly to the <button>, or set the disabled attribute on the <fieldset> containing the button.
Disabled buttons cannot be interacted with and have no visual interaction effect.
<button class="acl-button" disabled>
<div class="acl-button__ripple"></div>
<span class="acl-button__label">Button</span>
</button>Material Design spec advises that touch targets should be at least 48 x 48 px. To meet this requirement, add the following to your button:
<div class="acl-touch-target-wrapper">
<button class="acl-button acl-button--touch">
<div class="acl-button__ripple"></div>
<span class="acl-button__label">My Accessible Button</span>
<div class="acl-button__touch"></div>
</button>
</div>Note that the outer acl-touch-target-wrapper element is only necessary if you want to avoid potentially overlapping touch targets on adjacent elements (due to collapsing margins).
| CSS Class | Description |
|---|---|
acl-button |
Mandatory. Defaults to a text button that is flush with the surface. |
acl-button__ripple |
Mandatory. Indicates the element which shows the ripple styling. |
acl-button--raised |
Optional. Styles a contained button that is elevated above the surface. |
acl-button--unelevated |
Optional. Styles a contained button that is flush with the surface. |
acl-button--outlined |
Optional. Styles an outlined button that is flush with the surface. |
acl-button__label |
Recommended.* Indicates the element containing the button’s text label. |
acl-button__icon |
Optional. Indicates the element containing the button’s icon. |
*NOTE: The
acl-button__labelelement is required for buttons with a trailing icon, but it is currently optional for buttons with no icon or a leading icon. In the latter cases, it is acceptable for the text label to simply exist directly within theacl-buttonelement. However, theacl-button__labelclass may become mandatory for all cases in the future, so it is recommended to always include it to be future-proof.
To customize a button’s color and properties, you can use the following mixins.
MDC Button uses MDC Theme‘s primary color by default. Use the following mixins to customize it.
| Mixin | Description |
|---|---|
acl-button-filled-accessible($container-fill-color) |
Sets the container fill color for a contained (raised or unelevated) button, and updates the button’s ink, icon, and ripple colors to meet accessibility standards |
These mixins will override the color of the container, ink, outline or ripple. It is up to you to ensure your button meets accessibility standards.
| Mixin | Description |
|---|---|
acl-button-container-fill-color($color) |
Sets the container fill color to the given color. |
acl-button-icon-color($color) |
Sets the icon color to the given color. |
acl-button-ink-color($color) |
Sets the ink color to the given color, and sets the icon color to the given color unless acl-button-icon-color is also used. |
acl-button-density($density-scale) |
Sets density scale for button. Supported density scale values (-3, -2, -1, 0). |
acl-button-height($height) |
Sets custom height of button. |
acl-button-shape-radius($radius, $density-scale, $rtl-reflexive) |
Sets rounded shape to button with given radius size. $density-scale is only required when $radius value is in percentage unit, defaults to $acl-button-density-default-scale. Set $rtl-reflexive to true to flip radius values in RTL context, defaults to false. |
acl-button-horizontal-padding($padding) |
Sets horizontal padding to the given number. |
acl-button-outline-color($color) |
Sets the outline color to the given color. |
acl-button-outline-width($width, $padding) |
Sets the outline width to the given number (defaults to 2px) and adjusts padding accordingly. $padding is only required in cases where acl-button-horizontal-padding is also included with a custom value. |
In browsers that fully support CSS custom properties, the above mixins will work if you pass in a MDC Theme property (e.g. primary) as an argument. However, Edge does not fully support CSS custom properties. If you are using the acl-button-container-fill-color mixin, you must pass in an actual color value for support in Edge.