Hiding Text - Teil 1

Hiding Text - Teil 1

Willkommen auf unserer einzigartigen Reise durch Innovation und Kreativität! Tauchen Sie ein und entdecken Sie, was hinter den Kulissen verborgen liegt. Doch Vorsicht: Nicht alles ist auf den ersten Blick sichtbar. Verborgene Schätze warten darauf, von Ihnen entdeckt zu werden. Sind Sie bereit, die Geheimnisse zu enthüllen?

EINLEITUNG

Einen modernen Onepager von Grund auf entwickeln

In diesem Tutorial entwickeln wir Schritt für Schritt einen modernen Onepager mit HTML und CSS. Dabei entsteht nicht einfach nur eine statische Seite: Wir kombinieren ein bildschirmfüllendes Hintergrundvideo, große Typografie, Parallax-Effekte, animierte Hover-Bereiche, eine feste Navigation und einen individuellen Footer.

Wir beginnen bewusst mit einer einfachen Projektstruktur und bauen den Onepager Abschnitt für Abschnitt auf. So kannst du jeden Schritt nachvollziehen und das Design später problemlos an dein eigenes Projekt anpassen.
Im ersten Teil kümmern wir uns um das Grundgerüst und die wichtigsten Bereiche der Seite. Die weiterführenden Animationen und Interaktionen folgen anschließend.

Vorbereitung

Bilder, Video und Projektstruktur

Für unseren Onepager benötigen wir zunächst einige visuelle Elemente: zwei Bilder, ein kurzes Video und ein Logo. Passendes Material findest du beispielsweise bei pixabay  oder anderen Plattformen mit frei nutzbaren Medien.

Für dieses Tutorial verwende ich folgende Dateien:

tropfen.mp4 7.21 MB


Anschließend legen wir eine übersichtliche Projektstruktur an:
$ mkdir OnePager
$ cd OnePager
$ mkdir assets
$ cd assets
$ mkdir images
$ mkdir videos
Bilder und Logo kommen in assets/images, das Video in assets/videos.
Zusätzlich erstellen wir im Hauptordner die index.html und innerhalb von assets unsere styles.css.

2. GRUNDGERÜST

Die Basis unseres Onepagers

Jetzt erstellen wir das HTML-Grundgerüst unseres Onepagers. Die index.html bildet dabei die zentrale Datei unserer Seite. Im <head> hinterlegen wir die wichtigsten Meta-Angaben und binden außerdem unsere zuvor angelegte styles.css ein.
// index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>One Pager</title>
  <link rel="stylesheet" href="assets/styles.css" />
</head>
<body>
  
</body>
</html>
Damit steht das Grundgerüst. Über assets/styles.css werden später sämtliche Styles unseres Onepagers geladen. Alles, was auf der eigentlichen Seite sichtbar sein soll, fügen wir im weiteren Verlauf innerhalb des <body> ein.

3. HEADER & NAVIGATION

Logo und Navigation hinzufügen

Als ersten sichtbaren Bestandteil unseres Onepagers erstellen wir den Header. Er enthält links unser Logo und rechts die Navigation zu den drei Hauptbereichen About, Work und Contact.

Die Links verweisen bereits auf die entsprechenden IDs der späteren Bereiche. Dadurch können wir innerhalb derselben Seite direkt zu den einzelnen Abschnitten navigieren.

Zusätzlich erhalten die Links mit data-scroll und data-hover bereits Attribute, die wir später für unsere Effekte verwenden können.

// index.html
<header>
  <div class="logo magnetic">
    <img src="assets/images/logo-white.webp" alt="b4um" />
  </div>
  <nav>
    <div class="hidden-link">
      <a
        class="nav-link hidden-link"
        href="#About"
        data-scroll="About"
        data-hover="About"
      ><span>About</span></a>
      <a
        class="nav-link hidden-link"
        href="#Work"
        data-scroll="Work"
        data-hover="Work"
      ><span>Work</span></a>
      <a
        class="nav-link hidden-link"
        href="#Contact"
        data-scroll="Contact"
        data-hover="Contact"
      ><span>Contact</span></a>
    </div>
  </nav>
</header>
Das Logo liegt in assets/images und wird über logo-white.webp eingebunden. Die Navigation selbst funktioniert bereits über normale Ankerlinks: href="#About" führt später beispielsweise zum Element mit id="About".

Optisch ist der Header allerdings noch nicht fertig. Bevor wir ihn gestalten, legen wir zunächst einige grundlegende CSS-Regeln fest, die wir im gesamten Onepager immer wieder benötigen werden.

4. BASIS-STYLES

Die Grundlage für das Design schaffen

Bevor wir unseren Header gestalten, legen wir einige grundlegende CSS-Regeln fest. Sie bestimmen unter anderem Hintergrundfarbe, Schrift, Abstände und das Verhalten unseres Layouts.

Außerdem erstellen wir einige kleine Hilfsklassen wie .row, .align-items-center und .min-vh-100. Diese können wir später in mehreren Bereichen wiederverwenden, ohne dieselben CSS-Eigenschaften jedes Mal neu schreiben zu müssen.

In unserer assets/styles.css beginnen wir mit:

// assets/styles.css

:root {
  --bg: #272c3b;
  --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif,
    "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}

*,
::after,
::before {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

html,
body {
  max-width: 100vw;
  overflow-x: hidden;
  margin: 0;
  background-color: var(--bg);
  color: #b7ab98;
}

body {
  margin-left: 1rem;
  margin-right: 1rem;
  font-family: var(--bs-font-sans-serif);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}

@media (min-width: 768px) {
  body {
    margin: 0;
  }
}

a {
  color: #b7ab98;
  text-decoration: none;
}

a:hover {
  color: #b7ab98;
}

.bg {
  background-color: var(--bg) !important;
  position: relative;
  padding-bottom: 5rem;
}

p {
  text-transform: uppercase;
  font-weight: bold;
}

.align-items-center {
  align-items: center !important;
}

.justify-content-center {
  justify-content: center !important;
}

.min-vh-100 {
  min-height: 100vh !important;
}

.justify-content-start {
  justify-content: flex-start !important;
}

.row {
  --bs-gutter-x: 1.5rem;
  --bs-gutter-y: 0;
  display: flex;
  flex-wrap: wrap;
  margin-top: calc(var(--bs-gutter-y) * -1);
  margin-right: calc(var(--bs-gutter-x) * -0.5);
  margin-left: calc(var(--bs-gutter-x) * -0.5);
}

.h1,
.h2,
.h3,
.h4,
.h5,
.h6,
h1,
h2,
h3,
h4,
h5,
h6 {
  margin-top: 0;
  margin-bottom: 0.5rem;
  font-weight: 500;
  line-height: 1.2;
}
Mit :root legen wir zunächst globale CSS-Variablen fest. Unsere Hintergrundfarbe ist damit beispielsweise über var(--bg) im gesamten Stylesheet verfügbar.

Anschließend vereinheitlichen wir mit box-sizing: border-box die Größenberechnung aller Elemente und aktivieren über scroll-behavior: smooth das weiche Scrollen zu unseren Ankerpunkten.

Für body, Links und Überschriften definieren wir grundlegende Farben, Schrift- und Abstandseinstellungen. Die Media Query ab 768px passt dabei die seitlichen Abstände für größere Displays an.

Die Klassen .align-items-center, .justify-content-center, .justify-content-start und .min-vh-100 sind wiederverwendbare Hilfsklassen für unser späteres Flexbox-Layout. .row bildet dafür einen flexiblen Zeilen-Container mit definierten Abständen.

5. HEADER-STYLING

Navigation fixieren und den Hover-Effekt gestalten

Unser Header ist bereits im HTML vorhanden, besitzt aber noch kein eigenes Erscheinungsbild. Jetzt positionieren wir ihn dauerhaft am oberen Rand des Browserfensters und gestalten Logo und Navigation.

Die Navigation erhält außerdem ihren charakteristischen Hover-Effekt: Beim Überfahren eines Links bewegt sich der ursprüngliche Text nach oben und der über data-hover hinterlegte Text erscheint an seiner Stelle.

Füge Folgendes unter deinen bisherigen Code in assets/styles.css ein:
// assets/styles.css

header {
  background-color: transparent;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  color: #b7ab98;
  z-index: 100;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  height: 1rem;
}
header .logo {
  padding: 1rem;
  color: #b7ab98;
}
header .hidden-content {
  width: 10rem;
}
header .logo img {
  height: 3rem;
  width: 3rem;
}
header nav div {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1rem;
  right: 0;
  justify-content: end;
  text-align:// assets/styles.css

header {
  background-color: transparent;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  color: #b7ab98;
  z-index: 100;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  height: 1rem;
}

header .logo {
  padding: 1rem;
  color: #b7ab98;
}

header .hidden-content {
  width: 10rem;
}

header .logo img {
  height: 3rem;
  width: 3rem;
}

header nav div {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1rem;
  right: 0;
  justify-content: end;
  text-align: end;
  align-items: end;
}

header nav a.nav-link,
header nav a {
  color: rgb(183, 171, 152, 0.5);
  text-decoration: none;
}

header nav a.nav-link,
header nav a {
  position: relative;
  overflow: hidden;
  display: block;
  text-align: center;
  -webkit-box-flex: 1;
  -webkit-flex-grow: 1;
  -ms-flex-positive: 1;
  flex-grow: 1;
  -webkit-animation-duration: 1s;
  animation-duration: 1s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
  padding: 0;
}

header nav a span {
  display: block;
  -webkit-transition: -webkit-transform 500ms
    cubic-bezier(0.68, -0.55, 0.265, 1.55);
  transition: -webkit-transform 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
  transition: transform 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
  transition: transform 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55),
    -webkit-transform 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

header nav a:after {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  content: attr(data-hover);
  display: inline;
  text-align: center;
  -webkit-transition: top 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
  transition: top 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

header nav a.nav-link:hover,
header nav a.is-active,
header nav a:hover {
  color: #b7ab98;
  font-weight: bold;
}

header nav a:hover span {
  color: #b7ab98;
  font-weight: bold;
  -webkit-transform: translateY(-100%);
  transform: translateY(-100%);
}

header nav a:hover:after {
  top: 0;
}

header nav a:active {
  -webkit-animation-name: rubberBand;
  animation-name: rubberBand;
}

@media (min-width: 1248px) {
  header .logo {
    padding: 4rem;
  }

  header nav div {
    padding: 4rem;
  }
}
Mit position: fixed bleibt der Header auch beim Scrollen am oberen Bildschirmrand sichtbar. z-index: 100 sorgt dafür, dass Logo und Navigation über den später folgenden Seiteninhalten liegen.

Logo und Navigation werden mit Flexbox an den gegenüberliegenden Seiten des Headers positioniert. Ab einer Bildschirmbreite von 1248px erhöhen wir über die Media Query die Abstände und geben dem Layout auf großen Displays mehr Raum.

Für den Hover-Effekt nutzen wir das Pseudo-Element ::after. Dessen Inhalt stammt direkt aus dem jeweiligen data-hover-Attribut unseres HTML-Links. Standardmäßig befindet sich dieser Text unterhalb des sichtbaren Bereichs des Links.

Beim Hover wird der normale Text mit translateY(-100%) nach oben geschoben, während das Pseudo-Element gleichzeitig auf top: 0 fährt. Die cubic-bezier()-Kurve sorgt dabei für die etwas dynamischere Bewegung.

Damit steht unsere feste Navigation inklusive Hover-Effekt. Im nächsten Schritt bauen wir den eigentlichen Hero-Bereich mit unserem Hintergrundvideo auf.

1.mp4 107 KB

6. HERO

Den Hero-Bereich mit Hintergrundvideo aufbauen

Nach dem Header erstellen wir den ersten großen Inhaltsbereich unseres Onepagers. Der Hero nimmt die gesamte Höhe des Browserfensters ein und kombiniert unser vorbereitetes Video tropfen.mp4 mit einer großformatigen Typografie.

Der Hero kommt in der index.html direkt nach dem schließenden </header>.

Füge deinen vorhandenen Code ein:
// index.html

<main class="bg">
  <div class="content">
    <!-- -------------------------------- hero --------------------------------- -->
    <div
      id="About"
      class="row justify-content-center align-items-center min-vh-100"
    >
      <div class="bg-video">
        <div class="bg-parallax video">
          <video
            data-parallax="0.5"
            id="bg-video"
            class="parallax-img"
            autoplay=""
            muted=""
            playsinline=""
            loop=""
            preload="auto"
            src="assets/videos/tropfen.mp4"
          ></video>
          <div class="parallax-overlay"></div>
        </div>
      </div>

      <div class="display">
        <p class="about_content_label text-align-center text-color">b4um</p>
        <div class="text-center">Making</div>
        <div class="text-center"><strong>good</strong></div>
        <div class="text-center"><strong>shit</strong></div>
        <div class="text-center">since</div>
        <div class="text-center">2023</div>
      </div>
    </div>
    <!-- ------------------------------ hero ende ------------------------------ -->
  </div>
</main>

Mit min-vh-100 erhält unser Hero eine Mindesthöhe von 100vh und nimmt damit mindestens die vollständige Höhe des Browserfensters ein. Die bereits angelegten Flexbox-Hilfsklassen zentrieren den Inhalt horizontal und vertikal.

Innerhalb von .bg-video binden wir unser zuvor vorbereitetes tropfen.mp4 ein. autoplay, muted und loop sorgen dafür, dass das Video automatisch und ohne Ton in einer Schleife abgespielt wird. playsinline verhindert insbesondere auf mobilen Geräten, dass das Video automatisch im Vollbildmodus geöffnet wird.

Mit .parallax-overlay legen wir zusätzlich eine Ebene über das Video. Diese benötigen wir gleich, um das Hintergrundvideo abzudunkeln und den darüberliegenden Text besser lesbar zu machen.

data-parallax="0.5" und die Klasse .parallax-img bereiten das Video außerdem bereits für den späteren Parallax-Effekt vor.

Momentan sieht der Hero noch nicht wie gewünscht aus. Im nächsten Schritt positionieren wir das Video als vollflächigen Hintergrund und gestalten das Overlay.

7. HINTERGRUNDVIDEO & PARALLAX-BASIS

Das Video vollflächig hinter dem Hero positionieren

Unser Video ist bereits im HTML eingebunden. Jetzt sorgen wir dafür, dass es den gesamten Hero-Bereich ausfüllt und tatsächlich als Hintergrund funktioniert.

Gleichzeitig legen wir die Grundlage für die späteren Parallax-Bereiche. Deshalb berücksichtigen wir hier nicht nur .bg-video, sondern auch .bg-img. Dieselben Regeln können wir später für unsere Hintergrundbilder wiederverwenden.

Füge Folgendes unter deinen bisherigen Code in assets/styles.css ein:
// assets/styles.css

.bg-img,
.bg-video {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  margin: auto;
  right: 0;
  height: 100vh;
}

.bg-img .bg-parallax,
.bg-video .bg-parallax {
  display: block;
  -webkit-transform: translate3d(0, var(--offset-parallax), 0) rotate(0);
  transform: translate3d(0, var(--offset-parallax), 0) rotate(0);
  will-change: transform;
  justify-content: center;
  align-items: center;
}

.bg-img .img img.parallax-img,
.bg-video .video video {
  height: 100vh;
  object-fit: cover;
  width: 100vw;
  position: relative;
}

.bg-img .img .parallax-overlay {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: var(--bg);
  opacity: 0.5;
  z-index: 100;
}

#Contact,
#Work,
#About {
  position: relative;
  overflow: hidden;
}

.parallax-img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: auto;
  z-index: -1;
  transform: translateZ(0);
}

.parallax-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 1;
}

@media (min-width: 1248px) {
  .bg-img,
  .bg-video {
    max-height: 100vh;
  }

  .bg-img .img img.parallax-img,
  .bg-video .video video {
    max-height: 100vh;
  }
}

.bg-video und .bg-img werden absolut positioniert und auf die vollständige Höhe des Browserfensters gesetzt. Dadurch können Video und spätere Hintergrundbilder unabhängig vom eigentlichen Inhalt hinter unseren Abschnitten liegen.

Mit width: 100vw, height: 100vh und object-fit: cover füllt das Video den verfügbaren Bereich vollständig aus. Dabei bleiben seine Proportionen erhalten; überstehende Bereiche werden bei Bedarf abgeschnitten.

Die Klasse .parallax-overlay erzeugt eine halbtransparente schwarze Ebene über dem Hintergrund. Dadurch wird das Video abgedunkelt und der darüberliegende Inhalt bleibt besser lesbar.

Die Regeln für #About, #Work und #Contact sorgen mit overflow: hidden dafür, dass Inhalte der Hintergrund- und Parallax-Ebenen nicht aus ihrem jeweiligen Abschnitt herausragen.

Gleichzeitig bereiten .bg-parallax und .parallax-img bereits die später folgende Bewegung der Hintergründe vor. Deshalb verwenden wir diese Klassen schon jetzt, auch wenn der eigentliche Parallax-Effekt erst später vollständig umgesetzt wird.

Unser Hintergrundvideo sitzt damit an der richtigen Stelle. Allerdings fehlt unserem Hero-Text noch seine eigentliche Gestaltung. Genau darum kümmern wir uns als Nächstes.

8. HERO-TYPOGRAFIE

Die große Typografie über dem Video gestalten

Das Hintergrundvideo funktioniert bereits. Jetzt geben wir dem darüberliegenden Text sein eigentliches Erscheinungsbild. Dabei unterscheiden wir zwischen dem kleinen Label b4um, der großen Hero-Typografie und den orange hervorgehobenen Wörtern.

Füge den folgenden vorhandenen Code unter deinen bisherigen Code in assets/styles.css ein:
// assets/styles.css

.about_content_label {
  text-transform: uppercase;
  font-size: 0.875rem;
  line-height: 180%;
  letter-spacing: 0.5em;
  display: block;
  font-family: Avant Garde, sans-serif;
  font-style: normal;
  font-weight: 700;
  z-index: 0;
  position: relative;
  padding-left: 1rem;
  max-width: 1248px;
  margin: auto;
  margin-bottom: 1.875rem;
  text-align: left;
}

.text-align-center {
  text-align: center;
}

.text-color {
  color: rgb(183, 171, 152, 1);
}

.text-center {
  font-size: 4rem;
  font-weight: 600;
  line-height: 100%;
  width: 100%;
  color: rgb(183, 171, 152, 1);
  background: linear-gradient(to right, #b6b6b6, #b6b6b6) no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  background-size: 0%;
  transition: background-size cubic-bezier(0.1, 0.5, 0.5, 1) 0.5s;
  display: block;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  position: relative;
  max-width: 1248px;
  margin: auto;
  text-align: center;
  text-transform: uppercase;
}

strong {
  color: #eb5939;
}

@media (min-width: 1248px) {
  .about_content_label {
    padding-left: 0;
  }

  .text-center {
    font-size: 5vw;
  }
}

.about_content_label gestaltet das kleine Label oberhalb unseres Hero-Textes. Durch Großbuchstaben und einen großen Zeichenabstand hebt es sich deutlich von der restlichen Typografie ab.

Die eigentliche Hero-Typografie entsteht mit .text-center. Auf kleineren Displays verwenden wir eine feste Schriftgröße von 4rem. Ab einer Bildschirmbreite von 1248px wechseln wir auf 5vw, sodass sich die große Schrift proportional an die Breite des Browserfensters anpasst.

Über strong können einzelne Wörter innerhalb der großen Typografie hervorgehoben werden. In unserem Hero erhalten good und shit dadurch die Akzentfarbe #eb5939.

Die Eigenschaften background-clip, background-size und transition bereiten außerdem bereits einen späteren Texteffekt vor. Auch diesen Code behalten wir deshalb schon jetzt bei.

1.webp 109 KB


Damit ist unser Hero mit Hintergrundvideo und großer Typografie fertig aufgebaut. Im nächsten Abschnitt verlassen wir den bildschirmfüllenden Einstieg und erstellen den ersten inhaltlichen Bereich unseres Onepagers.

9. ABOUT ME

Den ersten Inhaltsbereich erstellen

Nach dem Hero folgt ein ruhigerer, rein typografischer Abschnitt. Auch dieser Bereich nimmt mindestens die gesamte Höhe des Browserfensters ein und wird horizontal sowie vertikal zentriert.

Die einzelnen Textzeilen bekommen eigene Container. Das benötigen wir später für die Gestaltung und weitere Effekte
.
Füge den folgenden Code in der index.html innerhalb von <div class="content"> direkt nach dem Hero-Bereichein:
// index.html

<div class="row justify-content-center align-items-center min-vh-100">
  <div class="display">
    <p class="about_content_label text-color">About me</p>
    <div class="text no-padding no-border text-align-left text-row">
      <span
        >Ich bin ein <strong>selektiv</strong>
        <strong>qualifizierter</strong> Produkt</span
      >
    </div>
    <div class="text no-padding no-border text-align-left text-row">
      <span>Designer mit starkem Fokus auf</span>
    </div>
    <div class="text no-padding no-border text-align-left text-row">
      <span>der Erstellung von hochwertigen &amp;</span>
    </div>
    <div class="text no-padding no-border text-align-left text-row">
      <span>wirkungsvollen digitalen Erlebnissen.</span>
    </div>
  </div>
</div>

Für den Aufbau verwenden wir erneut unsere bereits angelegten Hilfsklassen. min-vh-100 gibt dem Bereich mindestens die Höhe des Browserfensters, während justify-content-center und align-items-center den Inhalt zentrieren.

Jede Textzeile erhält die Klasse .text. Mit zusätzlichen Hilfsklassen können wir bei Bedarf Innenabstände und Rahmen entfernen oder die Ausrichtung verändern. Die bereits bekannte strong-Formatierung hebt einzelne Wörter wieder in unserer Akzentfarbe hervor.


Den About-Text gestalten

Jetzt ergänzen wir die noch fehlenden Klassen in unserer assets/styles.css:
// assets/styles.css

.text {
  font-size: 2rem;
  font-weight: 700;
  line-height: 100%;
  padding-left: 1rem !important;
  padding-right: 1rem !important;
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
  width: 100%;
  color: rgb(183, 171, 152, 0.2) !important;
  background: linear-gradient(to right, #b6b6b6, #b6b6b6) no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  background-size: 0%;
  transition: background-size cubic-bezier(0.1, 0.5, 0.5, 1) 0.5s;
  border-bottom: 1px solid #2f2b28;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  position: relative;
  margin: auto;
  text-align: left;
  text-shadow: 1px 1px 0 rgba(var(--bg), 0.9);
}

.no-padding {
  padding: 0;
}

.no-border {
  border: none;
}

.text-align-left {
  text-align: left;
  justify-content: start;
}

.text-row {
  width: 100%;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  margin: auto;
}

@media (min-width: 1248px) {
  .about_content_label {
    padding-left: 0;
  }

  .text-center {
    font-size: 4vw;
  }

  .text {
    font-size: 4vw;
    padding-left: 0rem !important;
    padding-right: 0rem !important;
  }

  .text-row {
    width: 100%;
    max-width: 1248px;
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    margin: auto;
  }
}

.text bildet ab jetzt eine zentrale Klasse für die großen Textzeilen unseres Onepagers. Neben Schriftgröße und Gewicht enthält sie bereits Eigenschaften wie background-clip, background-size und transition, die wir für weitere visuelle Effekte vorbereiten.

Der Text wird zunächst mit einer sehr transparenten Farbe dargestellt. Das ist an dieser Stelle beabsichtigt und wird später im Abschnitt zu den globalen Einstellungen noch einmal wichtig.

Mit .no-padding, .no-border und .text-align-left können wir die Grundeinstellungen von .text gezielt überschreiben. .text-row begrenzt unseren Inhalt auf großen Displays später auf maximal 1248px.

Ab 1248px verwenden wir für .text eine Schriftgröße von 4vw. Dadurch wächst die Typografie mit der Breite des Browserfensters und erhält auf großen Displays die gewünschte Wirkung.


2.webp 51.7 KB


Unser About-Bereich steht. Als Nächstes verwenden wir dieselbe typografische Grundlage für eine deutlich interaktivere Variante: Textzeilen, deren zusätzliche Inhalte erst beim Hover sichtbar werden.

10. INTERAKTIVE HOVER-TEXTE

Zusätzliche Inhalte beim Hover sichtbar machen

Jetzt bekommt unser Onepager eine erste größere Interaktion. Die einzelnen Zeilen zeigen zunächst nur die jeweilige Leistung. Sobald wir mit der Maus über einen Eintrag fahren, wird eine farbige Fläche eingeblendet, auf der zusätzliche Informationen erscheinen.

Dafür benötigen wir kein JavaScript. Der Effekt wird vollständig mit CSS und clip-path umgesetzt.

Füge den folgenden Code in der index.html direkt nach dem About-Me-Bereich ein:
// index.html

<div class="row justify-content-center align-items-center min-vh-100">
  <div class="display-row width-100">
    <p class="about_content_label text-color">What i do</p>

    <div class="text uppercase hidden-link">
      <div class="text-row">3D</div>
      <div class="span">
        <div class="text-row">
          <div class="big">3D</div>
          <div class="smal">
            Ich kann alles produzieren, was mein 16-Zoll-Laptop rendern
            kann.
          </div>
        </div>
      </div>
    </div>

    <div class="text uppercase hidden-link">
      <div class="text-row">Visuell</div>
      <div class="span">
        <div class="text-row">
          <div class="big">Visuell</div>
          <div class="smal">
            Ich suche im Internet nach visuellen Referenzen und
            kombiniere sie dann, um meine eigenen Arbeiten zu erstellen.
          </div>
        </div>
      </div>
    </div>

    <div class="text uppercase hidden-link">
      <div class="text-row">Bewegung</div>
      <div class="span">
        <div class="text-row">
          <div class="big">Bewegung</div>
          <div class="smal">
            Ich verwende ausgefallene Bewegungen, die mein Design
            interessanter erscheinen lassen, als es tatsächlich ist.
          </div>
        </div>
      </div>
    </div>

    <div class="text uppercase hidden-link">
      <div class="text-row">Produkt</div>
      <div class="span">
        <div class="text-row">
          <div class="big">Produkt</div>
          <div class="smal">
            Ich nutze gängige Design-Best Practices, teste und
            überarbeite sie, bis es funktioniert (hoffentlich).
          </div>
        </div>
      </div>
    </div>

    <div class="text uppercase hidden-link">
      <div class="text-row">Tutorial</div>
      <div class="span">
        <div class="text-row">
          <div class="big">Tutorial</div>
          <div class="smal">
            Ich dachte, ich würde Millionen von Dollar mit YouTube
            verdienen, aber das habe ich nicht.
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Jeder Eintrag besteht aus zwei Ebenen. Die erste .text-row enthält den zunächst sichtbaren Titel. Direkt danach folgt mit .span eine zweite Ebene mit dem zusätzlichen Inhalt.

Diese zweite Ebene wird nicht aus dem HTML entfernt oder ausgeblendet. Stattdessen verwenden wir gleich clip-path, um sie zunächst auf eine schmale Linie zusammenzuschneiden. Beim Hover öffnen wir diese Fläche wieder auf ihre vollständige Größe.

Den Hover-Effekt mit CSS erstellen

Jetzt kommt dein vollständiger zugehöriger CSS-Code:
// assets/styles.css

.row > * {
  width: auto !important;
}

.width-100 {
  width: 100% !important;
}

.uppercase {
  text-transform: uppercase;
}

.span {
  position: absolute;
  width: 100%;
  min-height: 100%;
  background-color: #eb5939;
  color: #0d0d0d;
  clip-path: polygon(0 50%, 100% 50%, 100% 50%, 0 50%);
  transform-origin: center;
  transition: all cubic-bezier(0.1, 0.5, 0.5, 1) 0.4s;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  /* max-width: 1248px; */
  margin: auto;
  text-align: left;
}

.text-row:hover .span,
.text:hover > .span {
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
}

.big {
  font-size: 1.5rem;
  line-height: 100%;
  text-transform: uppercase;
  padding-left: 1rem;
}

.smal {
  font-size: 1rem;
  padding-right: 2rem;
  letter-spacing: 0em;
  width: 60vw;
  height: auto;
  line-height: 1.2rem;
  text-transform: none;
}

.h3 {
  margin-top: -12px !important;
  font-size: 1.5rem !important;
}

.text div.h3 {
  width: 5rem;
  line-height: 1rem;
  margin-top: -26px !important;
}

@media (min-width: 1248px) {
  .big {
    font-size: 4vw;
    padding-left: 0rem;
  }

  .smal {
    width: 30vw;
  }

  .h3 {
    margin-top: -12px !important;
    font-size: 3vw !important;
  }

  .text div.h3 {
    width: 15rem;
    margin-top: -26px !important;
  }
}

Der entscheidende Teil des Effekts steckt in .span. Die orangefarbene Ebene liegt absolut über der jeweiligen Textzeile. Mit

clip-path: polygon(0 50%, 100% 50%, 100% 50%, 0 50%)

wird diese Fläche zunächst auf die horizontale Mitte zusammengeschnitten.

Sobald sich der Mauszeiger über dem Eintrag befindet, ändern wir den clip-path auf die vollständige Fläche:

polygon(0 0, 100% 0, 100% 100%, 0% 100%)

Durch die definierte transition geschieht dieser Wechsel nicht schlagartig, sondern als Animation. .big formatiert dabei die große Bezeichnung auf der linken Seite, während .smal den erklärenden Text auf der rechten Seite gestaltet.

Die Media Query passt diese beiden Texte anschließend für große Displays an.


2.mp4 2.78 MB


Damit haben wir unsere erste rein mit CSS erzeugte Interaktion fertig. Diesen Hover-Effekt werden wir später noch einmal wiederverwenden. Als Nächstes bauen wir den Work-Bereich auf und kombinieren unsere Typografie mit einem großflächigen Hintergrundbild.

11. WORK & EXPERIENCE

Großflächiges Hintergrundbild mit unserer Typografie kombinieren

Nach den textbasierten Bereichen bringen wir wieder mehr visuelle Tiefe in den Onepager. Der Work-Bereich erhält ein bildschirmfüllendes Hintergrundbild, über dem wir unseren Experience-Text platzieren.

Dabei können wir die bereits für den Hero vorbereiteten Klassen .bg-img, .bg-parallax, .parallax-img und .parallax-overlay wiederverwenden. Statt eines Videos dient diesmal unser Bild work.webp als Hintergrund.

Füge diesen Code in der index.html direkt nach dem vorherigen Bereich ein:
// index.html

<div
  id="Work"
  class="row justify-content-center align-items-center min-vh-100"
>
  <div class="bg-img">
    <div class="bg-parallax img">
      <img class="parallax-img" src="assets/images/work.webp" />
      <div class="parallax-overlay"></div>
    </div>
  </div>

  <div class="display text-parallax">
    <p class="about_content_label text-color">Experience</p>

    <div class="text no-padding no-border text-align-left text-row">
      <span>
        Über
        <strong>ein Jahrzehnt</strong>
        an Erfahrung</span
      >
    </div>

    <div class="text no-padding no-border text-align-left text-row">
      in interaktives Design und
    </div>

    <div class="text no-padding no-border text-align-left text-row">
      Zusammenarbeit mit einigen der talentiertesten Personen in der
      Branche
    </div>
  </div>
</div>

Mit id="Work" erhält dieser Abschnitt gleichzeitig das Ziel für den bereits im Header angelegten Link href="#Work".
Der Aufbau des Hintergrundes entspricht weitgehend unserem Hero. .bg-img bildet die Hintergrundebene, während .parallax-img unser Bild enthält. 

Das darüberliegende .parallax-overlay dunkelt das Bild ab, damit die große Typografie gut lesbar bleibt.

Für den Text verwenden wir erneut unsere bereits erstellten Klassen .text, .text-row, .no-padding und .no-border. Dadurch müssen wir die grundlegende Typografie nicht noch einmal neu definieren.

Die zusätzliche Klasse .text-parallax bereitet auch den Text bereits für den späteren Parallax-Effekt vor.

Der Work-Bereich funktioniert damit bereits mit unseren vorhandenen Styles. Dabei fällt allerdings etwas auf: Einige unserer Texte erscheinen momentan sehr transparent. Das ist grundsätzlich beabsichtigt, für unseren aktuellen Stand möchten wir sie jedoch vollständig sichtbar machen.

Dafür führen wir im nächsten Schritt einige Farben als globale CSS-Variablen zusammen.

12. GLOBALE EINSTELLUNGEN

Farben zentral über CSS-Variablen verwalten

In unserem Stylesheet verwenden wir inzwischen dieselben Farben an mehreren Stellen. Bisher haben wir die jeweiligen Farbwerte direkt in die einzelnen CSS-Regeln geschrieben.

Damit wir diese Farben später einfacher ändern können, legen wir sie jetzt als globale CSS-Variablen fest.

Ganz oben in unserer assets/styles.css befindet sich bereits der :root-Bereich:
:root {
  --bg: #272c3b;
  --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif,
    "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}

Diesen vorhandenen Bereich erweitern wir um vier Farbvariablen:
// assets/styles.css

:root {
  --bg: #272c3b;
  --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif,
    "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
  --color-body: #b7ab98;
  --color-text: rgb(183, 171, 152, 1);
  --color-text-transparent: rgb(183, 171, 152, 0.2);
  --color-text-navi: rgb(183, 171, 152, 0.5);
}

Damit haben wir vier unterschiedliche Varianten unserer Textfarbe zentral hinterlegt:

--color-body verwenden wir für die allgemeine Textfarbe. --color-text enthält die vollständig sichtbare Textfarbe. --color-text-transparent besitzt mit 0.2 nur eine geringe Deckkraft und --color-text-navi ist mit 0.5 für die zurückhaltendere Darstellung unserer Navigation vorgesehen.


Vorhandene Farbwerte durch die Variablen ersetzen

Das Anlegen der Variablen allein verändert unsere Seite noch nicht. Damit sie tatsächlich verwendet werden, ersetzen wir jetzt die entsprechenden Farbwerte in unserem bisherigen CSS.

Wo bisher beispielsweise steht:
color: #b7ab98;
können wir verwenden:
color: var(--color-body);
Eine vollständig sichtbare Textfarbe wie:
color: rgb(183, 171, 152, 1);
ersetzen wir durch:
color: var(--color-text);
Für unsere transparente Textfarbe:
color: rgb(183, 171, 152, 0.2) !important;
verwenden wir:
color: var(--color-text-transparent) !important;
Und die bisher direkt eingetragene Navigationsfarbe:
color: rgb(183, 171, 152, 0.5);
kann durch:
color: var(--color-text-navi);
ersetzt werden.

Das Aussehen unserer Seite verändert sich dadurch zunächst nicht. Wir haben lediglich die bereits vorhandenen Farbwerte durch zentrale Variablen ersetzt.


Die Textfarbe zentral verändern

Jetzt können wir den Vorteil der Variablen direkt ausprobieren.

Unsere großen Texte verwenden inzwischen:
color: var(--color-text-transparent) !important;
Die dazugehörige Variable ist in :root momentan so definiert:
--color-text-transparent: rgb(183, 171, 152, 0.2);
Dadurch erscheinen diese Texte nur mit geringer Deckkraft.

Für unseren aktuellen Stand möchten wir sie vollständig sichtbar machen. Deshalb ändern wir in :root nur diese eine Zeile zu:
--color-text-transparent: rgb(183, 171, 152, 1);
Alle Elemente, die var(--color-text-transparent) verwenden, erhalten damit automatisch die neue Deckkraft.

Wir müssen die einzelnen CSS-Regeln nicht mehr separat verändern. Genau darin liegt der Vorteil unserer globalen Variablen.

Experience
Experience


13. HISTORY

Berufliche Stationen mit dem Hover-Effekt darstellen

Unseren zuvor entwickelten Hover-Effekt können wir nicht nur für kurze Leistungsbeschreibungen verwenden. Im nächsten Abschnitt nutzen wir dieselbe Technik für eine kleine berufliche Historie.

Jede Zeile zeigt zunächst ein Jahr, eine Position und das zugehörige Unternehmen. Beim Hover erscheint wieder die orangefarbene Ebene und zeigt eine alternative Bezeichnung.

Füge den folgenden Bereich in der index.html direkt nach dem Work-Bereich ein:
// index.html

<div class="row justify-content-center align-items-center min-vh-100">
  <div class="display-row width-100">
    <p class="about_content_label text-color">History</p>

    <div class="text uppercase hidden-link">
      <div class="text-row justify-content-start">
        <div class="h3">Jetzt</div>
        <div class="simple-masking">
          <h3 class="h3">Design-Leiter</h3>
          <div class="font-400">Fantasy Interactive</div>
        </div>
      </div>
      <div class="span">
        <div class="text text-black">
          <div class="text-row justify-content-start">
            <div class="h3">Jetzt</div>
            <div class="simple-masking">
              <h3 class="h3">Selbstständiger Designer</h3>
              <div class="font-400">Fantasy Interactive</div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="text uppercase hidden-link">
      <div class="text-row justify-content-start">
        <div class="h3">2016</div>
        <div class="simple-masking">
          <h3 class="h3">Senior Produkt-Designer</h3>
          <div class="font-400">Interactive Labs</div>
        </div>
      </div>
      <div class="span">
        <div class="text text-black">
          <div class="text-row justify-content-start">
            <div class="h3">2016</div>
            <div class="simple-masking">
              <h3 class="h3">Regulärer Webdesigner</h3>
              <div class="font-400">Interactive Labs</div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="text uppercase hidden-link">
      <div class="text-row justify-content-start">
        <div class="h3">2012</div>
        <div class="simple-masking">
          <h3 class="h3">Kunstdirektor</h3>
          <div class="font-400">DR Com Group</div>
        </div>
      </div>
      <div class="span">
        <div class="text text-black">
          <div class="text-row justify-content-start">
            <div class="h3">2012</div>
            <div class="simple-masking">
              <h3 class="h3">Photoshop-Zeichner</h3>
              <div class="font-400">DR Com Group</div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="text uppercase hidden-link">
      <div class="text-row justify-content-start">
        <div class="h3">2009</div>
        <div class="simple-masking">
          <h3 class="h3">Flash-Designer</h3>
          <div class="font-400">DR Com Group</div>
        </div>
      </div>
      <div class="span">
        <div class="text text-black">
          <div class="text-row justify-content-start">
            <div class="h3">2009</div>
            <div class="simple-masking">
              <h3 class="h3">Jurassic-Designer</h3>
              <div class="font-400">DR Com Group</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Die zusätzlichen History-Styles ergänzen

Den eigentlichen Hover-Effekt müssen wir nicht erneut programmieren. Die dafür benötigten Klassen .span, .text und .text-row haben wir bereits angelegt.

Für die History benötigen wir lediglich einige zusätzliche Formatierungen.

Füge deshalb Folgendes unter deinen bisherigen Code in assets/styles.css ein:
// assets/styles.css

.text-black {
  color: #0d0d0d !important;
}

.simple-masking {
  text-transform: none;
}

.simple-masking .font-400 {
  font-size: 0.85rem;
  line-height: 1rem;
}

Mit .text-black erhält der Text innerhalb der orangefarbenen Hover-Fläche eine dunkle Farbe und hebt sich dadurch deutlich vom Hintergrund ab.
.simple-masking hebt die zuvor über .uppercase festgelegte Großschreibung für diesen Teil des Inhalts wieder auf. So können Position und Unternehmen in normaler Schreibweise dargestellt werden.

Mit .font-400 verkleinern wir zusätzlich die Unternehmensbezeichnung unterhalb der jeweiligen Position.

Die bereits vorhandene Klasse .justify-content-start richtet Jahr und Beschreibung gemeinsam am Anfang der Zeile aus. Auch die .h3-Formatierungen haben wir bereits im vorherigen Hover-Bereich vorbereitet und können sie hier wiederverwenden.

Beim Überfahren einer Zeile greift schließlich derselbe clip-path-Effekt wie zuvor. Dadurch öffnet sich die orangefarbene Ebene und gibt den alternativen Inhalt frei.


4.webp 67.6 KB


Damit haben wir einen bestehenden Effekt für einen völlig anderen Inhalt wiederverwendet, ohne die eigentliche Animation erneut programmieren zu müssen.

Als Nächstes erstellen wir einen weiteren typografischen Abschnitt, in dem wir einige ausgewählte Kunden beziehungsweise Projekte vorstellen.

14. CLIENTS

Einen weiteren typografischen Abschnitt aufbauen

Nach unserer beruflichen Historie erstellen wir einen weiteren großformatigen Textbereich. Diesmal verwenden wir ihn als Einleitung für die anschließend folgenden Kunden und Projekte.

Beim Aufbau können wir vollständig auf unsere bereits vorhandenen Klassen zurückgreifen. Dadurch benötigen wir für diesen Abschnitt kein zusätzliches CSS.

Füge den folgenden Code in unserer index.html nach dem History-Bereich ein:
// index.html

<div class="row justify-content-center align-items-center min-vh-100">
  <div class="display">
    <p class="about_content_label text-color">Clients</p>
    <div class="text no-padding no-border text-align-left text-row">
      Ich habe mit einigen der innovativsten Branchenführer
      zusammengearbeitet, um ihre erstklassigen Produkte aufzubauen.
    </div>
    <div class="text no-padding no-border text-align-left text-row">
      <span><strong>innovative</strong> Industrieführer</span>
    </div>
    <div class="text no-padding no-border text-align-left text-row">
      zu helfen, ihre erstklassigen Produkte aufzubauen.
    </div>
  </div>
</div>

Der Aufbau entspricht unserem vorherigen About-Bereich. Mit min-vh-100 nimmt auch dieser Abschnitt mindestens die vollständige Höhe des Browserfensters ein.

Für die einzelnen Zeilen verwenden wir wieder .text, .text-row, .no-padding, .no-border und .text-align-left. Sämtliche dafür notwendigen Formatierungen befinden sich deshalb bereits in unserer assets/styles.css.

Das Wort innovative liegt innerhalb eines strong-Elements und erhält dadurch automatisch unsere bereits definierte orangefarbene Hervorhebung.

Gerade bei einem Onepager ist diese Wiederverwendung hilfreich: Statt für jeden Abschnitt neue Styles anzulegen, bauen wir unterschiedliche Inhalte aus denselben grundlegenden Komponenten auf.

5.webp 105 KB


Der Clients-Bereich dient zunächst als typografische Einleitung. Im nächsten Schritt ergänzen wir die eigentliche Kundenliste und greifen dabei erneut auf unseren animierten Hover-Effekt zurück.

15. INTERAKTIVE KUNDENLISTE

Kunden und Projekte mit unserem Hover-Effekt darstellen

Unterhalb der Clients-Einleitung erstellen wir jetzt die eigentliche Kundenliste. Dafür verwenden wir denselben Aufbau, den wir bereits bei „What i do“ kennengelernt haben.

Zunächst ist jeweils nur der Name des Kunden sichtbar. Beim Hover öffnet sich die orangefarbene Ebene und zeigt zusätzlich eine kurze Beschreibung des jeweiligen Projekts.

Füge den folgenden Code in der index.html direkt nach dem vorherigen Clients-Bereich ein:
// index.html

<div
  class="row justify-content-center align-items-center min-vh-100"
  style="position: relative"
>
  <div class="display-row width-100">
    <div class="text uppercase hidden-link">
      <div class="text-row">Ford</div>
      <div class="span">
        <div class="text-row">
          <div class="big">Ford</div>
          <div class="smal">
            Arbeit an der nächsten Generation der HMI-Erfahrung ohne Fahrerfahrung.
          </div>
        </div>
      </div>
    </div>
    <div class="text uppercase hidden-link">
      <div class="text-row">Ufc</div>
      <div class="span">
        <div class="text-row">
          <div class="big">Ufc</div>
          <div class="smal">
            Entwicklung der Zukunft des UFC-Sportökosystems, obwohl ich kein Sportfan bin.
          </div>
        </div>
      </div>
    </div>
    <div class="text uppercase hidden-link">
      <div class="text-row">Lincoln</div>
      <div class="span">
        <div class="text-row">
          <div class="big">Lincoln</div>
          <div class="smal">
            Definition des visuellen Konzepts und der Designsprache für den Lincoln Zephyr 2022, obwohl ich ihn nie persönlich gesehen habe.
          </div>
        </div>
      </div>
    </div>
    <div class="text uppercase hidden-link">
      <div class="text-row">Royal caribbean</div>
      <div class="span">
        <div class="text-row">
          <div class="big">Royal caribi</div>
          <div class="smal">
            Ich war nur eine Person in einem riesigen Team, das ein ganzes Royal Caribbean-Ökosystem geschaffen hat.
          </div>
        </div>
      </div>
    </div>
    <div class="text uppercase hidden-link">
      <div class="text-row">SleepiQ</div>
      <div class="span">
        <div class="text-row">
          <div class="big">SleepiQ</div>
          <div class="smal">
            Entwickelte ein Produkt für über 1 Million Benutzer und nutzte dabei meine beste persönliche Erfahrung: das Schlafen.
          </div>
        </div>
      </div>
    </div>
    <div class="text uppercase hidden-link">
      <div class="text-row">NFL</div>
      <div class="span">
        <div class="text-row">
          <div class="big">NFL</div>
          <div class="smal">
            Erforschung der Zukunft des Fantasy-Footballs, während ich mich in einem Land befand, in dem Fußball eine völlig andere Sportart bedeutet.
          </div>
        </div>
      </div>
    </div>

  </div>
</div>

Für diesen Abschnitt müssen wir keine neuen CSS-Regeln hinzufügen. Die Klassen .text, .span, .text-row, .big, .smal, .uppercase und .hidden-link haben wir bereits in den vorherigen Abschnitten angelegt.

Auch die Animation funktioniert deshalb sofort nach demselben Prinzip: Die orangefarbene .span-Ebene ist zunächst mit clip-path auf die Mitte der jeweiligen Zeile reduziert. Beim Hover wird sie auf die vollständige Höhe und Breite geöffnet.

Dadurch können wir denselben visuellen Effekt für unterschiedliche Inhalte einsetzen, ohne den dazugehörigen CSS-Code zu duplizieren.


6.webp 51.9 KB

Damit ist auch unser Clients-Bereich abgeschlossen. Als Nächstes erstellen wir den Contact-Bereich am Ende des Onepagers. Dort kombinieren wir erneut ein großflächiges Hintergrundbild mit unserer Typografie.

16. CONTACT

Den Abschlussbereich mit einem Hintergrundbild gestalten

Zum Abschluss unseres Hauptinhalts erstellen wir den Contact-Bereich. Ähnlich wie beim Work-Bereich verwenden wir wieder ein großflächiges Hintergrundbild, ein dunkles Overlay und unsere bereits vorhandene Typografie.

Als Inhalt verwenden wir an dieser Stelle ein kurzes Motto. Durch den bildschirmfüllenden Hintergrund hebt sich dieser Bereich deutlich von den vorherigen Abschnitten ab.

Füge den folgenden Code in der index.html direkt nach dem Clients-Bereich ein:
// index.html

<div
  id="Contact"
  class="row justify-content-center align-items-center min-vh-100"
>
  <div class="bg-img">
    <div class="bg-parallax img">
      <img class="parallax-img" src="assets/images/banner-bottom.webp" />
      <div class="parallax-overlay"></div>
    </div>
  </div>

  <div class="display">
    <p class="about_content_label text-color text-align-center">
      Mein Motto
    </p>
    <div class="text no-padding uppercase text-center no-border">
      Gutes Design
    </div>
    <div class="text no-padding uppercase text-center no-border">
      ist ehrlich
    </div>
    <p class="about_content_label text-color text-align-center">
      Dieter Rams
    </p>
  </div>
</div>

Mit id="Contact" erhält der Bereich gleichzeitig das Ziel für den bereits zu Beginn angelegten Navigationslink href="#Contact".

Für das Hintergrundbild greifen wir erneut auf .bg-img, .bg-parallax, .parallax-img und .parallax-overlay zurück. Der Aufbau entspricht damit unserem Work-Bereich und benötigt keine zusätzlichen CSS-Regeln.

Das Bild banner-bottom.webp wird bildschirmfüllend im Hintergrund dargestellt und durch das Overlay abgedunkelt. Darüber platzieren wir unser Motto mit den bereits vorhandenen Textklassen.

Auch hier zeigt sich wieder der Vorteil unserer bisherigen Struktur: Hintergrund, Overlay und Typografie können für einen neuen Abschnitt kombiniert werden, ohne dieselben Styles erneut schreiben zu müssen.


Mein Motto
Mein Motto

Damit ist der eigentliche Hauptinhalt unseres Onepagers aufgebaut. Im nächsten Schritt ergänzen wir eine seitlich fixierte Leiste mit mehreren Icons, die auf großen Displays eingeblendet wird.

17. SEITLICHE ICON-LEISTE

Eine fixierte Icon-Leiste für große Displays hinzufügen

Zusätzlich zu unserer Navigation ergänzen wir eine kleine seitliche Icon-Leiste. Sie wird am linken unteren Rand des Browserfensters fixiert und bleibt dadurch auch beim Scrollen an derselben Position.

Die einzelnen Grafiken werden direkt als SVG in unser HTML eingebunden. Dadurch benötigen wir für die Icons keine zusätzlichen Bilddateien und können ihr Erscheinungsbild später unmittelbar über CSS beeinflussen.

Füge den folgenden <aside>-Bereich in unserer index.html ein:
// index.html

<aside>
  <ul>
    <li class="magnetic">
      <a href="#">
        <svg
          width="24"
          height="24"
          viewBox="0 0 24 24"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
          class="svg"
          viewbox_="0 0 NaN NaN"
        >
          <path
            d="M16.5781 12.5693C16.6822 14.7607 17.625 16.7336 19.1013 18.1693C20.415 16.6534 21.2417 14.7057 21.3334 12.5693H16.5781Z"
            fill="#B7AB98"
          ></path>
          <path
            d="M12.5703 11.7719H15.7707C15.8748 9.35122 16.9216 7.17217 18.5523 5.59053C16.989 4.07429 14.8905 3.1084 12.5703 3.0083V11.7719Z"
            fill="#B7AB98"
          ></path>
          <path
            d="M3.00879 12.5693C3.10091 14.7057 3.92723 16.6534 5.24087 18.1693C6.71723 16.734 7.66 14.7607 7.76408 12.5693H3.00879Z"
            fill="#B7AB98"
          ></path>
          <path
            d="M16.5781 11.7723H21.3334C21.2413 9.63594 20.415 7.6882 19.1013 6.17236C17.625 7.60804 16.6818 9.58091 16.5781 11.7723Z"
            fill="#B7AB98"
          ></path>
          <path
            d="M8.57167 11.7719H11.772V3.0083C9.45182 3.1084 7.35334 4.07429 5.79004 5.59053C7.42073 7.17217 8.46758 9.35122 8.57167 11.7719Z"
            fill="#B7AB98"
          ></path>
          <path
            d="M15.7707 12.5693H12.5703V21.333C14.8905 21.2333 16.989 20.267 18.5523 18.7507C16.9216 17.1691 15.8748 14.9901 15.7707 12.5693Z"
            fill="#B7AB98"
          ></path>
          <path
            d="M7.76408 11.7723C7.66 9.58091 6.71723 7.60804 5.24087 6.17236C3.92723 7.6882 3.10091 9.63594 3.00879 11.7723H7.76408Z"
            fill="#B7AB98"
          ></path>
          <path
            d="M11.772 12.5693H8.57167C8.46758 14.9901 7.42073 17.1691 5.79004 18.7507C7.35334 20.267 9.45182 21.2329 11.772 21.333V12.5693Z"
            fill="#B7AB98"
          ></path>
        </svg>
      </a>
    </li>
    <li class="magnetic">
      <a href="#">
        <svg
          width="24"
          height="24"
          viewBox="0 0 24 24"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
          class="svg"
          viewbox_="0 0 NaN NaN"
        >
          <path
            d="M17.0912 2.6665H6.90942C6.35229 2.6665 5.80063 2.77624 5.28591 2.98944C4.7712 3.20264 4.30351 3.51514 3.90957 3.90908C3.11396 4.70469 2.66699 5.78377 2.66699 6.90893V17.0907C2.66699 17.6479 2.77673 18.1995 2.98993 18.7143C3.20313 19.229 3.51562 19.6966 3.90957 20.0906C4.70518 20.8862 5.78426 21.3332 6.90942 21.3332H17.0912C17.6484 21.3332 18.2 21.2234 18.7147 21.0102C19.2295 20.797 19.6971 20.4845 20.0911 20.0906C20.485 19.6966 20.7975 19.229 21.0107 18.7143C21.2239 18.1995 21.3337 17.6479 21.3337 17.0907V6.90893C21.3337 6.3518 21.2239 5.80014 21.0107 5.28542C20.7975 4.77071 20.485 4.30303 20.0911 3.90908C19.6971 3.51514 19.2295 3.20264 18.7147 2.98944C18.2 2.77624 17.6484 2.6665 17.0912 2.6665ZM6.06093 6.90893C5.89312 6.90893 5.72907 6.85917 5.58954 6.76593C5.45001 6.6727 5.34125 6.54018 5.27703 6.38514C5.21281 6.2301 5.19601 6.0595 5.22875 5.89491C5.26149 5.73032 5.3423 5.57914 5.46096 5.46047C5.57962 5.34181 5.73081 5.261 5.8954 5.22826C6.05999 5.19552 6.23059 5.21233 6.38563 5.27655C6.54067 5.34076 6.67319 5.44952 6.76642 5.58905C6.85965 5.72858 6.90942 5.89263 6.90942 6.06044C6.90942 6.28548 6.82002 6.50129 6.6609 6.66041C6.50178 6.81953 6.28596 6.90893 6.06093 6.90893ZM12.0003 17.0907C10.9934 17.0907 10.0092 16.7922 9.17197 16.2328C8.33477 15.6734 7.68226 14.8783 7.29694 13.948C6.91162 13.0178 6.8108 11.9942 7.00724 11.0066C7.20367 10.0191 7.68853 9.112 8.40051 8.40002C9.11249 7.68804 10.0196 7.20318 11.0071 7.00675C11.9947 6.81031 13.0183 6.91113 13.9485 7.29645C14.8788 7.68177 15.6739 8.33428 16.2333 9.17148C16.7927 10.0087 17.0912 10.993 17.0912 11.9998C17.0912 13.35 16.5549 14.6449 15.6001 15.5997C14.6454 16.5544 13.3505 17.0907 12.0003 17.0907Z"
            fill="#B7AB98"
          ></path>
        </svg>
      </a>
    </li>
    <li class="magnetic">
      <a href="#">
        <svg
          width="24"
          height="24"
          viewBox="0 0 24 24"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
          class="svg"
          viewbox_="0 0 NaN NaN"
        >
          <path
            d="M19.2611 11.3279L6.57538 3.39932C6.45536 3.32431 6.31745 3.2828 6.17597 3.27908C6.03449 3.27537 5.8946 3.30959 5.77081 3.3782C5.64702 3.44681 5.54386 3.5473 5.47202 3.66924C5.40019 3.79119 5.3623 3.93014 5.3623 4.07167V19.9288C5.3623 20.0703 5.40019 20.2093 5.47202 20.3312C5.54386 20.4532 5.64702 20.5536 5.77081 20.6223C5.8946 20.6909 6.03449 20.7251 6.17597 20.7214C6.31745 20.7177 6.45536 20.6761 6.57538 20.6011L19.2611 12.6726C19.3758 12.6015 19.4705 12.5022 19.5361 12.3843C19.6018 12.2664 19.6363 12.1336 19.6363 11.9986C19.6363 11.8637 19.6018 11.7309 19.5361 11.613C19.4705 11.495 19.3758 11.3958 19.2611 11.3247V11.3279Z"
            fill="#B7AB98"
          ></path>
        </svg>
      </a>
    </li>
    <li class="magnetic">
      <a href="#">
        <svg
          width="24"
          height="24"
          viewBox="0 0 24 24"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
          class="svg"
          viewbox_="0 0 NaN NaN"
        >
          <path
            d="M7.02814 19.8291H3.44995V8.07215H7.13038V19.8291H7.02814ZM5.18793 6.43641C4.06336 6.43641 3.04102 5.5163 3.04102 4.28949C3.04102 3.16492 3.96112 2.14258 5.18793 2.14258C6.31251 2.14258 7.33485 3.06268 7.33485 4.28949C7.33485 5.5163 6.41474 6.43641 5.18793 6.43641ZM20.7275 19.8291H17.0471V14.104C17.0471 12.7749 17.0471 11.0369 15.2069 11.0369C13.2644 11.0369 13.06 12.4682 13.06 14.0017V19.8291H9.37953V8.07215H12.8555V9.7079C13.3667 8.78779 14.4912 7.86769 16.3314 7.86769C20.0119 7.86769 20.7275 10.3213 20.7275 13.4906V19.8291Z"
            fill="#B7AB98"
          ></path>
        </svg>
      </a>
    </li>
  </ul>
</aside>

Der <aside> enthält vier Listeneinträge mit jeweils einer direkt eingebetteten SVG-Grafik. Durch diese Struktur können wir die gesamte Leiste gemeinsam positionieren und die einzelnen Icons untereinander anordnen.


Die Icon-Leiste positionieren und gestalten

Jetzt ergänzen wir die zugehörigen Styles in unserer assets/styles.css:
// assets/styles.css

aside {
  display: none;
  flex-direction: column;
  gap: 3rem;
  position: fixed;
  padding: 2.5rem;
  padding-bottom: 4rem;
  left: 0;
  bottom: 0;
}

aside ul {
  display: flex;
  flex-direction: column;
  gap: 3rem;
  position: sticky;
  list-style: none;
}

aside ul li {
  --x: 0px;
  --y: 0px;
  --size: 20px;
}

a:hover svg path {
  fill: #0d0d0d;
  -webkit-transition: fill 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);
  transition: fill 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);
}

@media (min-width: 1248px) {
  aside {
    display: flex;
  }
}

Standardmäßig ist der gesamte aside mit display: none ausgeblendet. Dadurch erscheint die zusätzliche Leiste nicht auf kleineren Displays und nimmt dort auch keinen Platz ein.

Erst ab einer Bildschirmbreite von 1248px setzen wir den Bereich über die Media Query auf display: flex.

Mit position: fixed, left: 0 und bottom: 0 bleibt die Leiste am linken unteren Rand des Browserfensters stehen. Die Icons selbst werden innerhalb der Liste mit Flexbox untereinander angeordnet.

Für die einzelnen Listeneinträge legen wir außerdem die Variablen --x, --y und --size an. Diese bereiten die Icons bereits für weitere Interaktionen vor, die wir in einem späteren Teil des Tutorials ergänzen können.

Beim Hover über einen Link verändern wir mit svg path außerdem die Füllfarbe der SVG-Grafik. Die definierte Transition sorgt dafür, dass dieser Farbwechsel weich animiert wird.


3.mp4 21 MB


Damit ist auch unsere seitlich fixierte Icon-Leiste vorbereitet. Auf kleineren Geräten bleibt sie verborgen, während sie auf großen Displays automatisch eingeblendet wird.

Als Nächstes bauen wir den Footer unseres Onepagers auf. Dort kombinieren wir Kontaktinformationen und verschiedene Links erneut mit unserem bereits entwickelten Hover-Effekt.

18. FOOTER

Links und Kontaktmöglichkeiten im Footer ergänzen

Zum Abschluss unseres Onepagers erstellen wir einen Footer mit verschiedenen Social-Media-Links sowie unseren direkten Kontaktmöglichkeiten.

Auch hier verwenden wir den bereits entwickelten Hover-Effekt erneut. Dadurch verändert sich beim Überfahren eines Links nicht nur seine Darstellung, sondern es kann zusätzlich ein alternativer Text eingeblendet werden.

Füge den folgenden Code in der index.html ein:
// index.html

<footer>
  <div class="row">
    <div class="display">
      <p class="about_content_label text-color">connect</p>
      <div
        class="text no-padding no-border text-align-left text-row"
      ></div>
    </div>
  </div>

  <div class="row hidden-circle">
    <div class="div-icon"></div>

    <div class="display">
      <ul class="no-padding no-border text-align-left text-column">
        <li class="text uppercase hidden-link">
          <div class="text-row">
            <a href="" class="contact-link">Dribbble</a>
          </div>
          <div class="span">
            <div class="text-row">
              <div class="big">
                <a href="" class="contact-link">Falsche Arbeiten</a>
              </div>
            </div>
          </div>
        </li>

        <li class="text uppercase hidden-link">
          <div class="text-row">
            <a href="https://youtube.com" class="contact-link">Youtube</a>
          </div>
          <div class="span">
            <div class="text-row">
              <div class="big">
                <a href="https://youtube.com" class="contact-link"
                  >Zufällige Tutorials</a
                >
              </div>
            </div>
          </div>
        </li>

        <li class="text uppercase hidden-link">
          <div class="text-row">
            <a href="" class="contact-link">Linkedin</a>
          </div>
          <div class="span">
            <div class="text-row">
              <div class="big">
                <a href="" class="contact-link">Ernsthaft ich</a>
              </div>
            </div>
          </div>
        </li>
      </ul>

      <ul class="no-padding no-border text-align-left text-column">
        <li class="text uppercase hidden-link">
          <div class="text-row">
            <a href="" class="contact-link">Instagram</a>
          </div>
          <div class="span">
            <div class="text-row">
              <div class="big">
                <a href="" class="contact-link">Kein TikTok</a>
              </div>
            </div>
          </div>
        </li>

        <li class="text uppercase hidden-link">
          <div class="text-row">
            <a href="" class="contact-link">Facebook</a>
          </div>
          <div class="span">
            <div class="text-row">
              <div class="big">
                <a href="" class="contact-link"
                  >Hauptsächlich Hundegeschichten</a
                >
              </div>
            </div>
          </div>
        </li>

        <li class="text uppercase hidden-link">
          <div class="text-row">
            <a href="" class="contact-link">Behance</a>
          </div>
          <div class="span">
            <div class="text-row">
              <div class="big">
                <a href="" class="contact-link">Der Jurassic Park</a>
              </div>
            </div>
          </div>
        </li>
      </ul>

      <ul class="no-padding no-border text-align-left text-column">
        <li class="text uppercase hidden-link column">
          <div class="text-row small-height">E-Mail</div>
          <div class="small small-height">bonsai1972@gmail.com</div>
          <div class="span">
            <div class="text-row column">
              <div class="small small-height">
                100%ige Chance, dass ich sie lese
              </div>
              <div class="small small-height">bonsai1972@gmail.com</div>
            </div>
          </div>
        </li>

        <li class="text uppercase hidden-link">
          <div class="text-row small-height">Telefon</div>
          <div class="small small-height">+49 221 2828288</div>
          <div class="span">
            <div class="text-row column">
              <div class="small small-height">
                90%ige Chance, dass ich nicht abhebe
              </div>
              <div class="small small-height">+49 221 2828288</div>
            </div>
          </div>
        </li>
      </ul>
    </div>
  </div>
</footer>

Der Footer besteht aus drei Spalten. Die ersten beiden enthalten verschiedene externe Links, während die dritte Spalte E-Mail-Adresse und Telefonnummer aufnimmt.

Für die Links greifen wir erneut auf .text, .hidden-link, .span, .text-row und .big zurück. Dadurch können wir unseren bereits vorhandenen Hover-Effekt auch im Footer verwenden.

Die Klasse .hidden-circle sowie das leere Element .div-icon bereiten außerdem bereits Elemente vor, die wir in einem späteren Teil des Tutorials noch benötigen.


Den Footer gestalten

Jetzt ergänzen wir den vollständigen Footer-Code in unserer assets/styles.css:
// assets/styles.css

footer {
  background: var(--bg);
  color: #b7ab98 !important;
}

footer .row {
  max-width: 1248px;
  margin: auto;
}

footer .row .display {
  display: flex;
  flex-direction: column;
  gap: 2rem;
  justify-content: space-between;
  align-items: center;
  width: 100% !important;
}

footer .row .display .text-column {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  width: 100%;
}

footer .row .display .text-column {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

footer .row .display .text-column .text .text-row .big,
footer .row .display .text-column .text .text-row {
  font-size: 2rem;
  text-decoration: none;
  text-transform: none;
}

footer .row .display .text-column .text .text-row,
footer .row .display .text-column .text .text-row + .small {
  color: #b7ab98;
}

footer .row .display .text-column .text .span .text-row {
  color: #0d0d0d;
  padding-left: 0.5rem;
}

footer .row .display .text-column .text {
  display: flex;
  flex-direction: column;
  height: 2rem;
  border-bottom: none;
  padding-left: 1rem;
  margin-left: -1rem;
}

footer .row .display .text-column .text .column {
  display: flex;
  flex-direction: column;
  justify-content: start;
}

footer .row .display .text-column .text .small {
  font-size: 1rem;
  text-decoration: none;
  text-transform: none;
}

footer .row .display .text-column .text .small-height {
  display: flex;
  flex-direction: row;
  height: 1.4rem;
  line-height: 1.4rem;
  font-size: 1rem;
  width: 100%;
}

footer .contact-link {
  text-decoration: none;
  color: var(--color-body);
}

footer .big .contact-link {
  text-decoration: none;
  color: #0d0d0d;
}

footer .contact-link::after {
  background-image: url(assets/images/contact-link.svg);
  background-repeat: no-repeat;
  background-size: 100%;
  content: "";
  display: block;
  height: 0.75rem;
  left: -0.5em;
  position: absolute;
  top: 0.55em;
  width: 0.75rem;
}

@media (min-width: 1248px) {
  footer .row .display {
    flex-direction: row;
  }
}

Auf kleineren Displays stehen die drei Bereiche zunächst untereinander. Ab einer Bildschirmbreite von 1248px wechseln wir mit der Media Query auf eine horizontale Anordnung.

Die unterschiedlichen Selektoren innerhalb von footer passen unsere bereits vorhandenen Text- und Hover-Klassen gezielt an die kompaktere Darstellung des Footers an.

Mit .small und .small-height formatieren wir die kleineren Kontaktinformationen. Die eigentlichen Links erhalten über .contact-link unsere globale Textfarbe, während die Links innerhalb der orangefarbenen Hover-Fläche dunkel dargestellt werden.

Über .contact-link::after wird außerdem eine kleine zusätzliche Grafik neben den entsprechenden Links eingebunden.


4.mp4 44 MB



Damit ist auch unser Footer fertig aufgebaut und der erste Teil unseres Onepagers abgeschlossen.
Meld dich an und schreibe ein Kommentar