Rocking Californias "I Voted"-Aufkleber in CSS für den Wahltag 2018

Avatar of Geoff Graham
Geoff Graham am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Hallo, also morgen (morgen!) ist Wahltag hier in den Vereinigten Staaten. Wir sind nicht dazu da, politische Empfehlungen abzugeben oder Ähnliches bei CSS-Tricks, obwohl wir dafür sind, dass jeder sein Wahlrecht ausübt.

Genau das habe ich vor zwei Jahren getan und eine CSS-Nachbildung des "I Voted"-Aufklebers gepostet, der mit meinem kalifornischen Briefwahlumschlag kam.

Siehe den Pen I Voted Sticker von Geoff Graham (@geoffgraham) auf CodePen.

Schnellvorlauf ins Heute, und ich habe einen neuen Aufkleber im Umschlag erhalten, der ein frisches Design aufweist

Quelle: Los Angeles Magazine (source)

Ich habe etwas Zeit, also werde ich versuchen, diesen Aufkleber in CSS nachzubilden und meinen Gedankengang dabei darzulegen. Fühlen Sie sich frei, mitzumachen, wenn Sie möchten!

Zerlegung der Elemente

Jedes Mal, wenn ich ein Design irgendwelcher Art erhalte, stelle ich mir gerne vor, meine Augen hätten die Superkraft von Röntgenstrahlen und könnten durch das Design hindurchsehen, als wäre es ein Skelett. Das hilft mir, darüber nachzudenken, wie viele Elemente ich im HTML verwenden könnte.

OK, ich denke, ich werde mit so etwas beginnen:

<!-- Main Circle -->
<div class="sticker">
  <div class="sticker__top">
    <!-- Will use ::before and ::after to create halves -->
    <h1>I Voted</h1>
  </div>
  <div class="sticker__bottom">
    <!-- The list of languages -->
    <ul>
      <li>Item</li>
      <li>Item</li>
      <li>Item</li>
      <li>Item</li>
      <li>Item</li>
      <li>Item</li>
      <li>Item</li>
      <li>Item</li>
      <li>Item</li>
      <li>Item</li>
      <li>Item</li>
      <li>Item</li>
    </ul>
  </div>
</div>

Ich werde auch einige Basisstile auf dem <body> anwenden, damit ich direkt mit dem Rest des Aufklebers beginnen kann.

Siehe den Pen "I Voted" Sticker HTML von Geoff Graham (@geoffgraham) auf CodePen.

OK, bisher nichts Besonderes. Sieht wirklich nur aus wie eine unsortierte Liste mit einer Überschrift mit einem schrecklichen Kontrast zwischen Inhalt und Hintergrund.

Arbeiten am Haupt-Aufkleber-Container

Ich denke, ich werde den Container aufsetzen, der der Hauptkreis ist. Ich werde eine feste Breite und Höhe verwenden, dann border-radius verwenden, um ihn abzurunden und in die Form eines Kreises zu bringen.

Oh, und ich sollte mich um den dunklen Text kümmern und dabei auch einen Rahmen hinzufügen, damit ich sehe, was ich tue.

.sticker {
   border: 20px solid #fff;
   border-radius: 100%;
   color: #fff;
   height: 400px;
   width: 400px;
 }

Siehe den Pen "I Voted" Sticker HTML 2 von Geoff Graham (@geoffgraham) auf CodePen.

Die Ausrichtung ist komplett daneben. Das scheint ein guter Ort zu sein, um Flexbox einzubauen. Das wird es mir ermöglichen, unsere Elemente horizontal zu zentrieren. Ich denke, eine einspaltige Anordnung wird die vertikale Ausrichtung regeln.

.sticker {
  display: flex;
  flex-flow: column;
  align-items: center;
  border: 20px solid #fff;
  border-radius: 100%;
  color: #fff;
  height: 400px;
  width: 400px;
}

Ja, das hilft.

Siehe den Pen "I Voted" Sticker HTML 3 von Geoff Graham (@geoffgraham) auf CodePen.

Das Letzte, was ich jetzt mit dem Aufkleber machen möchte, ist, ihn in zwei Hälften zu teilen – eine obere und eine untere. OK, ja, ich habe dafür explizite Elemente im HTML (.sticker__top und .sticker__bottom). Ich könnte background-color für jedes Element verwenden, um die obere Hälfte blau und die untere Hälfte rot zu machen, aber ich mag die Idee, stattdessen einen linearen Farbverlauf mit einem harten Stopp auf halber Höhe zu verwenden.

.sticker {
  background-image:
    linear-gradient(
      to bottom,
       #080968,
       #080968 50%,
       #080968 50%,
       #F81616 50%
    );
  border: 20px solid #fff;
  border-radius: 100%;
  color: #fff;
  display: flex;
  flex-flow: column;
  align-items: center;
  height: 400px;
  width: 400px;
}

Hey, das sieht schon viel schärfer aus!

Siehe den Pen "I Voted" Sticker HTML 4 von Geoff Graham (@geoffgraham) auf CodePen.

Zeit, sich mit der oberen Hälfte zu beschäftigen

Die oberen und unteren Hälften nehmen jeweils 50% der Aufkleberhöhe ein, sodass die Selektoren kombiniert werden können, um beide auf einmal anzusprechen. Außerdem verwende ich Flexbox, sodass ich diese Elemente einfach flexen kann.

.sticker__top,
.sticker-bottom {
  flex: 0 50%;
}

Die obere Hälfte ist super seltsam. So wie ich es sehe, gibt es zwei Zeilen: eine, die die Sterne und Streifen enthält, und eine andere, die die Überschrift enthält. Ich werde wieder Flexbox verwenden, um dieses Layout zu zeichnen.

.sticker__top {
  display: flex;
  flex-flow: row wrap;
  position: relative;
}

Das wird im Moment nicht viel ändern, denn nun ja, ich habe noch *nichts* getan, um Elemente für die Sterne und Streifen im HTML zu definieren. Ich denke daran, die ::before und ::after Pseudo-Elemente auf .sticker__top zu verwenden, um diese zu erstellen. Auch hier können sie kombiniert werden, da sie einige gemeinsame Eigenschaften und Werte teilen.

.sticker__top::before,
.sticker__top::after {
  content: "";
  height: 45%; /* Had to play with this a bit */
  margin-top: 2em; /* Move away from the top edge of the sticker */
}

Ich werde schummeln und SVG für die Sterne verwenden. Ich meine, das ist vielleicht kein Schummeln, aber es fühlt sich irgendwie wie eine Abweichung von einem "reinen" CSS-Weg an. Egal.

Das gesagt, die Streifen können definitiv in CSS gemacht werden, wieder mit der gleichen linearen Farbverlauf-Hintergrundtechnik, die verwendet wird, um den Aufkleber in blaue und rote Hälften zu teilen.

.sticker__top::before {
  background-image: 
    url("/path/to/star/image.svg");
  background-size: 35px; /* Magic number, depends on the image used. */
}

.sticker__top::after {
  background-image:
    linear-gradient(
      to bottom,
          #F81616,
          #F81616 14%,
      transparent 14%,
      transparent 28%,
          #F81616 28%,
          #F81616 42%,
      transparent 42%,
      transparent 56%,
          #F81616 56%,
          #F81616 70%,
      transparent 70%,
      transparent 84%,
          #F81616 84%,
          #F81616 98%,
      transparent 100%
    );
}

Das ist cool, aber Mist, die Dinge sind durcheinander.

Siehe den Pen "I Voted" Sticker HTML 5 von Geoff Graham (@geoffgraham) auf CodePen.

Ich bin so dankbar, dass Flexbox eine order-Eigenschaft hat. Ich werde die Sterne, Streifen und die Überschrift mit 1, 2 und 3 nummerieren,

.sticker__top::before {
  /* Same as before... */
  order: 1;
}

.sticker__top::after {
  /* Same as before... */
  order: 2;
}

.sticker__top h1 {
  order: 3;
}

Wenn ich hier aufhöre, wäre die Form der Sterne und Streifen komplett daneben und die Schrift der Überschrift wäre schlampig.

border-radius ist immer noch ein guter Weg, um die Sterne und Streifen dem gleichen kreisförmigen Pfad wie dem Aufkleber folgen zu lassen. Das Problem ist, dass die Unterseiten eine flache Kante beibehalten müssen. Da border-radius eine Kurzschreibweise ist, werde ich border-top-left-radius auf die Sterne und border-top-right-radius auf die Streifen anwenden.

Es ist auch erwähnenswert, dass die Streifen etwas breiter sind als die Sterne. Vielleicht eine 55-45-Aufteilung? Ich weiß es nicht. Ich werde mich dafür entscheiden und auch relative Positionierung auf den Streifen verwenden, damit ich sie ein wenig nach rechts schieben kann, um Trennung zwischen ihnen und den Sternen hinzuzufügen.

.sticker__top::before {
  /* Same as before... */
  flex: 45%;
}
  
.sticker__top::after {
  /* Same as before... */
  flex: 55%;
  position: relative;
  left: 10px;
}

Die Sterne und Streifen *sollten* mit der Größe und Breite der Überschrift flexen. Ich musste mit der Schriftart, Schriftgröße, Buchstabenabstand und Texttransformation spielen, um etwas zu bekommen, das ziemlich gut aussieht. Falls Sie sich fragen, ich habe mich für Raleway als Schriftart entschieden. Es ist nicht präzise, aber nah genug... zumindest für mein untrainiertes typografisches Auge.

.sticker__top h1 {
  font-family: 'Raleway', sans-serif;
  font-size: 4em;
  letter-spacing: 3px;
  line-height: 0;
  text-transform: uppercase;
  order: 3;
}

Siehe den Pen "I Voted" Sticker HTML 6 von Geoff Graham (@geoffgraham) auf CodePen.

Okay, jetzt kriege ich die Krise wegen der unteren Hälfte. Muss ich angehen.

Die untere Hälfte gestalten

So viel wurde bereits getan. Das Element für die untere Hälfte ist bereits im HTML vorhanden und ist so dimensioniert und positioniert, wie es sein sollte. Ich denke, das Entfernen der Aufzählungspunkte der Listenelemente und das Entfernen des linken Abstands von der unsortierten Liste wird viel aufräumen.

.sticker__bottom ul {
  list-style: none;
  padding: 0;
  width: 100%; /* Gotta take up the all of the bottom half */
}

Aber das reicht nicht ganz. Ich möchte, dass diese Liste horizontal verläuft, Zeilen umbricht und die Listenelemente freien Platz einnehmen. Ja, das klingt wieder nach Flexbox.

.sticker__bottom ul {
  display: flex;
  flex-flow: row wrap;
  align-items: flex-start;
  justify-content: flex-start;
  /* same as before... */
}

.sticker__bottom li {
  flex: auto; /* Flex as much as you need, guys */
  margin: .75em; /* A liiiiitle breathing room between items */
}

Siehe den Pen "I Voted" Sticker HTML 7 von Geoff Graham (@geoffgraham) auf CodePen.

Jetzt muss ich ein paar Anpassungen an .sticker__bottom vornehmen. Insbesondere werde ich es etwas schmaler machen (80% der vollen Aufkleberbreite), um es vom Rand des Aufklebers wegzubekommen, und dann seine Kanten abrunden... obwohl es vielleicht keine abgerundeten Ecken braucht, da der Inhalt nicht überlaufen wird.

.sticker__bottom {
  border-bottom-right-radius: 100%;
  border-bottom-left-radius: 100%;
  width: 80%;
}

Und jetzt den Text zentrieren. Ich denke, das kann auf dem übergeordneten Element .sticker erfolgen, da technisch gesehen nichts auf dem Aufkleber linksbündig ist.

.sticker {
  /* same as before... */
  text-align: center;
}

Schließlich werde ich mein Bestes tun, um den Dummy-Inhalt durch die "I Voted"-Übersetzungen zu ersetzen. Lass mich das mal nachschlagen.

(Geht zu Google Translate.)

Meh, ich konnte nicht alles finden, was ich brauchte. Ich bin sicher, es liegt an meiner mangelnden Geduld, aber ich habe einige Alternativen verwendet

<ul>
  <li>Yo voté</li>
  <li>我投票</li>
  <li>나는 투표했다</li>
  <li>Bumoto ako</li>
  <li>Я проголосував</li>
  <li>मैने मतदान किया</li>
  <li>أنا صوتت</li>
  <li>Ik stemde</li>
  <li>Szavaztam</li>
  <li>ฉันโหวตแล้ว</li>
  <li>Anigu waxaan codsaday</li>
  <li>Tôi đã bầu chọn</li>
</ul>

Ich werde mit der Schriftgröße spielen müssen, um die gleiche Ausrichtung wie beim IRL-Aufkleber zu erzielen, der Reihen von: 4 Elementen, 3 Elementen, 3 Elementen, 1 Element, 1 Element hat.

Hier ist, wo ich gelandet bin:

.sticker__bottom ul {
  display: flex;
  flex-flow: row wrap;
  font-size: .75em;
  align-items: flex-start;
  justify-content: flex-start;
  list-style: none;
  padding: 0;
  width: 100%;
}

Um die letzten beiden Elemente von der gleichen Zeile zu bekommen, werde ich das vorletzte mit :last-child() hervorheben, damit beide immer zu 100% flexen.

.sticker__bottom li:nth-child(11) {
  flex: 100%;
}

Und schließlich werde ich den weißen Rand um den Aufkleber von weiß auf blau ändern. Das verleiht ihm den Pseudo-Randeffekt, den ich erzielen wollte.

Siehe den Pen "I Voted" Sticker HTML 8 von Geoff Graham (@geoffgraham) auf CodePen.

Fertig, bereit!

Ich nenne das mal gebacken. Ich weiß, ich weiß. Ich sollte Cross-Browser-Tests machen. Es wäre auch klug, elegante Fallbacks für ältere Browser zu finden, die Flexbox nicht unterstützen. Und etwas Responsivität wäre schön zu haben. Vielleicht möchte das jemand aufgreifen und teilen. 😉

Ist das der beste Weg, den Aufkleber zu machen? Wahrscheinlich nicht. Zum Beispiel wette ich, dass es einige interessante Dinge gibt, die mit clip-path statt der Art und Weise, wie ich mich mit Hintergrundverläufen herumgeschlagen habe, getan werden können. Und wenn ich es noch einmal machen müsste, würde ich vielleicht sogar in Erwägung ziehen, ein CSS Grid Layout für das Elternelement zu verwenden, denn es gibt eindeutig Möglichkeiten, in zwei Richtungen statt in einer zu arbeiten.

Aber das ist die Schönheit von CSS. Es gibt mehr als einen Weg, etwas zu erreichen.

Alles Gute zum Wahltag, Freunde. 🇺🇸