Chuyển đổi trên thuộc tính hiển thị CSS


1448

Tôi hiện đang thiết kế một menu 'thả xuống lớn' CSS - về cơ bản là một menu thả xuống chỉ có CSS ​​thông thường, nhưng một menu chứa các loại nội dung khác nhau.

Tại thời điểm này, có vẻ như CSS 3 chuyển không áp dụng cho các 'display' bất động sản , tức là bạn không thể làm bất kỳ loại chuyển tiếp từ display: noneđến display: block(hoặc bất kỳ sự kết hợp).

Có cách nào để menu cấp hai từ ví dụ trên chuyển sang 'fade in' khi ai đó di chuyển qua một trong các mục menu cấp cao nhất không?

Tôi biết rằng bạn có thể sử dụng các hiệu ứng chuyển tiếp trên visibility:tài sản, nhưng tôi không thể nghĩ ra cách sử dụng hiệu quả.

Tôi cũng đã thử sử dụng chiều cao, nhưng điều đó đã thất bại thảm hại.

Tôi cũng nhận thức được rằng việc đạt được điều này bằng JavaScript là không đáng kể, nhưng tôi muốn thử thách bản thân mình chỉ sử dụng CSS và tôi nghĩ rằng tôi sẽ xuất hiện một chút.


Chuyển đổi CSS có hoạt động không nếu bạn áp dụng nó cho thuộc tính độ mờ, thay vì hiển thị?
Paul D. Chờ

13
vị trí: tuyệt đối; tầm nhìn: ẩn; giống như hiển thị: none;
Jawad

8
@Jawad: Chỉ khi bạn thêm một cái gì đó như z-index:0là tốt.
DanMan

7
@Jawad: Bạn không bao giờ nên sử dụng visibility: hiddentrừ khi bạn muốn người đọc màn hình đọc nó (trong khi các trình duyệt thông thường sẽ không). Nó chỉ xác định khả năng hiển thị của phần tử (như nói opacity: 0), và nó vẫn có thể lựa chọn, có thể nhấp và bất cứ thứ gì nó từng là; nó chỉ không nhìn thấy được
Rừng Katsch

1
không hỗ trợ pointer-eventstrong IE 8,9,10, vì vậy không phải lúc nào cũng ổn
Steven Pribilinskiy

Câu trả lời:


1351

Bạn có thể ghép hai chuyển tiếp trở lên, và đó visibilitylà những gì có ích trong lần này.

div {
  border: 1px solid #eee;
}
div > ul {
  visibility: hidden;
  opacity: 0;
  transition: visibility 0s, opacity 0.5s linear;
}
div:hover > ul {
  visibility: visible;
  opacity: 1;
}
<div>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>
</div>

(Đừng quên tiền tố nhà cung cấp cho transitiontài sản.)

Thêm chi tiết trong bài viết này .


10
Câu trả lời này có vẻ như ít công việc hơn những câu hỏi khác và đạt được những gì chúng ta mong đợi từ màn hình: none / block; Cảm ơn. Tiết kiệm cho tôi một tấn thời gian.
Brendan

21
Vâng, vấn đề với điều này là bất cứ điều gì đằng sau nó sẽ chồng chéo ngay cả khi nó không hiển thị. Tôi tìm thấy bằng cách sử dụng chiều cao: 0 một giải pháp tốt hơn nhiều
Josh Bedo

741
Điều này là tốt nhưng vấn đề là các yếu tố "ẩn tầm nhìn" vẫn chiếm không gian trong khi "không hiển thị" thì không.
Rui Marques

41
Tôi có thể thiếu một cái gì đó, nhưng tại sao bạn thay đổi cả khả năng hiển thị VÀ độ mờ? Sẽ không đặt độ mờ thành 0 ẩn phần tử - tại sao bạn cũng cần đặt chế độ hiển thị thành ẩn?
GMA

21
@GeorgeMillo nếu bạn chỉ đặt độ mờ, phần tử thực sự vẫn còn trên kết xuất trang (ví dụ bạn không thể nhấp vào suy nghĩ).
adriendenat

800

Bạn cần ẩn phần tử bằng các phương tiện khác để làm cho nó hoạt động.

Tôi đã hoàn thành hiệu ứng bằng cách định vị cả hai <div>s và đặt cái ẩn thành opacity: 0.

Nếu bạn thậm chí chuyển đổi thuộc displaytính từ nonesang block, quá trình chuyển đổi của bạn trên các yếu tố khác sẽ không xảy ra.

Để khắc phục điều này, luôn cho phép phần tử tồn tại display: block, nhưng ẩn phần tử bằng cách điều chỉnh bất kỳ phương tiện nào sau đây:

  1. Đặt heightthành 0.
  2. Đặt opacitythành 0.
  3. Định vị phần tử bên ngoài khung của phần tử khác có overflow: hidden.

Có nhiều giải pháp hơn, nhưng bạn không thể thực hiện chuyển đổi nếu bạn chuyển phần tử sang display: none. Ví dụ: bạn có thể thử dùng một cái gì đó như thế này:

div {
    display: none;
    transition: opacity 1s ease-out;
    opacity: 0;
}
div.active {
    opacity: 1;
    display: block;
}

Nhưng điều đó sẽ không làm việc. Từ kinh nghiệm của tôi, tôi đã tìm thấy điều này để không làm gì cả.

Vì điều này, bạn sẽ luôn cần phải giữ nguyên tố display: block- nhưng bạn có thể khắc phục nó bằng cách làm một cái gì đó như thế này:

div {
    transition: opacity 1s ease-out;
    opacity: 0;
    height: 0;
    overflow: hidden;
}
div.active {
    opacity: 1;
    height: auto;
}

29
Cảm ơn Jim đã trả lời thấu đáo. Bạn hoàn toàn đúng về thực tế là nếu màn hình: thuộc tính thay đổi, thì TẤT CẢ các chuyển đổi của bạn sẽ không hoạt động. Đó là một sự xấu hổ - tôi tự hỏi lý do đằng sau đó là gì. Bên cạnh đó, trên cùng một liên kết tôi đã đăng trong câu hỏi ban đầu, bạn có thể thấy tôi đang ở đâu với nó. Vấn đề (nhỏ) duy nhất tôi gặp phải là trong Chrome [5.0.375.125] khi tải trang, bạn có thể thấy menu nhanh chóng biến mất khi các yếu tố được tải trên trang. Firefox 4.0b2 và Safari 5.0 hoàn toàn ổn ... lỗi hoặc thứ gì đó tôi đã bỏ lỡ?
RichardTape

7
Tôi đồng ý rằng điều này đúng và sẽ đóng góp điều này; một đầu lên cho du khách trong tương lai. Tôi đã tìm thấy một giải pháp hoạt động trong Chrome, nhưng tôi thấy nó không thành công trên iPhone 4: visibility:hidden; opacity:0; -webkit-transition: all .2s ease-in-out;Không chỉ điều này không chuyển đổi chính xác, mà yếu tố mục tiêu sẽ không bao giờ hiển thị. QA sẽ làm bạn thất vọng, tôi và mẹ của bạn.
SimplGy

1
Bạn thực sự có thể chuyển đổi thuộc tính khả năng hiển thị .. chỉ cần nói
Cu7l4ss

2
Nếu bạn đặt trạng thái ẩn của mình thành height: 0;và không chuyển đổi trạng thái đó, quá trình chuyển đổi sẽ không hoạt động. Tôi đã thử điều này chỉ cố gắng để chuyển đổi độ mờ đục. Tôi đã phải gỡ bỏheight: 0;
chovy

10
bạn vừa giành được một phiếu bầu vì overflow: hiddencảm ơn bạn rất nhiều!
thiagoh

279

Tại thời điểm của bài đăng này, tất cả các trình duyệt chính đều vô hiệu hóa các chuyển đổi CSS nếu bạn cố gắng thay đổi thuộc displaytính, nhưng hoạt ảnh CSS vẫn hoạt động tốt để chúng tôi có thể sử dụng chúng như một cách giải quyết.

Mã ví dụ (bạn có thể áp dụng nó cho menu của mình cho phù hợp) Demo :

Thêm CSS sau vào biểu định kiểu của bạn:

@-webkit-keyframes fadeIn {
    from { opacity: 0; }
      to { opacity: 1; }
}
@keyframes fadeIn {
    from { opacity: 0; }
      to { opacity: 1; }
}

Sau đó, áp dụng fadeInhình ảnh động cho đứa trẻ trên cha mẹ di chuột (và tất nhiên được đặt display: block):

.parent:hover .child {
    display: block;
    -webkit-animation: fadeIn 1s;
    animation: fadeIn 1s;
}

Cập nhật 2019 - Phương pháp cũng hỗ trợ mờ dần:

(Một số mã JavaScript là bắt buộc)

// We need to keep track of faded in elements so we can apply fade out later in CSS
document.addEventListener('animationstart', function (e) {
  if (e.animationName === 'fade-in') {
      e.target.classList.add('did-fade-in');
  }
});

document.addEventListener('animationend', function (e) {
  if (e.animationName === 'fade-out') {
      e.target.classList.remove('did-fade-in');
   }
});
div {
    border: 5px solid;
    padding: 10px;
}

div:hover {
    border-color: red;
}

.parent .child {
  display: none;
}

.parent:hover .child {
  display: block;
  animation: fade-in 1s;
}

.parent:not(:hover) .child.did-fade-in {
  display: block;
  animation: fade-out 1s;
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fade-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
<div class="parent">
    Parent
    <div class="child">
        Child
    </div>
</div>


3
Cám ơn vì cái này. Thủ height: 0thuật (cho các chuyển tiếp) được đề cập ở trên dường như không hoạt động vì chiều cao được đặt thành 0 trên chuyển tiếp mờ dần, nhưng thủ thuật này dường như chỉ hoạt động tốt.
Elliot Winkler

41
Cảm ơn, rất hữu ích. Nhưng làm thế nào để làm mờ nó ra?
Illiou

1
Đoạn đầu tiên của câu trả lời này không hoàn toàn có ý nghĩa. Các trình duyệt không chỉ vô hiệu hóa tất cả các chuyển đổi hoàn toàn ngay khi bạn sử dụng displaytài sản - thực sự không có lý do gì. Và ngay cả khi họ đã làm , tại sao hoạt hình sẽ làm việc sau đó? Bạn cũng không thể sử dụng thuộc displaytính trong hoạt hình CSS.
BoltClock

7
Câu trả lời tốt nhất, không thể với chuyển tiếp nhưng có với hình ảnh động.
Mikel

6
Làm thế nào về hoạt hình đảo ngược, đó là khi yếu tố nên từ từ biến mất?
Màu xanh lá cây

77

Tôi nghi ngờ rằng lý do chuyển đổi bị vô hiệu hóa nếu displaybị thay đổi là vì những gì hiển thị thực sự làm. Nó không thay đổi bất cứ điều gì có thể hình dung được hoạt hình trơn tru.

display: none;visibility: hidden;là hai điều hoàn toàn khác nhau.
Cả hai đều có tác dụng làm cho phần tử trở nên vô hình, nhưng với visibility: hidden;nó vẫn được hiển thị trong bố cục, nhưng không rõ ràng như vậy.
Phần tử ẩn vẫn chiếm dung lượng và vẫn được hiển thị nội tuyến hoặc dưới dạng khối hoặc khối hoặc nội tuyến hoặc bất kỳ displayphần tử nào bảo nó hiển thị dưới dạng và chiếm không gian tương ứng.
Các yếu tố khác không tự động di chuyển để chiếm không gian đó. Phần tử ẩn chỉ không hiển thị pixel thực của nó cho đầu ra.

display: nonemặt khác thực sự ngăn chặn phần tử hiển thị hoàn toàn .
Nó không chiếm bất kỳ không gian bố trí.
Các phần tử khác đã chiếm một phần hoặc toàn bộ không gian được chiếm bởi phần tử này bây giờ sẽ điều chỉnh để chiếm chỗ đó, như thể phần tử đơn giản là không tồn tại .

displaykhông chỉ là một thuộc tính hình ảnh khác.
Nó thiết lập toàn bộ chế độ dựng hình của nguyên tố này, chẳng hạn như cho dù đó là một block, inline, inline-block, table, table-row, table-cell,list-item , hoặc bất cứ điều gì!
Mỗi trong số chúng có sự phân chia bố cục rất khác nhau, và sẽ không có cách nào hợp lý để làm động hoặc chuyển đổi chúng một cách trơn tru ( ví dụ, hãy thử tưởng tượng một sự chuyển đổi suôn sẻ từ blocksang inlinehoặc ngược lại!).

Đây là lý do tại sao các hiệu ứng chuyển tiếp bị vô hiệu hóa nếu thay đổi hiển thị (ngay cả khi thay đổi là hoặc từ none- nonekhông chỉ là vô hình, đó là chế độ kết xuất phần tử của chính nó có nghĩa là không hiển thị gì cả!).


8
Cũng giống như các giải pháp trên, rất hài lòng khi nhận được lời giải thích hợp lý về lý do tại sao các chuyển đổi không áp dụng để hiển thị các thuộc tính.
kqr

8
Tôi không đồng ý. Nó có thể có ý nghĩa hoàn chỉnh. Nếu hiển thị: none để hiển thị: khối xảy ra ngay lập tức khi bắt đầu quá trình chuyển đổi, điều đó sẽ rất tuyệt. Và để chuyển đổi trở lại, nếu nó chuyển từ display: block sang display: không có quyền nào ở cuối quá trình chuyển đổi, điều đó sẽ hoàn hảo.
Curtis Yallop

2
Nếu bạn không thể tưởng tượng một hình ảnh động từ một điểm đến một hình chữ nhật trông như thế nào, thì bạn đã gặp vấn đề. Chuyển đổi từ chiếm không gian sang chiếm một không gian hình chữ nhật là RẤT rõ ràng, giống như, bạn làm điều đó mỗi khi bạn kéo một hình chữ nhật ra bằng chuột như mọi ứng dụng. Do thất bại này, có rất nhiều vụ hack liên quan đến chiều cao tối đa và tỷ lệ lợi nhuận âm. Điều duy nhất hoạt động là lưu trữ chiều cao 'thực' và sau đó hoạt ảnh từ 0 đến giá trị được lưu trong bộ nhớ cache bằng JavaScript. Buồn.
Triynko

2
Tryniko: display: none không thay đổi kích thước của phần tử thành hình chữ nhật 0 x 0 - nó loại bỏ nó khỏi DOM. Bạn có thể làm động từ hình chữ nhật đến một điểm bằng cách làm động các thuộc tính chiều rộng và chiều cao về 0 và sau đó các phần tử khác sẽ chảy xung quanh nó như thể nó có 'display: none' nhưng thuộc tính 'display' của nó sẽ vẫn là 'block'; phần tử vẫn còn trong DOM. Khái niệm hoạt hình giữa display: block và display: none là vô lý: Không có trạng thái trung gian. Một phần tử tồn tại trong DOM hoặc nó không tồn tại, bất kể nó nhỏ hay vô hình.
Steve Thorpe

1
Nó không phải là vô lý để animate tính chất rời rạc. Các thuộc tính riêng biệt như displaykhông thể được chuyển đổi suôn sẻ như các thuộc tính khác, nhưng điều đó không có nghĩa là thời gian không quan trọng. Có khả năng kiểm soát khi quá trình chuyển đổi từ disply:blockđể display:nonexảy ra là rất quan trọng. Giống như @CurtisYallop đã mô tả nó. Nếu tôi muốn chuyển đổi từ opacity:1sang opacity:0sau đó thay đổi display:blockthành display:nonetôi sẽ có thể làm điều đó.
Jens

56

Thay vì gọi lại, không tồn tại trong CSS, chúng ta có thể sử dụng thuộc transition-delaytính.

#selector {
    overflow: hidden; // Hide the element content, while height = 0
    height: 0; opacity: 0;
    transition: height 0ms 400ms, opacity 400ms 0ms;
}
#selector.visible {
    height: auto; opacity: 1;
    transition: height 0ms 0ms, opacity 600ms 0ms;
}

Vì vậy, những gì đang xảy ra ở đây?

  1. Khi visiblelớp được thêm vào, cả hai heightopacitybắt đầu hoạt ảnh không chậm trễ (0 ms), mặc dùheight mất 0 ms để hoàn thành hoạt ảnh (tương đương display: block) và opacitymất 600 ms.

  2. Khi visiblelớp bị xóa,opacity bắt đầu hoạt ảnh (độ trễ 0 ms, thời lượng 400 ms) và chiều cao chờ 400 ms và chỉ sau đó ngay lập tức (0 ms) khôi phục giá trị ban đầu (tương đương với display: nonetrong cuộc gọi lại hoạt hình).

Lưu ý, phương pháp này tốt hơn phương pháp sử dụng visibility . Trong những trường hợp như vậy, phần tử vẫn chiếm không gian trên trang và không phải lúc nào nó cũng phù hợp.

Để biết thêm ví dụ xin vui lòng tham khảo bài viết này .


8
ngạc nhiên khi điều này không có nhiều upvote - giải pháp thông minh này bằng cách nào đó hoạt động hoàn hảo.
phô trương

3
Nó chỉ hoạt động với height:100%nó có thể phá hủy bố cục trong một số trường hợp. Giải pháp tuyệt vời, nếu đó không phải là vấn đề. Một trong số ít những người làm việc hai chiều.
Fabian von Ellerts

Điều đó thật tuyệt! Tôi đã có thể đơn giản hóa nó hơn nữa trong trường hợp của mình vì tôi muốn thời gian hoạt hình mờ dần giống như thời gian mờ dần. Thay vì sử dụng transition: height 0ms 0ms, opacity 600ms 0ms, tôi chỉ sử dụng transition-delay: 0s.
Jacob Lockard

52

display không phải là một trong những tính chất mà quá trình chuyển đổi hoạt động.

Xem các thuộc tính CSS có thể hoạt hình để biết danh sách các thuộc tính CSS có thể có các hiệu ứng chuyển tiếp được áp dụng cho chúng. Xem Giá trị CSS và Đơn vị Mô-đun Cấp 4, Kết hợp các Giá trị: Nội suy, Bổ sung và Tích lũy để biết cách chúng được nội suy.

Lên đến CSS 3 đã được liệt kê trong 9.1. Thuộc tính từ CSS (chỉ cần đóng cửa sổ bật lên cảnh báo)

Tôi cũng đã thử sử dụng chiều cao, nhưng điều đó đã thất bại thảm hại.

Lần trước tôi phải làm điều này, tôi đã sử dụng max-heightthay thế, đó là một tài sản có thể hoạt hình (mặc dù là một chút hack, nó đã hoạt động), nhưng hãy cẩn thận rằng nó có thể rất gây cười cho các trang phức tạp hoặc người dùng có thiết bị di động cấp thấp thiết bị.


Liên kết không còn trỏ trực tiếp đến phần thuộc tính hoạt hình.
Andrew Lam

1
@AndrewLam Đã sửa. Cảm ơn.
robocat

34

Bạn có thể thêm một hình ảnh động tùy chỉnh vào thuộc tính khối ngay bây giờ.

@keyframes showNav {
  from {opacity: 0;}
  to {opacity: 1;}
}
.subnav-is-opened .main-nav__secondary-nav {
  display: block;
  animation: showNav 250ms ease-in-out both;
}

Bản giới thiệu

Trong bản demo này, menu phụ thay đổi từ display:nonesang display:blockvà vẫn quản lý để mờ dần.


Nên myfirstđược showNavđây? Còn Firefox thì sao? Thật không may, tôi không thể tìm thấy một cái gì đó liên quan trên trang demo mà bạn đang đề cập.
Sebastian nôn Meer

Cảm ơn @SebastianG. Tôi đã thực hiện chỉnh sửa và thêm một số thông tin ở trên.
Manish Pradhan

@Sebastian nôn Meer: các phiên bản Firefox cũ hơn cần tiền tố nhà cung cấp "-moz-", xem mã được chỉnh sửa
Herr_Schwabullek

23
Trừ khi tôi thiếu một cái gì đó, liên kết "demo" không còn hiển thị quá trình chuyển đổi menu phụ.
Hiện thực

1
Chuyển đổi chính xác cho thứ gì đó không chiếm không gian (như trường hợp hiển thị: không có) sang thứ gì đó chiếm không gian (hiển thị: khối), là sự mở rộng kích thước, không phải là mờ dần. Nếu đó là vấn đề về khả năng hiển thị bị ẩn (chiếm không gian nhưng không nhìn thấy được) để hiển thị, thì kích thước vẫn giữ nguyên và độ mờ dần là phù hợp. Không có câu trả lời nào giải quyết được vấn đề.
Triynko

21

Theo Dự thảo làm việc ngày 19 tháng 11 năm 2013 của W3C display không phải là một tài sản hoạt hình . May mắn thay, visibilitylà hoạt hình. Bạn có thể xâu chuỗi quá trình chuyển đổi của nó với sự chuyển đổi độ mờ đục ( JSFiddle ):

  • HTML:

    <a href="http://example.com" id="foo">Foo</a>
    <button id="hide-button">Hide</button>
    <button id="show-button">Show</button>
  • CSS:

    #foo {
        transition-property: visibility, opacity;
        transition-duration: 0s, 1s;
    }
    
    #foo.hidden {
        opacity: 0;
        visibility: hidden;
        transition-property: opacity, visibility;
        transition-duration: 1s, 0s;
        transition-delay: 0s, 1s;
    }
  • JavaScript để thử nghiệm:

    var foo = document.getElementById('foo');
    
    document.getElementById('hide-button').onclick = function () {
        foo.className = 'hidden';
    };
    
    document.getElementById('show-button').onclick = function () {
        foo.className = '';
    };

Lưu ý rằng nếu bạn chỉ làm cho liên kết trong suốt mà không cần cài đặt visibility: hiddenthì nó sẽ có thể nhấp được.


1
tôi không thấy bất kỳ sự chuyển đổi nào trong ví dụ jsfiddle
Gino

@Gino Tôi đã sửa nó bằng cách đổi 0thành 0s. Rõ ràng, trong quá khứ trình duyệt mà tôi đã sử dụng để kiểm tra đơn vị được hỗ trợ 0 lần. Tuy nhiên, thời gian không có đơn vị không nằm trong Khuyến nghị của Ứng viên W3C, ngày 29 tháng 9 năm 2016 .
feklee

Điều này nên được nâng cao hơn. Tôi thấy nó là một trong những giải pháp tốt nhất.
Arthur Tarasov

Việc sử dụng độ trễ chỉ là logic tốt nhất để hiểu cách thức hoạt động của nó. Animate, và ẩn. Vô duyên, và animate. Giải pháp hoàn hảo cho tôi
Bruno Pitteli Gonçalves

15

Chỉnh sửa: hiển thị không được áp dụng trong ví dụ này.

@keyframes hide {
  0% {
    display: block;
    opacity: 1;
  }
  99% {
    display: block;
  }
  100% {
    display: none;
    opacity: 0;
  }
}

Điều xảy ra ở trên là thông qua 99% màn hình hoạt hình được đặt thành chặn trong khi độ mờ mờ dần. Trong khoảnh khắc cuối cùng thuộc tính hiển thị được đặt thành không.

Và bit quan trọng nhất là giữ lại khung hình cuối cùng sau khi hoạt ảnh kết thúc bằng chế độ hoạt hình-fill: chuyển tiếp

.hide {
   animation: hide 1s linear;
   animation-fill-mode: forwards;
}

Dưới đây là hai ví dụ: https://jsfiddle.net/qwnz9tqg/3/


Với giải pháp display: nonenày không hoạt động thì sao?
Bart Calix đến

Phải là 'chế độ hoạt hình điền vào: chuyển tiếp' không 'chuyển tiếp'
Alex

Chỉnh sửa phải có sáu ký tự và tôi chỉ có thể đề xuất chỉnh sửa do đó nhận xét
Alex

1
@Alex Ok. Typo cố định. Điều thú vị là câu trả lời của tôi thậm chí không hoạt động như mong đợi, nhưng thật hợp lý khi nghĩ rằng nó sẽ như vậy tôi sẽ giữ nó cho đến khi các trình duyệt sẽ hỗ trợ nó.
Pawel

3
Như bạn có thể thấy trong câu đố này với bộ con trỏ display: none, không bao giờ được thực hiện. jsfiddle.net/3e6sduqh
robstarbuck

14

Thủ thuật JavaScript gọn gàng của tôi là tách toàn bộ kịch bản thành hai chức năng khác nhau !

Để chuẩn bị mọi thứ, một biến toàn cục được khai báo và một trình xử lý sự kiện được xác định:

  var tTimeout;
  element.addEventListener("transitionend", afterTransition, true);//firefox
  element.addEventListener("webkitTransitionEnd", afterTransition, true);//chrome

Sau đó, khi ẩn phần tử, tôi sử dụng một cái gì đó như thế này:

function hide(){
  element.style.opacity = 0;
}

function afterTransition(){
  element.style.display = 'none';
}

Để xuất hiện lại phần tử, tôi đang làm một cái gì đó như thế này:

function show(){
  element.style.display = 'block';
  tTimeout = setTimeout(timeoutShow, 100);
}

function timeoutShow(){
  element.style.opacity = 1;
}

Nó hoạt động, cho đến nay!


Điều này không hoạt động vì thời gian trễ và không phải vì các lệnh javascript nằm trong các chức năng riêng biệt.

10

Tôi chạy vào đây hôm nay, với một position: fixedphương thức mà tôi đang sử dụng lại. Tôi không thể giữ nó display: nonevà sau đó làm động nó, vì nó vừa xuất hiện, vàz-index (giá trị âm, v.v.) cũng làm những điều kỳ lạ.

Tôi cũng đã sử dụng một height: 0đến height: 100%, nhưng nó chỉ làm việc khi phương thức xuất hiện. Điều này giống như khi bạn sử dụngleft: -100% hoặc một cái gì đó.

Sau đó, tôi nhận ra rằng có một câu trả lời đơn giản. Et voila:

Đầu tiên, phương thức ẩn của bạn. Lưu ý height0và kiểm tra heightkhai báo trong các chuyển tiếp ... nó có một 500ms, dài hơn opacitychuyển đổi của tôi . Hãy nhớ rằng, điều này ảnh hưởng đến quá trình chuyển dần dần ra: trả lại phương thức về trạng thái mặc định.

#modal-overlay {
    background: #999;
    background: rgba(33,33,33,.2);
    display: block;
    overflow: hidden;
    height: 0;
    width: 100%;
    position: fixed;
    top: 0;
    left: 0;
    opacity: 0;
    z-index: 1;
    -webkit-transition: height 0s 500ms, opacity 300ms ease-in-out;
       -moz-transition: height 0s 500ms, opacity 300ms ease-in-out;
            -ms-transition: height 0s 500ms, opacity 300ms ease-in-out;
         -o-transition: height 0s 500ms, opacity 300ms ease-in-out;
        transition: height 0s 500ms, opacity 300ms ease-in-out;
}

Thứ hai, phương thức hữu hình của bạn. Giả sử bạn đang thiết lập một .modal-activeđến body. Bây giờ height100%, và quá trình chuyển đổi của tôi cũng đã thay đổi. Tôi muốn heightđược thay đổi ngay lập tức và opacitythực hiện 300ms.

.modal-active #modal-overlay {
    height: 100%;
    opacity: 1;
    z-index: 90000;
    -webkit-transition: height 0s, opacity 300ms ease-in-out;
       -moz-transition: height 0s, opacity 300ms ease-in-out;
        -ms-transition: height 0s, opacity 300ms ease-in-out;
         -o-transition: height 0s, opacity 300ms ease-in-out;
            transition: height 0s, opacity 300ms ease-in-out;
}

Đó là nó, nó hoạt động như một nét duyên dáng.


Nâng cao phong cách của bạn trong việc sắp xếp các thuộc tính tiền tố của nhà cung cấp 👍
George Green

9

Lấy từ một vài trong số những câu trả lời này và một số gợi ý ở nơi khác, những điều sau đây rất hữu ích cho các menu di chuột (  cụ thể là tôi đang sử dụng với Bootstrap 3):

nav .dropdown-menu {
    display: block;
    overflow: hidden;
    max-height: 0;
    opacity: 0;
    transition: max-height 500ms, opacity 300ms;
    -webkit-transition: max-height 500ms, opacity 300ms;
}
nav .dropdown:hover .dropdown-menu {
    max-height: 500px;
    opacity: 1;
    transition: max-height 0, opacity 300ms;
    -webkit-transition: max-height 0, opacity 300ms;
}

Bạn cũng có thể sử dụng heightthay cho max-heightnếu bạn chỉ định cả hai giá trị vì height:autokhông được phép với transitions. Giá trị di chuột của max-heightnhu cầu phải lớn hơn heightmenu có thể có thể.


3
Đó là một mẹo hay nhưng có một thiếu sót. Thời gian chuyển tiếp phụ thuộc vào chiều cao. Nếu có nhiều menu có chiều cao thay đổi, những yếu tố có chiều cao gần với chiều cao tối đa sẽ sinh động độc đáo. Tuy nhiên, những cái ngắn hơn sẽ hoạt hình quá nhanh, mang lại trải nghiệm không nhất quán.
người dùng

8

Tôi tìm thấy cách tốt hơn cho vấn đề này, bạn có thể sử dụng CSS Animation và tạo hiệu ứng tuyệt vời của bạn để hiển thị các mục.

    .item {
     display: none;
}

.item:hover {
     display: block;
     animation: fade_in_show 0.5s
}

@keyframes fade_in_show {
     0% {
          opacity: 0;
          transform: scale(0)
     }
     100% {
          opacity: 1;
          transform: scale(1)
     }
}

Cảm ơn vì lời khuyên hữu ích này. Đó là hoạt động hoàn hảo.
Sedat Kumcu

6

Tôi đã gặp vấn đề này nhiều lần và bây giờ chỉ đơn giản là đi với:

.block {
  opacity: 1;
  transition: opacity 250ms ease;
}

.block--invisible {
  pointer-events: none;
  opacity: 0;
}

Bằng cách thêm lớp block--invisible, toàn bộ Element sẽ không thể nhấp được nhưng tất cả các Element nằm sau nó sẽ được pointer-events:nonehỗ trợ bởi tất cả các trình duyệt chính (không có IE <11).


Bạn có thể đưa điều này vào một ví dụ không?
GarethAS

1
Điều này hoạt động tốt, nhưng cần lưu ý rằng các sự kiện con trỏ không hoạt động với IE dưới 11
user1702965

thêm ghi chú cho IE dưới 11
DominikAngerer

Nếu bạn cần phải nói yếu tố trên tất cả mọi thứ (ví dụ như một menu) thì đây thực sự là cách sạch nhất để làm điều này ngay bây giờ vì năm 2019 hỗ trợ là vững chắc chopointer-events
Josh Davenport

5

Thay đổi overflow:hiddenthành overflow:visible. Nó hoạt động tốt hơn. Tôi sử dụng như thế này:

#menu ul li ul {
    background-color:#fe1c1c;
    width:85px;
    height:0px;
    opacity:0;
    box-shadow:1px 3px 10px #000000;
    border-radius:3px;
    z-index:1;
    -webkit-transition:all 0.5s ease;
    -moz-transition:all 0.6s ease;
}

#menu ul li:hover ul  {
    overflow:visible;
    opacity:1;
    height:140px;
}

visiblelà tốt hơn bởi vì overflow:hiddenhành động chính xác như a display:none.


Đây là vé cho tôi. Cảm ơn!
Dan Loewenherz

5

JavaScript là không bắt buộc và không cần chiều cao tối đa quá lớn. Thay vào đó, hãy đặt các max-heightthành phần văn bản của bạn và sử dụng một đơn vị tương đối phông chữ như remhoặc em. Bằng cách này, bạn có thể đặt chiều cao tối đa lớn hơn thùng chứa của mình, đồng thời tránh độ trễ hoặc "bật" khi menu đóng:

HTML

<nav>
  <input type="checkbox" />
  <ul>
    <li>Link 1</li>
    <li>Link 1</li>
    <li>Link 1</li>
    <li>Link 1</li>
  </ul>
</nav>

CSS

nav input + ul li { // Notice I set max-height on li, not ul
   max-height: 0;
}

nav input:checked + ul li {
   max-height: 3rem; // A little bigger to allow for text-wrapping - but not outrageous
}

Xem một ví dụ ở đây: http://codepen.io/mindfullsilence/pen/DtzjE


Tương tự như điều này, bạn có thể đặt chiều cao dòng trên văn bản của mình và chuyển đổi nó thành không. Nếu chỉ có văn bản bên trong, điều này sẽ ẩn container.
Abbeymortelmans

Tại sao rất ít phiếu? Đây là một câu trả lời thực sự tốt và có thể là câu tôi sử dụng.
mwilcox

@mwilcox Bởi vì nó sử dụng chiều cao cố định, rất tệ khi làm việc với nội dung động (chiều cao ước tính chẵn). Và nó chỉ hữu ích về nội dung văn bản.
Fabian von Ellerts

5

Sau khi câu trả lời được chấp nhận từ Guillermo được viết, đặc tả chuyển đổi CSS của 2012-04-03 đã thay đổi hành vi của chuyển đổi khả năng hiển thị và bây giờ có thể giải quyết vấn đề này theo cách ngắn hơn , mà không cần sử dụng độ trễ chuyển đổi:

.myclass > div {
                   transition:visibility 1s, opacity 1s;
                   visibility:hidden;  opacity:0
               }
.myclass:hover > div
               {   visibility:visible; opacity:1 }

Thời gian chạy được chỉ định cho cả hai lần chuyển đổi thường phải giống hệt nhau (mặc dù thời gian hiển thị lâu hơn một chút không phải là vấn đề).

Đối với phiên bản đang chạy, hãy xem bài đăng trên blog của tôi Hiển thị chuyển đổi CSS .

Viết tiêu đề của câu hỏi "Chuyển tiếp trên màn hình: thuộc tính" và phản hồi các bình luận từ Rui Marques và josh cho câu trả lời được chấp nhận:

Giải pháp này hoạt động trong trường hợp không liên quan nếu thuộc tính hiển thị hoặc hiển thị được sử dụng (vì có thể đó là trường hợp trong câu hỏi này).

Nó sẽ không hoàn toàn loại bỏ các yếu tố như display:none , chỉ làm cho nó vô hình, nhưng nó vẫn nằm trong luồng tài liệu và ảnh hưởng đến vị trí của các phần tử sau.

Các chuyển đổi loại bỏ hoàn toàn phần tử tương tự display:nonecó thể được thực hiện bằng cách sử dụng chiều cao (như được chỉ ra bởi các câu trả lời và nhận xét khác), chiều cao tối đa hoặc lề trên / dưới, nhưng cũng xem Làm thế nào tôi có thể chuyển đổi chiều cao: 0; đến chiều cao: tự động; sử dụng CSS? và bài đăng trên blog của tôi Cách giải quyết cho các chuyển tiếp CSS trên Thuộc tính hiển thị và chiều cao .

Đáp lại nhận xét từ GeorgeMillo: Cả hai thuộc tính và cả hai quá trình chuyển đổi đều cần thiết: Thuộc tính độ mờ được sử dụng để tạo hiệu ứng mờ dần và mờ dần và thuộc tính hiển thị để tránh phần tử vẫn phản ứng với các sự kiện chuột. Chuyển đổi là cần thiết về độ mờ cho hiệu ứng hình ảnh và khả năng hiển thị để trì hoãn ẩn cho đến khi hoàn thành mờ dần.


4

Cuối cùng tôi đã tìm ra giải pháp cho mình, bằng cách kết hợp opacityvới position absolute(không chiếm không gian khi ẩn).

.toggle {
  opacity: 0;
  position: absolute;
  transition: opacity 0.8s;
}

.parent:hover .toggle {
  opacity: 1;
  position: static;
}

4

Tôi nghi ngờ bất cứ ai chỉ bắt đầu chuyển đổi CSS nhanh chóng phát hiện ra rằng chúng không hoạt động nếu bạn sửa đổi thuộc tính hiển thị (chặn / không) cùng một lúc. Một cách giải quyết khác chưa được đề cập là bạn có thể tiếp tục sử dụng display:block/noneđể ẩn / hiển thị phần tử, nhưng đặt độ mờ của nó thành 0 để ngay cả khi nó display:blockvẫn còn ẩn.

Sau đó, để làm mờ dần nó, thêm một lớp CSS khác, chẳng hạn như "bật", đặt độ mờ thành 1 và xác định chuyển đổi cho độ mờ. Như bạn có thể tưởng tượng, bạn sẽ phải sử dụng JavaScript để thêm lớp "bật" đó vào thành phần, nhưng ít nhất bạn vẫn đang sử dụng CSS cho quá trình chuyển đổi thực tế.

PS Nếu bạn thấy mình trong tình huống cần thực hiện cả hai display:blockvà thêm lớp "bật", đồng thời, trì hoãn việc sau bằng cách sử dụng setTimeout. Mặt khác, trình duyệt chỉ thấy cả hai điều xảy ra cùng một lúc và vô hiệu hóa quá trình chuyển đổi.


Cảm ơn vô cùng! Tôi đã viết một câu trả lời khác với một ví dụ thực sự hoạt động với display:none.
mojuba

4

Nó đơn giản như sau :)

@keyframes fadeout {
    0% { opacity: 1; height: auto; }
    90% { opacity: 0; height: auto; }
    100% { opacity: 0; height: 0;
}
animation: fadeout linear 0.5s 1 normal forwards !important;

Làm cho nó mờ dần đi, và sau đó làm cho nó height 0;. Cũng đảm bảo sử dụng chuyển tiếp để nó ở trạng thái cuối cùng.


Điều này sẽ ngay lập tức thiết lập lại khi xóa lớp vì vậy đó không phải là một ý tưởng hay
Sean T

2

Giải pháp này có khả năng tương thích tuyệt vời và tôi chưa thấy nó:

.hidden-element {
  position: absolute;
  z-index: -1;
  pointer-events: none;
  visibility: hidden;
  opacity: 0;
  transition: visibility 0s, opacity .5s ease-out;
}

.hidden-element.visible {
  position: static;
  z-index: auto;
  pointer-events: auto;
  visibility: visible;
  opacity: 1;
}

Giải thích : nó sử dụng visibility: hiddenmánh khóe (tương thích với chương trình và hiển thị trực tiếp trên một bước), nhưng nó sử dụng kết hợp position: absolute; z-index: -1; pointer-events: none;để đảm bảo rằng container ẩn không chiếm dung lượngkhông trả lời các tương tác của người dùng .


1
Nhưng sự thay đổi của positionvẫn sẽ làm cho các yếu tố giật xung quanh, phải không?
Arsylum

Vâng, tất nhiên: position: absolutecó nghĩa là phần tử không chiếm bất kỳ khoảng trống nào, như được mô tả trong phần giải thích. Khi nó chuyển sang position: staticvà xuất hiện, nó sẽ chiếm không gian như một yếu tố bình thường, đó là điểm của câu hỏi này. Tôi đề nghị bạn thử nó!
Barshe Marois

2
Tôi đã làm. Nhưng nếu tôi hiểu đúng câu hỏi là về sự chuyển đổi . Như trong "hình ảnh động mượt mà".
Arsylum

2

Bạn có thể làm cho nó hoạt động theo cách tự nhiên mà bạn mong đợi - sử dụng màn hình - nhưng bạn phải điều tiết trình duyệt để nó hoạt động, sử dụng Javascript hoặc như những người khác đã đề xuất một mẹo ưa thích với một thẻ bên trong một thẻ khác. Tôi không quan tâm đến thẻ bên trong vì nó làm phức tạp thêm CSS và kích thước, vì vậy đây là giải pháp Javascript:

https://jsfiddle.net/b9chris/hweyecu4/17/

Bắt đầu với một hộp như:

<div id="box" class="hidden">Lorem</div>

Một hộp ẩn.

div.hidden {
    display: none;
}
#box {
    transition: opacity 1s;
}

Chúng tôi sẽ sử dụng một mẹo được tìm thấy trong một q / a liên quan, kiểm tra offsetHeight để điều chỉnh trình duyệt ngay lập tức:

https://stackoverflow.com/a/16575811/176877

Đầu tiên, một thư viện chính thức hóa thủ thuật trên:

$.fn.noTrnsn = function () {
    return this.each(function (i, tag) {
        tag.style.transition = 'none';
    });
};
$.fn.resumeTrnsn = function () {
    return this.each(function (i, tag) {
        tag.offsetHeight;    
        tag.style.transition = null;
    });
};

Tiếp theo, chúng tôi sẽ sử dụng nó để tiết lộ một hộp và làm mờ nó trong:

$('#button').on('click', function() {
    var tag = $('#box');
    if (tag.hasClass('hidden'))
        tag.noTrnsn().removeClass('hidden')
        .css({ opacity: 0 })
        .resumeTrnsn().css({ opacity: 1 });
    else
        tag.css({ opacity: 0 });
});

Điều này làm mờ dần hộp trong và ngoài. Vì vậy, .noTrnsn()tắt các hiệu ứng chuyển tiếp, sau đó chúng ta loại bỏ hiddenlớp, lật displaytừ nonemặc định của nó , block. Sau đó, chúng tôi đặt độ mờ thành 0 để sẵn sàng mờ dần. Bây giờ chúng tôi đã thiết lập giai đoạn, chúng tôi bật lại chuyển tiếp, với.resumeTrnsn() . Và cuối cùng, khởi động quá trình chuyển đổi bằng cách đặt độ mờ thành 1.

Không có thư viện, cả thay đổi để hiển thị và thay đổi độ mờ đục sẽ mang lại cho chúng tôi kết quả không mong muốn. Nếu chúng tôi chỉ đơn giản loại bỏ các cuộc gọi thư viện, chúng tôi sẽ không có chuyển đổi nào cả.

Lưu ý rằng ở trên không đặt hiển thị thành không hiển thị lại ở cuối hoạt hình mờ dần. Chúng tôi có thể nhận được fancier mặc dù. Chúng ta hãy làm như vậy với một cái mờ dần và tăng chiều cao từ 0.

Mến!

https://jsfiddle.net/b9chris/hweyecu4/22/

#box {
    transition: height 1s, opacity 1s;
}

Bây giờ chúng ta đang chuyển đổi cả chiều cao và độ mờ. Lưu ý rằng chúng tôi không đặt chiều cao, có nghĩa là mặc định , auto. Thông thường, điều này không thể được chuyển đổi - chuyển từ tự động sang giá trị pixel (như 0) sẽ giúp bạn không có chuyển đổi. Chúng tôi sẽ làm việc xung quanh đó với thư viện và một phương pháp thư viện nữa:

$.fn.wait = function (time, fn) {
    if (time)
        this.delay(time);
    if (!fn)
        return this;

    var _this = this;
    return this.queue(function (n) {
        fn.call(_this);
        n();
    });
};

Đây là một phương thức tiện lợi cho phép chúng tôi tham gia vào hàng đợi fx / hoạt hình hiện có của jQuery mà không yêu cầu bất kỳ khung hoạt hình nào hiện bị loại trừ trong jQuery 3.x. Tôi sẽ không giải thích cách thức hoạt động của jQuery, nhưng đủ để nói, hệ thống .queue().stop()hệ thống ống nước mà jQuery cung cấp giúp chúng tôi ngăn chặn hoạt hình của chúng tôi bước lên nhau.

Hãy tạo hiệu ứng trượt xuống.

$('#button').on('click', function() {
    var tag = $('#box');
    if (tag.hasClass('hidden')) {
        // Open it
        // Measure it
        tag.stop().noTrnsn().removeClass('hidden').css({
            opacity: 0, height: 'auto'
        });
        var h = tag.height();
        tag.css({ height: 0 }).resumeTrnsn()
        // Animate it
        .css({ opacity: 1, height: h })
        .wait(1000, function() {
            tag.css({ height: 'auto' });
        });
    } else {
        // Close it
        // Measure it
        var h = tag.noTrnsn().height();
        tag.stop().css({ height: h })
        .resumeTrnsn()
        // Animate it
        .css({ opacity: 0, height: 0 })
        .wait(1000, function() {
            tag.addClass('hidden');
        });
    }
});

Mã này bắt đầu bằng cách kiểm tra #boxvà liệu nó có bị ẩn hay không, bằng cách kiểm tra lớp của nó. Nhưng nó thực hiện được nhiều hơn bằng cách sử dụng lệnh wait()gọi thư viện, bằng cách thêm hiddenlớp vào cuối hoạt hình trượt / mờ, mà bạn mong muốn tìm thấy nếu nó thực sự bị ẩn - điều mà ví dụ đơn giản ở trên không thể làm được. Điều này cũng xảy ra để cho phép hiển thị / ẩn phần tử nhiều lần, đây là một lỗi trong ví dụ trước, vì lớp ẩn không bao giờ được khôi phục.

Bạn cũng có thể thấy các thay đổi CSS và lớp được gọi sau .noTrnsn()để đặt giai đoạn cho hoạt ảnh, bao gồm lấy số đo, như đo chiều cao cuối cùng #boxmà không hiển thị cho người dùng trước khi gọi.resumeTrnsn() và tạo hiệu ứng cho nó từ thiết lập đầy đủ đó giai đoạn đến giá trị CSS mục tiêu của nó.

Câu trả lời cũ

https://jsfiddle.net/b9chris/hweyecu4/1/

Bạn có thể chuyển nó khi nhấp bằng:

function toggleTransition() {
  var el = $("div.box1");

  if (el.length) {
    el[0].className = "box";
    el.stop().css({maxWidth: 10000}).animate({maxWidth: 10001}, 2000, function() {
        el[0].className = "box hidden";
    });
  } else {
    el = $("div.box");
    el[0].className = "box";
    el.stop().css({maxWidth: 10001}).animate({maxWidth: 10000}, 50, function() {
        el[0].className = "box box1";
    });
  }

  return el;
}

someTag.click(toggleTransition);

CSS là những gì bạn đoán:

.hidden {
    display: none;
}
.box {
    width: 100px;
    height: 100px;
    background-color: blue;
    color: yellow;
    font-size: 18px;
    left: 20px;
    top: 20px;
    position: absolute;
    -webkit-transform-origin: 0 50%;
    transform-origin: 0 50%;
    -webkit-transform: scale(.2);
    transform: scale(.2);
    -webkit-transition: transform 2s;
    transition: transform 2s;
}
.box1{
    -webkit-transform: scale(1);
    transform: scale(1);
}

Điều quan trọng là điều chỉnh thuộc tính hiển thị. Bằng cách loại bỏ lớp ẩn và sau đó đợi 50 ms, sau đó bắt đầu quá trình chuyển đổi qua lớp được thêm vào, chúng ta sẽ làm cho nó xuất hiện và sau đó mở rộng như chúng ta muốn, thay vì nó chỉ hiển thị trên màn hình mà không có bất kỳ hình ảnh động nào. Tương tự xảy ra theo cách khác, ngoại trừ chúng ta đợi cho đến khi hoạt hình kết thúc trước khi áp dụng ẩn.

Lưu ý: Tôi đang lạm dụng .animate(maxWidth)ở đây để tránh các setTimeoutđiều kiện chủng tộc. setTimeoutlà nhanh chóng để giới thiệu các lỗi ẩn khi bạn hoặc người khác nhặt mã mà không biết về nó. .animate()có thể dễ dàng bị giết với .stop(). Tôi chỉ đang sử dụng nó để đặt độ trễ 50 ms hoặc 2000 ms trên hàng đợi fx tiêu chuẩn nơi dễ dàng tìm thấy / giải quyết bởi các lập trình viên khác đang xây dựng trên đầu này.


1

Tôi đã có một vấn đề tương tự mà tôi không thể tìm thấy câu trả lời. Một vài tìm kiếm Google sau đó đã dẫn tôi đến đây. Xem xét tôi đã không tìm thấy câu trả lời đơn giản mà tôi hy vọng, tôi tình cờ tìm thấy một giải pháp vừa thanh lịch vừa hiệu quả.

Hóa ra thuộc tính visibilityCSS có một giá trị collapsethường được sử dụng cho các mục bảng. Tuy nhiên, nếu được sử dụng trên bất kỳ yếu tố nào khác, nó sẽ hiển thị chúng một cách hiệu quả như bị ẩn , gần giống như display: hiddennhưng với khả năng bổ sung mà phần tử đó không chiếm bất kỳ khoảng trống nào và bạn vẫn có thể làm động phần tử trong câu hỏi.

Dưới đây là một ví dụ đơn giản về điều này trong hành động.

function toggleVisibility() {
  let exampleElement = document.querySelector('span');
  if (exampleElement.classList.contains('visible')) {
    return;
  }
  exampleElement.innerHTML = 'I will not take up space!';
  exampleElement.classList.toggle('hidden');
  exampleElement.classList.toggle('visible');
  setTimeout(() => {
    exampleElement.classList.toggle('visible');
    exampleElement.classList.toggle('hidden');
  }, 3000);
}
#main {
  display: flex;
  flex-direction: column;
  width: 300px;
  text-align: center;
}

.hidden {
  visibility: collapse;
  opacity: 0;
  transition: visibility 2s, opacity 2s linear;
}

.visible {
  visibility: visible;
  opacity: 1;
  transition: visibility 0.5s, opacity 0.5s linear;
}
<div id="main">
  <button onclick="toggleVisibility()">Click Me!</button>
  <span class="hidden"></span>
  <span>I will get pushed back up...</span>
</div>


1

Giải pháp phổ biến đơn giản nhất cho vấn đề là: thoải mái chỉ định display:nonetrong CSS của bạn, tuy nhiên bạn sẽ thay đổi nó thành block(hoặc bất cứ điều gì khác) bằng JavaScript, và sau đó bạn cũng sẽ phải thêm một lớp vào phần tử của mình. thực hiện chuyển đổi với setTimeout () . Đó là tất cả.

I E:

<style>
    #el {
        display: none;
        opacity: 0;
    }
    #el.auto-fade-in {
        opacity: 1;
        transition: all 1s ease-out; /* Future, future, please come sooner! */
        -webkit-transition: all 1s ease-out;
        -moz-transition: all 1s ease-out;
        -o-transition: all 1s ease-out;
    }
</style>

<div id=el>Well, well, well</div>

<script>
    var el = document.getElementById('el');
    el.style.display = 'block';
    setTimeout(function () { el.className = 'auto-fade-in' }, 0);
</script>

Điều này đã được thử nghiệm trong các trình duyệt lành mạnh mới nhất. Rõ ràng là nó không hoạt động trong Internet Explorer 9 hoặc sớm hơn.


1

Tôi nghĩ SalmanPK có câu trả lời gần nhất. Nó làm mờ dần một mục trong hoặc ngoài, với các hình ảnh động CSS sau. Tuy nhiên, thuộc tính hiển thị không hoạt hình trơn tru, chỉ có độ mờ.

@-webkit-keyframes fadeIn {
    from { opacity: 0; }
      to { opacity: 1; }
}

@-webkit-keyframes fadeOut {
    from { opacity: 1; }
      to { opacity: 0; }
}

Nếu bạn muốn làm động phần tử chuyển từ khối hiển thị sang không hiển thị, tôi không thể thấy rằng hiện tại chỉ có thể với CSS. Bạn phải lấy chiều cao và sử dụng hoạt hình CSS để giảm chiều cao. Điều này là có thể với CSS như trong ví dụ dưới đây, nhưng sẽ rất khó để biết các giá trị chiều cao chính xác mà bạn cần để tạo hiệu ứng cho một phần tử.

ví dụ jsFiddle

CSS

@-webkit-keyframes pushDown {
  0% {
    height: 10em;
  }
  25% {
    height: 7.5em;
  }
  50% {
    height: 5em;
  }
  75% {
    height: 2.5em;
  }
  100% {
    height: 0em;
  }
}

.push-down {
    -webkit-animation: pushDown 2s forwards linear;
}

JavaScript

var element = document.getElementById("element");

// Push item down
element.className = element.className + " push-down";

1

Bạn có thể làm điều này với các sự kiện chuyển tiếp, vì vậy bạn xây dựng hai lớp CSS cho quá trình chuyển đổi, một lớp giữ hình động khác, không hiển thị trạng thái nào. Và bạn chuyển chúng sau khi hoạt hình kết thúc? Trong trường hợp của tôi, tôi có thể hiển thị lại các div nếu tôi nhấn nút và xóa cả hai lớp.

Hãy thử đoạn trích dưới đây ...

$(document).ready(function() {
  // Assign transition event
  $("table").on("animationend webkitAnimationEnd", ".visibility_switch_off", function(event) {
    // We check if this is the same animation we want
    if (event.originalEvent.animationName == "col_hide_anim") {
      // After the animation we assign this new class that basically hides the elements.
      $(this).addClass("animation-helper-display-none");
    }

  });

  $("button").click(function(event) {

    $("table tr .hide-col").toggleClass(function() {
      // We switch the animation class in a toggle fashion...
      // and we know in that after the animation end, there
      // is will the animation-helper-display-none extra
      // class, that we nee to remove, when we want to
      // show the elements again, depending on the toggle
      // state, so we create a relation between them.
      if ($(this).is(".animation-helper-display-none")) {
        // I'm toggling and there is already the above class, then
        // what we want it to show the elements , so we remove
        // both classes...
        return "visibility_switch_off animation-helper-display-none";
      }
      else {
        // Here we just want to hide the elements, so we just
        // add the animation class, the other will be added
        // later be the animationend event...
        return "visibility_switch_off";
      }
    });
  });
});
table th {
  background-color: grey;
}

table td {
  background-color: white;
  padding: 5px;
}

.animation-helper-display-none {
  display: none;
}

table tr .visibility_switch_off {
  animation-fill-mode: forwards;
  animation-name: col_hide_anim;
  animation-duration: 1s;
}

@-webkit-keyframes col_hide_anim {
  0% {opacity: 1;}
  100% {opacity: 0;}
}

@-moz-keyframes col_hide_anim {
  0% {opacity: 1;}
  100% {opacity: 0;}
}

@-o-keyframes col_hide_anim {
  0% {opacity: 1;}
  100% {opacity: 0;}
}

@keyframes col_hide_anim {
  0%   {opacity: 1;}
  100% {opacity: 0;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <theader>
    <tr>
      <th>Name</th>
      <th class='hide-col'>Age</th>
      <th>Country</th>
    </tr>
  </theader>
  <tbody>
    <tr>
      <td>Name</td>
      <td class='hide-col'>Age</td>
      <td>Country</td>
    </tr>
  </tbody>
</table>

<button>Switch - Hide Age column with fadeout animation and display none after</button>


0

Nếu bạn đang sử dụng jQuery để thiết lập các lớp của mình, điều này sẽ hoạt động 100%:

$(document).ready(function() {
  $('button').click(function() {
    var container = $('.container');
    
    if (!container.hasClass('active')) {
      container.addClass('show').outerWidth();
      container.addClass('active');
    }
    else {
      container.removeClass('active').one('transitionend', function() {
        container.removeClass('show');
      });
    }
  });
});
.container {
  display: none;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.container.show {
  display: flex;
}
 
.container.active {
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button">Toggle</button>

<div class="container">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>

Tất nhiên bạn chỉ có thể sử dụng jQuery .fadeIn()và các .fadeOut()hàm, nhưng lợi thế của việc thiết lập các lớp thay vào đó là trong trường hợp bạn muốn chuyển sang một giá trị hiển thị khác block(như mặc định với .fadeIn().fadeOut()).

Ở đây tôi đang chuyển đổi để hiển thị flexvới hiệu ứng mờ dần đẹp.


0

Thay vì sử dụng, displaybạn có thể lưu trữ phần tử 'ngoài màn hình' cho đến khi bạn cần nó, sau đó đặt vị trí của nó thành nơi bạn muốn và biến đổi nó cùng một lúc. Điều này mang đến một loạt các vấn đề thiết kế khác, vì vậy số dặm của bạn có thể thay đổi.

displayDù sao, có lẽ bạn sẽ không muốn sử dụng , vì bạn muốn nội dung có thể truy cập được đối với trình đọc màn hình, phần lớn cố gắng tuân theo các quy tắc về khả năng hiển thị - tức là, nếu nó không thể nhìn thấy bằng mắt, thì nó sẽ không hiển thị như nội dung cho các đại lý.


0

Bạn chỉ có thể sử dụng khả năng hiển thị CSS : hidden / viewer thay vì display : none / block

div {
    visibility:hidden;
    -webkit-transition: opacity 1s ease-out;
    -moz-transition: opacity 1s ease-out;
    -o-transition: opacity 1s ease-out;
    transition: opacity 1s ease-out;
    opacity: 0;
}

parent:hover > div {
    opacity: 1;
    visibility: visible;
}

5
Điều này dự trữ không gian mặc dù, để lại một lỗ trống. Nếu bạn muốn thu gọn một không gian, bạn phải tạo hiệu ứng chiều cao hoặc một số thuộc tính khác.
Marcy Sutton

0

Tôi đã bắt đầu một dự án bộ xương nguồn mở có tên Toggle Display Animate .

Trình trợ giúp bộ xương này sẽ cho phép bạn dễ dàng bắt chước / hiển thị jQuery, nhưng với các hoạt ảnh chuyển tiếp CSS 3 vào / ra.

Nó sử dụng các toggles lớp để bạn có thể sử dụng bất kỳ phương thức CSS nào bạn muốn trên các phần tử bên cạnh hiển thị: none | block | bảng | inline, v.v. cũng như các cách sử dụng thay thế khác có thể được nghĩ ra.

Mục đích thiết kế chính của nó là dành cho các trạng thái chuyển đổi phần tử và nó hỗ trợ trạng thái hoàn nguyên trong đó việc ẩn đối tượng cho phép bạn chạy khung hình chính của mình theo chiều ngược lại hoặc phát một hình ảnh động thay thế để ẩn phần tử.

Hầu hết các đánh dấu cho khái niệm tôi đang làm việc là CSS và có rất ít JavaScript thực sự được sử dụng.

Có một bản demo ở đây: http://marcnewton.co.uk/projects/toggle-display-animate/

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.