Verschiedene Methoden für die Erweiterung der Box, Während die Erhaltung der Border-Radius

0
15

Ich habe vor kurzem bemerkt, eine interessante Veränderung auf CodePen: wenn Sie den Mauszeiger Stifte auf der homepage gibt es ein Rechteck mit abgerundeten Ecken erweitert in den Rücken.

Expanding-box-Effekt auf der CodePen-homepage.

Die merkwürdige Kreatur, die ich bin, musste ich schauen, wie das funktioniert! Stellt sich heraus, das Rechteck in der Rückseite ist ein absolut positioniert ::after pseudo-element.

Initial ::nach Stilen. Ein positiver Versatz nach innen von den Eltern Polsterung begrenzen, während eine negative geht man nach außen.

Auf :hover, seine offsets überschrieben werden und, kombiniert mit dem übergang, so erhalten wir die ausbau-box-Effekt.

Der ::nach der Stile auf :hover.

Die richtige Eigenschaft hat denselben Wert (-1rem) in sowohl der ersten und der :hover-Regel setzt, so ist es unnötig, um es zu überschreiben, aber alle anderen offsets verschieben von 2rem nach außen (von 1rem zu 1rem für den oberen und linken Abstände und aus -1rem zu 3rem für den unteren offset)

Eine Sache zu beachten hier ist, dass die ::after pseudo-element hat einen border-radius von 10px, die wird beibehalten, da es sich ausdehnt. Das hat mir zu denken über das, was Methoden, die wir für erweitern/schrumpfen (pseudo-) Elemente, während die Erhaltung Ihrer border-radius. Wie viele können Sie denken? Lassen Sie mich wissen, wenn Sie Ideen haben, die nicht unten aufgeführt, wo wir einen Blick auf ein paar Optionen und sehen, welche ist am besten geeignet für welche situation.

Ändern der offsets

Dies ist die Methode, die verwendet werden auf CodePen und es funktioniert wirklich gut, in dieser besonderen situation für eine Reihe von Gründen. First off, es hat große Unterstützung. Es funktioniert auch, wenn der ausbau (pseudo-) element reagiert, in dem es keine festen Abmessungen und in der gleichen Zeit, die Menge, auf die es baut, ist behoben (eine rem-Wert). Es funktioniert auch für die Expansion in mehr als zwei Richtungen (oben, unten und Links, in diesem Fall).

Es gibt jedoch ein paar Vorsichtsmaßnahmen, die wir beachten müssen.

Erstmals, unser wachsendes element kann nicht position: static. Dies ist nicht ein problem im Zusammenhang mit der CodePen use-case-seit dem ::after-pseudo-element muss absolut positioniert werden sowieso in Ordnung zu sein, unter den der rest von diesem übergeordneten Inhalt.

Zweite, über Bord gehen mit offset-Animationen (sowie, im Allgemeinen, animierend jede Eigenschaft wirkt sich auf die Anordnung mit der box-Eigenschaften die Art und Weise offsets, Margen, randbreiten, Polstern oder Abmessungen zu tun) kann sich negativ auf die Leistung auswirken. Wieder, dies ist nicht etwas, Sorge hier, wir haben nur eine kleine Umstellung :hover, keine große Sache.

Änderung der Dimensionen

Anstelle der änderung offsets, wir ändern könnte verwenden Maße statt. Allerdings ist dies eine Methode, die funktioniert, wenn wir wollen, dass unsere (pseudo-) element zu vergrößern, bei den meisten zwei Richtungen. Ansonsten müssen wir ändern offsets als gut. Um besser zu verstehen, betrachten wir die CodePen situation, wo wir wollen, dass unsere ::after pseudo-Elemente zu erweitern, sich in drei Richtungen (oben, unten und Links).

Die relevanten Initialen sizing info ist folgende:

.single-Element::after {
top: 1rem;
rechts: -1rem;
unten: -1rem;
Links: 1rem;
}

Da die gegnerischen offsets (oben-unten und rechts-Links-Paare) heben sich gegenseitig auf (1rem – 1rem = 0), ergibt sich, dass die pseudo-element-Maße sind gleich denen Ihrer Eltern (oder 100% des übergeordneten Dimensionen).

So können wir re-schreiben zu den oben genannten:

.single-Element::after {
top: 1rem;
rechts: -1rem;
width: 100%;
height: 100%;
}

Auf :hover, erhöhen wir die Breite von 2rem auf der linken Seite und die Höhe von 4rem, 2rem an die Spitze und 2rem nach unten. Allerdings nur zu schreiben:

.single-Element::after {
width: calc(100% + 2rem);
height: calc(100% + 4rem);
}

…ist das nicht genug, macht die Höhe zu erhöhen der Richtung nach unten durch 4rem statt zu erhöhen, indem 2rem und 2rem nach unten. Die folgende demo zeigt diese (setzen :konzentrieren Sie sich auf oder bewegen Sie den Mauszeiger über die Elemente, um zu sehen, wie die ::after pseudo-element erweitert):

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Wir brauchen ein update der top-Eigenschaft, um auch den gewünschten Effekt:

.single-Element::after {
top: -1rem;
width: calc(100% + 2rem);
height: calc(100% + 4rem);
}

Die funktioniert, wie man unten sehen kann:

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Aber, um ehrlich zu sein, fühlt sich weniger wünschenswert als die änderung der offsets allein.

Jedoch, änderung der Maße ist eine gute Lösung, in einer anderen Art von situation, wie wenn wir wollen, haben einige bars mit abgerundeten Ecken, erweitern/verkleinern in eine einzige Richtung.

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Beachten Sie, dass, wenn wir nicht über abgerundete Ecken zu erhalten, die bessere Lösung wäre die Verwendung direktionale Skalierung über die transform-Eigenschaft.

Ändern der padding/border-width

Ähnlich wie das ändern der Abmessungen, können wir uns ändern der padding-oder border-width (für eine Grenze das ist transparent). Beachten Sie, dass, genau wie mit dem Wechsel der Dimensionen, wir müssen auch die update-offsets, wenn die Erweiterung der box in mehr als zwei Dimensionen:

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

In der demo oben, die rosa-box stellt den Inhalt-box von ::after pseudo-element, und Sie können sehen, es bleibt die gleiche Größe, was wichtig ist für diesen Ansatz.

Um zu verstehen, warum es so wichtig ist, sollten Sie diese weitere Einschränkung: wir müssen auch über die box-Dimensionen, definiert durch zwei offsets sowie die Breite und die Höhe anstatt alle vier offsets. Dies ist, weil die padding/ border-width würde nur wachsen nach innen, wenn wir vier offsets anstatt zwei plus die Breite und die Höhe.

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Aus dem gleichen Grund können wir nicht box-sizing: border-box auf unserer ::after pseudo-element.

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Trotz dieser Einschränkungen, kann diese Methode in handliches kommen, wenn Sie unsere Erweiterung (pseudo-) element -, text-Inhalte, die wir nicht sehen wollen, bewegen auf :bewegen Sie wie abgebildet mit der Feder unten, wo die ersten beiden Beispiele ändern offsets/ Dimensionen, während die letzten beiden Wechsel-Polster/ randbreiten:

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Ändern Rand

Mit dieser Methode, setzen wir zuerst die offsets zu den :hover-Status-Werte und eine Marge zu kompensieren und geben Sie uns die Initialen Zustand Größe:

.single-Element::after {
top: -1rem;
rechts: -1rem;
unten: -3rem;
Links: -1rem;
Marge: 2rem 0 2rem 2rem;
}

Dann haben wir null diese Marge auf :hover:

.single-item:hover::after { margin: 0 }

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Dies ist ein weiterer Ansatz, die gut funktioniert für die CodePen situation, obwohl ich nicht wirklich glaube, die anderen Fällen verwenden. Beachten Sie auch, dass, gerade wie das ändern der offsets oder Dimensionen, diese Methode wirkt sich auf die Größe der content-box, so dass keine text-Inhalte, die wir haben können, wird verschoben und neu angeordnet.

Ändern der Schriftgröße

Dies ist wahrscheinlich die schwierigste von allen und hat viele Einschränkungen, die wichtigste, die wir haben, kann nicht-text-Inhalt auf die aktuelle (pseudo-) element, das sich ausdehnt/schrumpft — aber es ist eine andere Methode, die funktionieren würde gut in die CodePen Fall.

Auch font-size auf seine eigene ist nicht wirklich etwas tun, um eine box zu erweitern oder zu verkleinern. Wir kombinieren es mit einem der zuvor diskutierten Eigenschaften.

Zum Beispiel, wir können die font-size auf ::nach gleich 1rem, legen Sie die offsets, um die erweiterten Fall und legen Sie em-Margen, entspräche der Unterschied zwischen der erweiterten und der ursprüngliche Zustand.

.single-Element::after {
top: -1rem;
rechts: -1rem;
unten: -3rem;
Links: -1rem;
margin: 2em 0 2em 2em;
font-size: 1rem;
}

Dann auf :bewegen Sie, bringen wir die font-size auf 0:

.single-item:hover::after { font-size: 0 }

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Wir können auch font-size mit offsets, obwohl, wird es etwas komplizierter:

.single-Element::after {
top: calc(2em – 1rem);
rechts: -1rem;
unten: calc(2em – 3rem);
Links: calc(2em – 1rem);
font-size: 1rem;
}

.single-item:hover::after { font-size: 0 }

Dennoch ist das, was wichtig ist, ist, dass es funktioniert, wie man unten sehen kann:

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Die Kombination von schriftart,-Größe mit den Maßen ist auch hairier, wie wir müssen Sie auch ändern Sie den vertikalen offset-Wert auf :hover auf Anfang von allem:

.single-Element::after {
top: 1rem;
rechts: -1rem;
width: calc(100% + 2em);
height: calc(100% + 4em);
font-size: 0;
}

.single-item:hover::after {
top: -1rem;
font-size: 1rem
}

Oh, naja, zumindest funktioniert es:

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Dasselbe gilt für die Verwendung von font-size mit padding/border-width:

.single-Element::after {
top: 1rem;
rechts: -1rem;
width: 100%;
height: 100%;
font-size: 0;
}

.single-item:nth-child(1)::after {
padding: 2em 0 2em 2em;
}

.single-item:nth-child(2)::after {
border: 0 solid transparent;
border-width: 2em 0 2em 2em;
}

.single-item:hover::after {
top: -1rem;
font-size: 1rem;
}

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Ändern der Skalierung

Wenn Sie gelesen haben Stücke auf animation, performance, dann haben Sie wahrscheinlich Lesen Sie es besser, zu animieren, verwandelt anstelle von Eigenschaften, die Auswirkungen auf das layout, wie offsets, Ränder, Rahmen, Polster, Dimensionen — ziemlich viel, was wir bisher verwendet habe!

Die erste Frage, die hier steht, ist, dass die Skalierung eines Elements skaliert seiner Ecke Rundung, wie unten dargestellt:

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Wir können dies umgehen, indem man auch die Skalierung der border-radius auf die andere Weise.

Lassen Sie uns sagen, dass wir die Skala ein element um einen Faktor $fx entlang der x-Achse und um einen Faktor $fy entlang der y-Achse, und wir wollen, zu halten Ihr border-radius auf einen Konstanten Wert $r.

Das heißt, wir müssen auch teilen $r durch die entsprechende Skalierung an jeder Achse.

border-radius: #{$r/$fx}/ #{$r/$fy};
transform: scale($fx, $fy)

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Beachten Sie jedoch, dass mit dieser Methode, die wir brauchen, um die Verwendung von Skalierungsfaktoren, nicht die Beträge, durch die wir erweitern unsere (pseudo-) element in diese oder jene Richtung. Immer die Skalierungsfaktoren von den Abmessungen und den ausbau Beträge ist möglich, aber nur, wenn Sie ausgedrückt in Einheiten, die eine gewisse Feste Beziehung zwischen Ihnen. Während Präprozessoren können mix-Einheiten wie in “oder” px ” aufgrund der Tatsache, dass 1in immer 96px, die Sie nicht lösen können, wie viel 1em oder 1% oder 1vmin oder 1ch ist in px, da fehlt Kontext. Und calc() ist keine Lösung, da es nicht erlauben, uns aufzuteilen, um eine Länge mit dem Wert von einer anderen Länge Wert zu bekommen einheitenlosen Skalierungsfaktor.

Dies ist der Grund, warum die Skalierung nicht eine Lösung in der CodePen Fall, wo der ::nach der Boxen haben Abmessungen, die abhängig von der viewport und, zur gleichen Zeit, erweitern Sie durch Feste rem Mengen.

Aber wenn unsere Größe Betrag angegeben ist, können wir leicht berechnen, dies ist eine option zu berücksichtigen, vor allem da die Skalierungsfaktoren für die benutzerdefinierten Eigenschaften, die wir dann animieren, mit etwas von Houdini magic deutlich vereinfachen kann unseren code.

border-radius: calc(#{$r}/var(–fx))/ calc(#{$r}/var(–fy));
transform: Skala(var(–fx), var(–fy))

Beachten Sie, dass Houdini funktioniert nur in Chrom Browser mit der Experimental-Web-Platform-features – flag aktiviert.

Zum Beispiel, wir können diese tile-grid-animation:

Looping-tile-grid-animation (Demo, Chrom mit fahne, nur)

Die quadratischen Fliesen haben eine Kantenlänge $l und mit einer eckenrundung von $k*$l:

.Kachel {
Breite: $l;
Höhe: $l;
border-radius: calc(#{$r}/var(–fx))/ calc(#{$r}/var(–fy));
transform: Skala(var(–fx), var(–fy))
}

Wir registrieren unsere beiden benutzerdefinierten Eigenschaften:

CSS.registerProperty({
name: ‘–fx’,
syntax: ‘<Anzahl>’,
initialValue: 1,
erbt: false
});

CSS.registerProperty({
name: ‘–fy’,
syntax: ‘<Anzahl>’,
initialValue: 1,
erbt: false
});

Und dann können wir Sie animieren:

.Kachel {
/* gleich wie vorher */
animation: ein $t infinite ease-in-Alternative;
animation-name: fx, fy;
}

@keyframes fx {
0%, 35% { –fx: 1 }
50%, 100% { –fx: #{2*$k} }
}

@keyframes fy {
0%, 35% { –fy: 1 }
50%, 100% { –fy: #{2*$k} }
}

Schließlich, fügen wir eine Verzögerung abhängig von der horizontalen (–i) und vertikale (–j) grid-Indizes, um eine gestaffelte animation-Effekt:

animation-delay:
calc((var(–i) + var(–m) – var(–j))*#{$t}/(2*var(–m) – #{$t}),
calc((var(–i) + var(–m) – var(–j))*#{$t}/(2*var(–m) – #{1.5*$t})

Ein weiteres Beispiel ist das folgende, wo die Punkte sind mit Hilfe der pseudo-Elemente:

Looping-Spitzen animation (Demo, Chrom mit fahne, nur)

Da die pseudo-Elemente skaliert zusammen mit Ihren Eltern, wir müssen auch Umgekehrt die Skalierung transformieren auf Sie:

.spike {
/* andere spike styles */
Transformation: var(–position) scalex(var(–fx));

&::before, &::after {
/* andere pseudo-styles */
transform: scalex(calc(1/var(–fx)));
}
}

Ändern… clip-Pfad?!

Dies ist eine Methode, die ich wirklich mag, obwohl es schneidet pre-Chrom Rand-und Internet Explorer-Unterstützung.

So ziemlich jedes Beispiel zur Verwendung von clip-Pfad gibt, hat entweder ein polygon () – Wert oder eine SVG-Referenz-Wert. Allerdings, wenn Sie habe gesehen, wie einige meiner früheren Beiträge, dann haben Sie wahrscheinlich wissen, gibt es andere einfache Formen, die wir verwenden können, wie inset(), Werke, die, wie unten dargestellt:

Wie die inset () – Funktion funktioniert. (Demo)

So, um das zu reproduzieren, der CodePen-Effekt mit dieser Methode setzen wir die ::nach offsets, um den erweiterten Status-Werte und schneiden Sie dann aus, was wir nicht sehen wollen, mit Hilfe der clip-Pfad:

.single-Element::after {
top: -1rem;
rechts: -1rem;
bottom: -3em;
left: -1em;
clip-path: inset(2rem 0 2rem 2rem)
}

Und dann, in der :hover-Zustand, wir null alle Einsätze:

.single-item:hover::after {
clip-path: inset(0)
}

Dies kann gesehen werden in Aktion unten:

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Okay, das funktioniert, aber wir brauchen auch eine Ecke Rundung. Zum Glück, inset() können wir angeben, dass zu irgendeinem border-radius Wert, den wir wünschen.

Hier, ein 10px man für alle vier Ecken zusammen beide Richtungen funktioniert es:

.single-Element::after {
/* gleichen Stile wie zuvor */
clip-path: inset(2rem 0 2rem 2rem Runde 10px)
}

.single-item:hover::after {
clip-path: inset(0 Runde 10px)
}

Und das gibt uns genau das, was wir angestrebt haben:

Finden Sie den Stift, indem Sie thebabydino (@thebabydino) auf CodePen.

Darüber hinaus ist es nicht wirklich etwas zu brechen, in nicht-unterstützende Browser, nur es bleibt immer im maximierten Zustand.

Während jedoch diese Methode, die funktioniert gut für eine Vielzahl von Situationen, einschließlich der CodePen use-case — es klappt nicht, wenn unsere expandierenden/schrumpfenden Elemente haben Nachkommen, die sich außerhalb Ihrer beschnitten Eltern border-box, wie es der Fall für das Letzte Beispiel mit den zuvor erörterten Skalierung-Methode.