2016-08-27 8 views
5

Używam przejścia CSS z właściwością transform, aby zmniejszyć elementy podczas ich dodawania i usuwania.Jak przekształcić CSS wpływa na przepływ innych elementów

Jednak jednym z problemów jest to, że ta właściwość nie wpływa na przepływ innych elementów, więc wygląda na to, że element, który się usuwa, zmniejsza się, a reszta elementów nagle się skacze.

Gdybym miał animować właściwość wysokości zamiast używać transformacji, byłoby to w porządku, jednak w rzeczywistym użyciu używam elementów o zmiennej wysokości, więc nie będę wiedział, na jakie wysokości mogę animować.


Edit: ludzie sugerowali animowanie właściwości height (która nie będzie działać, jak wspomniano powyżej), albo właściwość max-height. Właściwość max-height będzie działać w pewnym stopniu, jednak nie można idealnie wyliczyć ustawień czasowych, ponieważ przejście będzie dostosowywać właściwość max-height poza rzeczywistą wysokość elementu do końca czasu przejścia.

Innym problemem związanym z tymi podejściami jest to, że nie wykorzystuje płynnych animacji, które można uzyskać za pomocą właściwości transform. Transformacja obiektu stanie się płynna, jednak ruch następujących elementów będzie się zacinał, ponieważ przeglądarka renderuje te przejścia w różny sposób.


Oto JSFiddle o co mi chodzi (spróbuj dodać następnie usuwanie elementów i zobaczyć skok, gdy elementy są usuwane):

var button = document.querySelector("button"); 
 
var box = document.createElement("div"); 
 

 
box.className = "box"; 
 
box.appendChild(document.createTextNode("Click to delete")); 
 

 
button.addEventListener("click", function(e) { 
 
    var new_box = box.cloneNode(true); 
 

 
    new_box.addEventListener("click", function(e) { 
 
    this.className = "box deleting"; 
 
    window.setTimeout(function(e) { 
 
     new_box.remove(); 
 
    }, 1000); 
 
    }); 
 

 
    this.parentNode.appendChild(new_box); 
 
});
button { 
 
    font-size: 20pt; 
 
} 
 
.box { 
 
    font-size: 20pt; 
 
    margin: 10px; 
 
    width: 200px; 
 
    padding: 10px; 
 
    background: pink; 
 
    transform: scale(1, 1); 
 
    transform-origin: top left; 
 
} 
 
.deleting { 
 
    transform: scale(1, 0); 
 
    transition: all 1000ms ease; 
 
}
<button> 
 
    Add Box 
 
</button>

Odpowiedz

1

Dla elementów, których układ jest regulowany modelu pudełkowego CSS, przekształcić właściwość nie ma wpływu na przepływ treści otaczającego przekształcona elementu.

REF: Transform Rendering

Będziesz musiał użyć właściwości max-height (check this answer), aby uzyskać pożądany efekt.

var button = document.querySelector("button"); 
 
var box = document.createElement("div"); 
 

 
box.className = "box"; 
 
box.appendChild(document.createTextNode("Click to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to delete")); 
 

 
button.addEventListener("click", function(e) { 
 
    var new_box = box.cloneNode(true); 
 
    new_box.style.height = (Math.random() * (200 - 30) + 30) + 'px'; 
 

 
    new_box.addEventListener("click", function(e) { 
 
    this.className = "box deleting"; 
 
    window.setTimeout(function(e) { 
 
     new_box.remove(); 
 
    }, 1000); 
 
    }); 
 

 
    this.parentNode.appendChild(new_box); 
 
});
button { 
 
    font-size: 20pt; 
 
} 
 
.box { 
 
    overflow:hidden; 
 
    font-size: 12pt; 
 
    margin-bottom: 10px; 
 
    width: 600px; 
 
    max-height:1000px; 
 
    padding: 10px; 
 
    background: pink; 
 
    transform: scaleY(1); 
 
    transform-origin: top left; 
 
} 
 
.deleting { 
 
    transform: scaleY(0); 
 
    max-height:0; 
 
    padding:0 10px; 
 
    margin-bottom:0; 
 
    transition: padding 1000ms ease,max-height 1000ms ease, transform 500ms ease 500ms, margin-bottom 1000ms ease; 
 
}
<button> 
 
    Add Box 
 
</button>

+0

Nie znosząc sprawy, ale czy przetestowałeś swoją odpowiedź? W najlepszym razie jest szałowy. –

+0

@RyanWheale To naprawdę działa dobrze dla elementów o znanym zakresie wysokości, takich jak 500px do 800px, problem polega na tym, że czas animacji będzie zależał od zastosowanej wysokości maksymalnej. Chciałem tylko wskazać tę możliwość :) – sabithpocker

+0

OK, dokonałem pewnych modyfikacji, aby zademonstrować rozwiązanie! Ale znowu działa to tylko dla pewnych scenariuszy :) – sabithpocker

0

Można by stworzyć owinięcie wokół kurczące się pudełka. Teraz właśnie przeskalujesz czerwone pola, co oznacza, że ​​wciąż używasz tej samej przestrzeni, ale renderowanej w skalowany sposób. Kiedy w końcu go usuniesz, nie używa już tej przestrzeni, elementy pod nią przeskoczą w górę.

Jeśli utworzysz opakowanie wokół każdego czerwonego pudełka, możesz kontrolować zajmowaną przestrzeń. Po prostu zmień wysokość tego opakowania, z przejściem też.

/* css for a wrapper */ 
overflow: hidden; 
transition: height .2s; /* your time */ 

Tak więc, nie tylko skala czerwone pudełka z przejścia, ale także umieścić je w elemencie owijania i zmienić wysokość tego elementu.

0

Aby uzyskać najlepszy efekt, należy zmodyfikować właściwości boksu, które mają wpływ na otoczenie. Obejmuje to szerokość/wysokość, dopełnienie, marginesy i szerokość obramowania. W poniższym przykładzie ustawiam odpowiednie właściwości na 0 dla pożądanego efektu. Obejmuje to wszystkie właściwości, które wpływają na pionowy odstęp elementu: height, padding-[top/bottom], margin-[top/bottom], a wszystko border-[top/bottom]-width zostały przeniesione do 0.

Dodałem też box-sizing: border-box; i overflow: hidden; do okna - trzeba zobaczyć, co się dzieje, gdy te nie są zestaw. Pozwolę ci samemu się o tym dowiedzieć.

var button = document.querySelector("button"); 
 
var box = document.createElement("div"); 
 

 
box.className = "box"; 
 
box.appendChild(document.createTextNode("Click to delete")); 
 

 
button.addEventListener("click", function(e) { 
 
    var new_box = box.cloneNode(true); 
 

 
    new_box.addEventListener("click", function(e) { 
 
    new_box.style.height = this.offsetHeight + 'px'; 
 
    window.requestAnimationFrame(function() { 
 
     new_box.style.height = 0; 
 
     new_box.className = "box deleting"; 
 
     window.setTimeout(function(e) { 
 
     new_box.remove(); 
 
     }, 1000); 
 
    }); 
 
    }); 
 

 
    this.parentNode.appendChild(new_box); 
 
});
button { 
 
    font-size: 20pt; 
 
} 
 
.box { 
 
    box-sizing: border-box; 
 
    overflow: hidden; 
 
    font-size: 20pt; 
 
    margin: 10px; 
 
    width: 200px; 
 
    padding: 10px; 
 
    border: 5px solid red; 
 
    background: pink; 
 
    transform: scale(1, 1); 
 
    transform-origin: top left; 
 
} 
 
.deleting { 
 
    height: 0; 
 
    padding-top: 0; 
 
    padding-bottom: 0; 
 
    margin-top: 0; 
 
    margin-bottom: 0; 
 
    border-top-width: 0; 
 
    border-bottom-width: 0; 
 
    transform: scale(1, 0); 
 
    transition: all 1000ms ease; 
 
}
<button> 
 
    Add Box 
 
</button>

+0

Cześć Ryan, dzięki za odpowiedź. Będzie to działać dla elementów o stałej wysokości, jednak nie działa dla elementów o zmiennej wysokości. – Lauren

+0

Dzięki @Lauren - Pomyślałem, że za pomocą guzików, nie ma dużej szkody w stałej wysokości. Nie prosiłeś o uniwersalne rozwiązanie, ale masz całkowitą rację - nie wspomniałem o wymaganiach dotyczących stałej wysokości w mojej oryginalnej odpowiedzi. Zaktualizowałem go, aby nie wymagał już stałej wysokości. –

+4

Warto również wspomnieć, że po uruchomieniu animacji, które są dołączone do stanu aplikacji, można bardzo szybko dostać się do kłopotów, miksując animacje css. Występują różnego rodzaju problemy z czasem, kolejność pierwszeństwa i [najgorsze] kwestie związane z konserwacją. Na przykład, jeśli chcesz, aby czas trwania wynosił 500 ms, musisz go zmienić w dwóch miejscach - nie dobrze. Znalazłem po 10 latach, że tego typu animacje powinny być wykonywane tylko w JavaScript. Animacje CSS są dobre dla prostych, prostych rzeczy, które nie są związane ze stanem twojej aplikacji. –

Powiązane problemy