CSS 전환 효과를 일시적으로 비활성화하는 가장 깨끗한 방법은 무엇입니까?


209

다음 효과 중 일부 / 모두가 적용된 DOM 요소가 있습니다.

#elem {
  -webkit-transition: height 0.4s ease;
  -moz-transition: height 0.4s ease;
  -o-transition: height 0.4s ease;
  transition: height 0.4s ease;
}

이 요소의 크기를 조정하는 jQuery 플러그인을 작성 중입니다.이 효과를 일시적으로 비활성화해야 부드럽게 크기를 조정할 수 있습니다.

이러한 영향을 일시적으로 비활성화 한 다음 다시 활성화하는 가장 우아한 방법은 부모로부터 적용되거나 전혀 적용되지 않을 수 있다는 점입니다.


1
이것은 유망한 것으로 보입니다 : ricostacruz.com/jquery.transit . 그것은 MIT 라이센스가 있으므로 그것을 통합하거나 연구하여 그가 어떻게하는지 볼 수 있습니다.
Robert Harvey

모든 답변 은 수업을 추가 합니다 .notransition. 다른 방법으로, 즉 #elem.yestransitionCSS로 대상 을 지정 하고이 클래스를 제거하는 것이 더 합리적 입니다. *CSS에서 불쾌한 것을 제거합니다 .
marcellothearcane

답변:


484

짧은 답변

이 CSS를 사용하십시오 :

.notransition {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  transition: none !important;
}

또한이 JS (jQuery 제외) ...

someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions

또는 jQuery가있는이 JS는 ...

$someElement.addClass('notransition'); // Disable transitions
doWhateverCssChangesYouWant($someElement);
$someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes
$someElement.removeClass('notransition'); // Re-enable transitions

... 또는 다른 라이브러리 또는 프레임 워크를 사용하는 동등한 코드.

설명

이것은 실제로 상당히 미묘한 문제입니다.

먼저 *-transitionCSS 속성을 로 설정하기 위해 요소에 적용 할 수있는 'notransition'클래스를 만들고 싶을 것입니다 none. 예를 들어 :

.notransition {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  transition: none !important;
}

(사소한 일이 있습니다-in의 부족에주의하십시오 -ms-transition. 필요하지 않습니다. 모든 트랜지션을 지원하는 Internet Explorer의 첫 번째 버전 은 IE 10으로, 접두사를 지원 하지 않았습니다 .)

그러나 그것은 단지 스타일이며 쉬운 일입니다. 이 클래스를 사용하려고 시도하면 함정에 빠지게됩니다. 함정은 이와 같은 코드가 순진하게 예상되는 방식으로 작동하지 않는다는 것입니다.

// Don't do things this way! It doesn't work!
someElement.classList.add('notransition')
someElement.style.height = '50px' // just an example; could be any CSS change
someElement.classList.remove('notransition')

순전히, 당신은 높이 변화가 애니메이션화되지 않을 것이라고 생각할 수 있습니다. 왜냐하면 '전이 없음'클래스가 적용되는 동안 발생하기 때문입니다. 현실에서는, 그러나, 그것은 것입니다 내가 해봤 모든 최신 브라우저에 적어도 애니메이션. 문제는 브라우저가 JavaScript 실행이 완료 될 때까지 필요한 스타일 변경 사항을 캐싱 한 다음 모든 변경 사항을 단일 리플 로우로 작성한다는 것입니다. 결과적으로 전환의 활성화 여부에 대한 순 변경은 없지만 높이에 대한 순 변경은 리플 로우를 수행합니다. 결과적으로 높이 변화에 애니메이션을 적용합니다.

이 문제를 해결하는 합리적이고 깨끗한 방법은 다음과 같이 1ms 시간 초과로 '전환 없음'클래스 제거를 래핑하는 것입니다.

// Don't do things this way! It STILL doesn't work!
someElement.classList.add('notransition')
someElement.style.height = '50px' // just an example; could be any CSS change
setTimeout(function () {someElement.classList.remove('notransition')}, 1);

그러나 이것은 확실하게 작동하지 않습니다. WebKit 브라우저에서 위의 코드를 깨뜨릴 수 없었지만 Firefox (느린 속도와 빠른 컴퓨터 모두)에서 때로는 (임의로 무작위로) 순진한 접근 방식과 동일한 동작을 얻습니다. 그 이유는 브라우저가 유휴 상태가 될 때까지 시간 초과 기능이 실행 대기 중이고 기회 주의적 리플 로우를 수행하려고 생각할 때 JavaScript 실행 속도가 느려질 수 있기 때문입니다. Firefox는 리플 로우 전에 대기중인 기능을 실행합니다.

나는이 문제를 발견 한 유일한 해결책은 것입니다 강제 'notransition'클래스를 제거하기 전에, 그것을 만든 CSS 변경을 세척, 요소의 리플 로우. 이를 수행하는 방법은 여러 가지가 있습니다 . 여기 를 참조 하십시오 . 이를 수행하는 '표준'방법에 가장 가까운 것은 offsetHeight요소 의 속성 을 읽는 것 입니다.

실제로 작동하는 한 가지 솔루션은

someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions

여기에 내가 설명한 세 가지 가능한 접근 방법 (하나의 성공적인 접근 방법과 두 가지 실패한 방법 모두)을 보여주는 JS 바이올린이 있습니다 .http : //jsfiddle.net/2uVAA/131/


8
Excelente 답변. 잘 했어요. 같은 문제가 생겨서 고맙습니다. 한 가지 유형의 전환 만 제거하려면 어떻게해야합니까?
rafaelmorais 2014

2
귀하의 솔루션은 맞지만 더 많은 배경 정보를 원하는 사람들을 위해 : stackoverflow.com/a/31862081/1026
Nickolay

2
마이너 마이너 옆, IE10은 처음 안정의 접두어가 전환과 함께 배에 IE의 버전. Release Preview를 제외한 시험판 버전에는 다른 것들과 함께 전환을 위해 -ms- 접두사가 필요했습니다. 그것이 바로 -ms- 접두사가 오늘날 나타나는 이유 중 하나라고 생각합니다. 물론 다른 가능성이 높은 이유는 벤더 접두사에 대해 우리 모두가 알고 사랑하는 일반적인화물 컬트입니다.
BoltClock

1
단순히 요소의 오프셋 높이를 확인하면 리플 로우가 트리거된다는 점에 흥미가 있습니다. 이 같은 문제로 벽에 머리를 대고 1 년 전에 이것을 알고 있었으면 좋겠다. 이것이 여전히 이것을 처리하는 가장 이상적인 방법으로 간주됩니까?
Brett84c

2
offsetHeight 속성이없는 SVG 요소에 애니메이션을 적용 할 때 리플 로우 트릭이 작동하지 않는 것 같습니다. setTimout이 작동합니다.
piotr_cz

19

DaneSoul이 제안한대로 애니메이션 비활성화를 옹호하지만 스위치를 전역으로 만듭니다.

/*kill the transitions on any descendant elements of .notransition*/
.notransition * { 
  -webkit-transition: none !important; 
  -moz-transition: none !important; 
  -o-transition: none !important; 
  -ms-transition: none !important; 
  transition: none !important; 
} 

.notransition그런 다음 body요소에 적용 하여 페이지의 전환 애니메이션을 효과적으로 재정 의 할 수 있습니다 .

$('body').toggleClass('notransition');

2
실제로 이것은 완벽한 옵션 imo입니다. 특히 *는 많은 애니메이션을 유발하여 하위 애니메이션이 트리거되지 않도록합니다. 고마워요
SchizoDuckie

이것은 당신이 한 번에 모두하고 싶은 상황에 대한 정답입니다. 예를 들어 모바일에서 회전하는 동안 전환을 비활성화하고 싶습니다. 이것은 완벽합니다.
벤 Lachman

나는 다소 복잡한 시나리오에서 angularjs에서 이것을 사용했지만 결국 신이 내 머리를 두드리는 데 도움이되었습니다.
Aditya MP

2
성능 현명한 나는 이것이 좋은 아이디어라고 기대할 수 없다. "오, 이것을 페이지의 모든 것에 적용하면 작업이 쉬워집니다!"
Lodewijk

1
".notransition"과 ".notransition *"를 모두 선택해야합니다.
Nathan

19

전환을 차단하는 추가 CSS 클래스를 추가 한 다음 제거하여 이전 상태로 돌아갑니다. 이것은 CSS와 JQuery 코드를 짧고 간단하며 이해하기 쉽게 만듭니다.

CSS :

.notransition {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  -ms-transition: none !important;
  transition: none !important;
}

!important ID는 일반적으로 클래스보다 더 구체적이기 때문에이 규칙에 더 많은 "가중치"가 부여되도록 추가되었습니다.

JQuery :

$('#elem').addClass('notransition'); // to remove transition
$('#elem').removeClass('notransition'); // to return to previouse transition

5
-1 Chrome이나 Firefox에서 문제를 해결하기에 충분하지 않았기 때문에-클래스를 추가하고 변경하고 클래스를 제거하는 Javascript가있는 경우 변경 사항이 여전히 애니메이션으로 표시됩니다. 지난 한두 시간 동안이 문제를 자세히 연구했으며 나중에 순진한 접근 방식이 실패한 경우를 보여주는 바이올린과 함께 변경 사항을 제거하고 제거하는 것 사이에 리플 로우를 강제로 해결하여 깔끔한 해킹을 게시합니다. 전이가없는 클래스
Mark Amery 10

9

순수 JS 솔루션 (아무 CSS 클래스)의 경우, 단지를 설정 transition합니다 'none'. CSS에 지정된대로 전환을 복원하려면를 transition빈 문자열로 설정하십시오 .

// Remove the transition
elem.style.transition = 'none';

// Restore the transition
elem.style.transition = '';

공급 업체 접두사를 사용하는 경우 접두사도 설정해야합니다.

elem.style.webkitTransition = 'none'

8

이 CSS 코드로 페이지의 모든 요소에 대해 애니메이션, 전환, 변형을 비활성화 할 수 있습니다

var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = '* {' +
'/*CSS transitions*/' +
' -o-transition-property: none !important;' +
' -moz-transition-property: none !important;' +
' -ms-transition-property: none !important;' +
' -webkit-transition-property: none !important;' +
'  transition-property: none !important;' +
'/*CSS transforms*/' +
'  -o-transform: none !important;' +
' -moz-transform: none !important;' +
'   -ms-transform: none !important;' +
'  -webkit-transform: none !important;' +
'   transform: none !important;' +
'  /*CSS animations*/' +
'   -webkit-animation: none !important;' +
'   -moz-animation: none !important;' +
'   -o-animation: none !important;' +
'   -ms-animation: none !important;' +
'   animation: none !important;}';
   document.getElementsByTagName('head')[0].appendChild(style);

1
먼저 이것은 굉장합니다, 감사합니다! 둘째, 다른 속성도 설정해야합니다. github.com/japgolly/test-state/blob/master/util/shared/src/test/…
Golly

@Golly 그 다른 속성은 최종 설계에 영향을 미칠 수
jonperl

0

다음과 같은 경우에 사용할 수있는 별도의 CSS 클래스를 만들 수 있다고 생각합니다.

.disable-transition {
  -webkit-transition: none;
  -moz-transition: none;
  -o-transition: color 0 ease-in;
  -ms-transition: none;
  transition: none;
}

그런 다음 jQuery에서 다음과 같이 클래스를 토글합니다.

$('#<your-element>').addClass('disable-transition');

예, 이것이 가장 좋은 방법이라고 생각합니다. 실제로 플러그인은 CSS 블록을 페이지에 삽입 할 수 있습니다.
Sam Saffron

3
중요한 클래스 눈금자가 없으면 ID 1을 무시합니까?
DaneSoul 2016 년

0

모든 전환을 방지하기 위해 간단한 jquery없는 솔루션을 원할 경우 :

  1. 이 CSS를 추가하십시오 :
body.no-transition * {
  transition: none !important;
}
  1. 그리고 당신의 js에서 :
document.body.classList.add("no-transition");

// do your work, and then either immediately remove the class:

document.body.classList.remove("no-transition");

// or, if browser rendering takes longer and you need to wait until a paint or two:

setTimeout(() => document.body.classList.remove("no-transition"), 1);

// (try changing 1 to a larger value if the transition is still applying)

-1

현재 웹 페이지에서 CSS 전환, 변형 및 애니메이션을 제거하려면 브라우저 콘솔 내부에서 작성한이 작은 스크립트를 실행하면됩니다.

let filePath = "https://dl.dropboxusercontent.com/s/ep1nzckmvgjq7jr/remove_transitions_from_page.css";
let html = `<link rel="stylesheet" type="text/css" href="${filePath}">`;
document.querySelector("html > head").insertAdjacentHTML("beforeend", html);

이 css-file 을로드 하기 위해 vanillaJS를 사용 합니다 . 스크레이퍼 (Ruby-Selenium)의 맥락에서 이것을 사용하려는 경우 github 저장소도 있습니다. remove-CSS-animations-repo


-3

않습니다

$('#elem').css('-webkit-transition','none !important'); 

당신의 js에서 그것을 죽입니까?

분명히 각각 반복합니다.


1
그런 다음 사실 이후에 재설정해야하므로 저장해야합니다. 이는 상당한 양의 보일러 플레이트로 이어질 것입니다
Sam Saffron

-4

CSS에 다음과 같은 클래스가 있습니다.

.no-transition { 
  -webkit-transition: none;
  -moz-transition: none;
  -o-transition: none;
  -ms-transition: none;
  transition: none;
}

그런 다음 jQuery에서 :

$('#elem').addClass('no-transition'); //will disable it
$('#elem').removeClass('no-transition'); //will enable it

1
중요한 클래스 눈금자가 없으면 ID 1을 무시합니까?
DaneSoul 2016 년

1
예, 이제 ID보다 더 구체적인 # elem.no-transition을 타겟팅하고 있기 때문에
Moin Zaman

3
@MoinZaman Erm, CSS를 타겟팅 하지 않았#elem.no-transition 으며 방금 타겟팅했습니다 .no-transition. 아마도 당신은 #elem.no-transitionCSS 로 작성하려고 했습니까?
Mark Amery
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.