262

I use hover, active and disabled to style Buttons.

But the problem is when the button is disabled the hover and active styles still applies.

How to apply hover and active only on enabled buttons?

Ali
  • 20,014
  • 14
  • 80
  • 93

8 Answers8

460

You can use :enabled pseudo-class, but notice IE<9 does not support it:

button:hover:enabled{
    /*your styles*/
}
button:active:enabled{
    /*your styles*/
}
Engineer
  • 45,891
  • 11
  • 86
  • 90
111
.button:active:hover:not([disabled]) {
    /*your styles*/
}

You can try this..

Velayutham Anjamani
  • 1,111
  • 1
  • 7
  • 3
  • 1
    This is a good solution for when you want the "hover disabled" state to look identical to the "non-hovered disabled" state. – Mikhael Loo Jul 13 '16 at 20:02
  • I <3 this solution. allows me to have the following: and – Ben Dec 15 '17 at 17:36
  • life saver for folks who using scss `.button { font-weight: 600 !important; width: 186px; height:46px; font-size: 16px !important; line-height: 144% !important; letter-spacing: -0.02em !important; opacity: 1; &:disabled, &.disabled{ color:#fff; border-color: #a0a0a0; background-color: #a0a0a0; } &:disabled:hover, &:disabled:focus, &.disabled:hover, &.disabled:focus { color:#fff; border-color: #a0a0a0; background-color: #a0a0a0; } &:hover:not([disabled]) { opacity: v.$hoverOpacity; } }` – sylvain s Dec 16 '21 at 16:50
42

Why not using attribute "disabled" in css. This must works on all browsers.

button[disabled]:hover {
    background: red;
}
button:hover {
    background: lime;
}
Madef
  • 579
  • 4
  • 9
  • 17
    Cover all the disabled states by selecting them all in one line: `.button[disabled], .button[disabled]:hover, .button[disabled]:focus, .button[disabled]:active {}` – DBK Jun 09 '14 at 19:35
26

If you are using LESS or Sass, You can try this:

.btn {
  &[disabled] {
    opacity: 0.6;
  }
  &:hover, &:active {
    &:not([disabled]) {
      background-color: darken($orange, 15);
    }
  }
}
Community
  • 1
  • 1
fatlinesofcode
  • 1,567
  • 17
  • 21
  • 2
    This is a good solution in SASS since the hover effect will get processed for a disabled button unless you wrap it in not block. – mbokil Jan 27 '20 at 15:26
19

Use the lightest touch: overriding via rule order.

.btn {
  /* base styles */
}

.btn:hover {
  color: red;
}

.btn:active {
  color: green;
}

.btn:disabled {
  color: #aaa;
}

The trick is the order -- apply all the non-disabled states first, makes sure they all have the same specificity, and do disabled last, with the same specificity.

This won't work for a class added to links, or non-interactive elements, which don't have the disabled property.

(Edited to remove higher-specificity rules, and messing with pointer-events)

michai
  • 401
  • 4
  • 7
16

In sass (scss):

 button {
  color: white;
  cursor: pointer;
  border-radius: 4px;

  &:disabled{
    opacity: 0.4;

    &:hover{
      opacity: 0.4;  //this is what you want
    }
  }

  &:hover{
    opacity: 0.9;
  }
}
jakeforaker
  • 1,570
  • 1
  • 18
  • 34
3

One way is to add a partcular class while disabling buttons and overriding the hover and active states for that class in css. Or removing a class when disabling and specifying the hover and active pseudo properties on that class only in css. Either way, it likely cannot be done purely with css, you'll need to use a bit of js.

techfoobar
  • 63,712
  • 13
  • 108
  • 129
0

I use the one below in my project.

.bg-brand-3 {
  background-color: black;
  &[type="button"]:enabled {
    &:hover {
      background-color: orange;
    }
    &:active {
      background-color: green;
    }
  }
  &[type="submit"] {
    // css
  }
}

The :enable has the same meaning as :not(:disabled)

Quang Dong
  • 389
  • 4
  • 5