Test
Test

Reputation: 13

CSS: Combination of Visibility and Opacity

In my project, I have a button that I want to display and hide under certain conditions. When the button is hidden, it should still take up space (meaning display: none; is not what I want) but it should not be visible and the user should not be able to interact with it. Changing the visibility does everything I want, but then it appears and disappears instantly, and I would like to have a smooth transition. When using the opacity, I can set the transition duration, but then the cursor still changes to a pointer when hovering over the button. By accident, I discovered that I can simply combine these two things to get the desired result: When I click on the button in the example, it fades out slowly, but once it is gone I cannot interact with it anymore. However, I don't understand why it works that way, since the visibility changes instantly, and I also don't know if it works like this in all major browsers. Could somebody answer these two things for me, please?

function hide() {
  document.querySelector("button").style.visibility = "hidden";
  document.querySelector("button").style.opacity = "0";
}
button {
  transition-duration: 1s;
}
<button onclick="hide()">This is a test.</button>

Upvotes: 1

Views: 457

Answers (2)

A Haworth
A Haworth

Reputation: 36492

The question was basically: why does this work when visibility is changed instantly.

This is in fact not correct. visibility is interpolated and as you have the transition set on everything, the visibility will transition.

Obviously it can not have continuous values, but it 'chooses' a value of visible or hidden, which are the two endpoints you have specified, in steps. The place(s) at which it changes are determined by the timing function.

So, your code works absolutely fine. The element fades away with the opacity and at some point (near the end in the case of the ease timing function) it will switch from visible to hidden.

See for example MDN:

Visibility values are interpolated between visible and not-visible.

Upvotes: 0

Dejan.S
Dejan.S

Reputation: 19128

You can use opacity and pointer-events. Also please don't use javascript for css stuff. In my example I add a class instead.

const button = document.querySelector('.js-disable')

button.addEventListener('click', function() {
  button.classList.add('button--is-disabled')
})
.button {
  background-color: #ededed;
  padding: .5rem 1rem;
  border: none;
}

.button--is-disabled {
  opacity: 0;
  pointer-events: none;
  transition: opacity 2s;
}
<button class="button js-disable">Click me</button>

Upvotes: 3

Related Questions