CSS-Rahmenanimationen

Verschiedene Möglichkeiten, einen Rahmen in CSS zu animieren

Rahmenlinien festlegen

Es gibt mehrere Methoden, um einen Rahmen für ein Element festzulegen: border, outline und box-shadow. Wie Stephanie Eckles in The 3 CSS Methods for Adding Element Borders (Die 3 CSS-Methoden zum Hinzufügen von Elementrahmen) beschreibt, hat jeder Ansatz seine eigenen Vor- und Nachteile, insbesondere wenn es um die Animation der Rahmen geht. Der Hauptgrund, warum kein richtiges CSS-border verwendet wird, sind Animationen.

Border Animations using outline-offset von Kevin J. Powell

Ein Artikel, der mir kürzlich aufgefallen ist, ist Fantastic CSS border animation, in dem die Autorin Coco weitere Optionen untersucht hat. Durch das Einfügen von generierten Inhalten mit ::before und ::after wird ein künstlicher Rahmen erstellt, der dann animiert wird.

Am meisten fallen mir die unterstützenden animierten Visualisierungen im Artikel auf. Sie helfen dabei, genau zu erklären, was getan wird, um den gewünschten Effekt zu erzielen.

Border Animations using generated content von Coco

Sowohl die weiße Ebene als auch die farbigen Linien sind generierte Inhalte. Durch das Ein- und Ausblenden der weißen Ebene wird deutlich, wie sie gestapelt sind und wie die Animation funktioniert.

Box-Modell beibehalten

Ein Nachteil der Verwendung von generierten Inhalten zur Imitation eines Rahmens ist, dass das Box-Modell fehlerhaft ist: Der Inhalt kann den künstlichen Rahmen verdecken, da dieser „Rahmen“ darunter gezeichnet wird. Zur Minimierung müssen Sie die gewünschte border-width als padding anwenden.

Wenn Sie einen echten Rahmen verwenden und somit die Funktionsweise des Box-Modells beibehalten möchten, können Sie mehrere Hintergründe verwenden, die Sie dann in den Rahmenbereich ausdehnen.

Grundlagen

Beginnen wir mit dem Erstellen eines gepunkteten Rahmens und dem Hinzufügen mehrerer Hintergründe.

/* Size of the border */
--border-size: 0.5rem;

/* Create a dotted border */
border: var(--border-size) dotted lime;

/* Create two background layers:
   1. A white semi-transparent
   2. A layer with the colored boxes
 */
background-image:
  linear-gradient(to right, rgb(255 255 255 / 0.5), rgb(255 255 255 / 0.5)),

  conic-gradient(
    from 45deg,
    #d53e33 0deg 90deg,
    #fbb300 90deg 180deg,
    #377af5 180deg 270deg,
    #399953 270deg 360deg
  )
;

Hintergründe mit background-origin anpassen

Wie Sie sehen, stimmt etwas mit den Hintergründen nicht: Sie sind in den Rahmen gezeichnet, aber der conic-gradient scheint völlig falsch zu sein. Das ist tatsächlich so beabsichtigt: Standardmäßig werden Hintergrundbilder nicht in den Rahmen gezeichnet, da ihr Ursprung der padding-box des Elements ist. Um dennoch einen Rahmen zu erstellen, werden die festgelegten Hintergrundbilder im Rahmen selbst wiederholt, was zu einem merkwürdigen visuellen Effekt führt.

Um dieses Problem zu beheben, müssen Sie den Hintergrund so strecken, dass er auch die Größe des Rahmens einnimmt. Sie könnten dies manuell tun, indem Sie den Hintergrund strecken und neu positionieren. Am besten ist es jedoch, die Property background-origin zu verwenden, um die Größe des Hintergrunds an das border-box anzupassen.

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 3.

Source

Was Sie nicht tun sollten
/* Manually add or offset the size of the border where needed */
background-position: calc(var(--border-size) * -1) calc(var(--border-size) * -1);
background-size: calc(var(--border-size) * 2 + 100%) calc(var(--border-size) * 2 + 100%);
Das sollten Sie tun:
background-origin: border-box;

Diese eine Ergänzung lässt alles viel besser aussehen:

Weiße Hintergrundebene mit background-clip verkleinern

Da die Hintergründe jetzt den gesamten Platz einnehmen, muss die halbtransparente Ebene wieder verkleinert werden. Anstatt sich noch einmal mit background-size zu beschäftigen, gibt es eine einfachere Möglichkeit: Verwenden Sie background-clip und legen Sie es auf padding-box fest. So wird der Hintergrund nicht mehr unter dem Bereich des Rahmens gezeichnet.

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 5.

Source

background-clip:
  padding-box, /* Clip white semi-transparent to the padding-box */
  border-box /* Clip colored boxes to the border-box (default) */
;

Wählen Sie schließlich transparent für den Rahmen aus, um den vollen Effekt zu erzielen.

border: 0.3rem dotted transparent;

Animation

Wenn Sie die Animation des Rahmens wiederherstellen möchten, können Sie den Startwinkel des conic-gradient-Elements ändern.

--angle: 0deg;
conic-gradient(
  from var(--angle),
  #d53e33 0deg 90deg,
  #fbb300 90deg 180deg,
  #377af5 180deg 270deg,
  #399953 270deg 360deg
);

Dank @property ist das in Browsern, die es unterstützen, ein Kinderspiel:

Browser Support

  • Chrome: 85.
  • Edge: 85.
  • Firefox: 128.
  • Safari: 16.4.

Source

@property --angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

@keyframes rotate {
  to {
    --angle: 360deg;
  }
}

Zusammengefasst sieht der Code so aus:

Bonusinhalte: border-image

Ein bereits beschriebener Ansatz zum Zeichnen eines Farbverlaufsrahmens ist die Verwendung von CSS-border-image.

Browser Support

  • Chrome: 16.
  • Edge: 12.
  • Firefox: 15.
  • Safari: 6.

Source

Der Code wird vereinfacht, da Sie sich nicht um überlappende Hintergründe kümmern müssen. Animationen können wie zuvor angewendet werden.

/* Create a border */
border: 0.5rem solid transparent;

/* Paint an image in the border */
border-image:
  conic-gradient(
    from var(--angle),
    #d53e33 0deg 90deg,
    #fbb300 90deg 180deg,
    #377af5 180deg 270deg,
    #399953 270deg 360deg
  ) 1
;

Bei diesem Ansatz funktionieren jedoch einige Dinge nicht mehr:

  • Der border-image folgt nicht dem border-radius, sondern bleibt immer rechteckig.
  • Wenn border-image-slice auf „fill“ gesetzt ist, wird border-image nicht unter dem festgelegten background, sondern darüber gezeichnet. Das kann problematisch sein, wenn der Hintergrund halbtransparent sein soll.

Fazit

Es gibt viele Möglichkeiten, Rahmen in CSS zu animieren. Je nach Anwendungsfall können Sie sich für die eine oder andere Variante entscheiden.