Das Lernjournal hat ein neues «Feature»

Veröffentlicht am 06. November 2019
Lesezeit: ca. 3 Minuten
Thumbnail: Das Lernjournal hat ein neues «Feature»

Wie die Lightbox-Funktion dieser Site entstanden ist. Ein kurzes Tutorial.

Wie ich in meinem letzten Post zum Lernjournal am Ende angemerkt habe, war das Hinzufügen eines Lightbox-Features einer der nächsten Schritte, den ich für diese Website in Angriff nehmen wollte. Ursprünglich habe ich gehofft, dass Gridsome diese Funktion irgendeinmal nativ mitliefert. Dies ist aber mit den letzten Releases nicht geschehen, also habe ich mich selbst nach einer Alternative umgesehen. In diesem kurzen Tutorial möchte ich zeigen, wie ich konkret vorgegangen bin.

Recherche

Nach einer kurzen Google-Suche, bin ich auf Github auf dieses Gridsome Starter Template gestossen (das übrigens einen ziemlich guten Startpunkt für zukünftige Projekte sein könnte). Es kommt mit einigen nützlichen Features, am meisten interessiert hat mich aber natürlich die Lightbox. Diese ist im Stil der Publishing-Platform «Medium» gehalten, welche ich sowieso vom Design her recht ansprechend finde. Also habe ich mir das Repository des Templates heruntergeladen und mir den Code etwas genauer angeschaut. So fand ich dann auch den Namen des für die Lightbox verantwortlichen Packages heraus: Medium Zoom. Zu den Eigenschaften des Plugins zählen (von der Github Seite des Projekts übernommen):

  • 📱 Responsive — scale on mobile and desktop
  • 🚀 Performant and lightweight — should be able to reach 60 fps
  • ⚡️ High definition support — load the HD version of your image on zoom
  • 🔎 Flexibility — apply the zoom to a selection of images
  • 🖱 Mouse, keyboard and gesture friendly — click anywhere, press a key or scroll away to close the zoom
  • 🎂 Event handling — trigger events when the zoom enters a new state
  • 📦 Customization — set your own margin, background and scroll offset
  • 🔧 Pluggable — add your own features to the zoom
  • 💎 Custom templates — extend the default look to match the UI of your app

Alles in allem entsprach diese Lösung also ziemlich meinen Vorstellungen.

Umsetzung

Für die Implementierung der Funktion, geht man nun wie folgt vor 👇

Als erstes muss das Package via npm installiert werden. Das geschieht über diesen Befehl:

npm install medium-zoom

Damit ist das Plugin im Projekt vorhanden und kann von nun an aufgerufen werden.

Jetzt muss das gewünschte Gridsome-Template noch so angepasst werden, dass sich die Lightbox auch wirklich öffnet, wenn auf ein Bild geklickt wird. In meinem Fall heisst das betroffene Template Post.vue. Dort ergänzt man dann im JavaScript-Teil des Files folgenden Code:

mounted() {
  import('medium-zoom').then(mediumZoom => {
    mediumZoom.default('.markdown p > img')
  })
}

Die mounted-Funktion stammt von Vue.js, dem Framework hinter Gridsome. Sie wird aufgerufen, nachdem das Template initialisiert wurde und ist somit ideal um das Lightbox-Package zu importieren. Dies geschieht dann auch schon auf der nächsten Zeile. Anschliessend wird noch angegeben, welche Elemente mit der Lightbox versehen werden sollen. Das sind in meinem Fall alle Bilder innerhalb der .markdown-Klasse. Damit ist die Basis dieser Funktion auch schon konfiguriert und alles sollte bereits funktionieren.

Eigene Anpassungen

Da das Plugin selbst ohne grosse Anpassungen schon sehr gut funktionierte, konnte ich diesen Teil eigentlich ziemlich kurz halten. Die einzige wirkliche Veränderung musste ich im CSS der Site vornehmen und die sah lediglich so aus:

/* Fix z-index of lightbox */
.medium-zoom-image--opened,
.medium-zoom-overlay {
  @apply z-40;
}

Damit wird der z-Index der Bildes, sowie der des farbigen Hintergrunds, auf 40 festgelegt. Dadurch verschwinden beide Elemente nicht hinter der fixen Navigation, die einen Wert von 30 besitzt. Wer sich übrigens wundert, woher die @apply-Funktion kommt: Die stammt von Tailwind CSS, dem CSS Framework, das ich für diese Seite nutze. Eventuell schreibe ich darüber bei Gelegenheit auch noch einen Artikel, da es einige Eigenheiten mit sich bringt, aber äusserst praktisch ist.

Endresultat

Zum Ende dieses Posts noch das obligatorische Bild zum selber testen 👇

Ein Demo-Bild aus meinen Ferien 🌅