Quantcast
Channel: #CSS - Agentur kulturbanause
Viewing all 173 articles
Browse latest View live

Transparente Rahmen (border) mit CSS

$
0
0
transparente-borders

Transparente Umrandungen mit Hilfe der border-Eigenschaft scheinen auf den ersten Blick kein Problem zu sein. In der Praxis stellt sich jedoch schnell heraus, dass es nicht so funktioniert, wie in der Theorie gedacht. Und so entstehen oft völlig überflüssige <div>-Verschachtelungen. Um euch vor solch peinlichen Konstruktionen zu bewahren, zeigen wir euch in diesem Beitrag wie es sauberer umgesetzt wird und rufen in diesem Zusammenhang die Eigenschaft background-clip in Erinnerung

Die background-clip-Eigenschaft

Die CSS-Eigenschaft background-clip legt fest, über welche Boxen des Box Modells ein Hintergrund gerendert wird. Der Standardwert ist border-box. Daher hilft es nicht, einfach nur einen transparenten Farbwert für die Umrandung zu verwenden. Wie im folgenden Beispiel erkennbar ist, schimmert der blaue Hintergrund des <div> nach wie vor durch.

div {
 height:100px;
 width: 100px;
 background:#19667a;
 border:10px solid rgba(255,255,255,0.5);
}

transparente-borders-1

Beispiel anschauen

background-clip: padding-box;

Um den Hintergrund hinter dem Rahmen zu entfernen, muss lediglich die folgende Zeile CSS-Code hinzugefügt werden:

background-clip: padding-box;

Anschließend wird die Hintergrundfarbe nur noch über die Content- und Padding-Box gerendert; mit dem Ergebnis, dass der Rahmen transparent angezeigt wird.

transparente-borders-2

Beispiel anschauen

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.


Die CSS-Eigenschaft box-decoration-break – padding & Co. beim Zeilenumbruch beibehalten

$
0
0
box-decoration-break

Wenn ihr Inline-Elementen über padding einen Innenabstand zuweist, dann wird dieses padding bei einem Zeilenumbruch ignoriert. Gleiches gilt für Eigenschaften wie box-shadow oder border-radius. Diese Tatsache ist in der Praxis extrem lästig, da es beispielsweise nicht möglich ist nur den Textbereich einer mehrzeiligen Überschrift mit einer Hintergrundfarbe zu hinterlegen und ansprechend zu gestalten. An den Zeilenumbrüchen wird der Hintergrund unschön abgeschnitten. Die CSS-Eigenschaft box-decoration-break schafft Abhilfe.

Zeilenumbrüche mit CSS optimieren

Angenommen wir möchten die Überschriften auf unserer Website so gestalten, dass der Text farbig hinterlegt ist. Da das HTML-Element ein Block-Element ist, muss die Überschrift zunächst auf display:inline; gestellt werden, damit der farbige Hintergrund auch wirklich nur hinter dem Text angezeigt wird. Mit padding sorgen wir dafür, dass der Text einen kleinen Abstand zum Rand des eingefärbten Hintergrunds behält.

Sofern die Überschrift einzeilig ist gibt es kein Problem. Bei mehrzeiligen Überschriften hingegen bricht der Text um, und verliert an der Umbruchkante das padding. Sehr ärgerlich.

h1 {
  font-size: 1.3em;
  background: #222;
  color: white;
  padding: .3em .7em .2em .4em;
  display: inline;
  line-height: 160%;
}
box-decoration-break-css

Das Standard-Styling: An den Umbrücken entstehen harte Kanten

CSS box-decoration-break

Die CSS-Eigenschaft box-decoration-break ermöglicht es die Gestaltung an der Umbruchkante eines Inline-Elements festzulegen. Es stehen folgende Eigenschaften zur Verfügung:

Eigenschaften für box-decoration-break

slice
Das Element wird als Ganzes betrachtet und die Gestaltung wird nur an den Außenkanten angewandt. Bei einem Umbruch entsteht ein harter Schnitt (Standardwert).
clone
Das Element wird – sofern ein Umbruch in der Horizontalen oder Vertikalen stattfindet – in Fragmente unterteilt. Der Style wird dann auf jedes Fragment einzeln angewandt.

Mit der Eigenschaft clone kann das Problem aus dem o.g. Beispiel problemlos korrigiert werden.

h1 {

  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
Korrigierte Darstellung mit box-decoration-break

Korrigierte Darstellung mit box-decoration-break

Beispiel anschauen

Browsersupport

Zum Veröffentlichungszeitpunkt dieses Beitrags unterstützen alle Browser bis auf den Internet Explorer die Eigenschaft. Den exakten Browsersupport entnehmt ihr bitte der Website caniuse.com

Links/Quellen

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

Touchscreen optimierte DropDown-Navigation mit jQuery

$
0
0
navi-touch

Umfangreiche Navigationen stellen insbesondere auf großen Touchscreens eine Herausforderung dar. Da Mouse-Over-Effekte nicht funktionieren, werden tiefer liegende Navigationsebenen häufig durch einen Klick auf das unverlinkte Elternelement geöffnet. Wenn ein anderes Elternelement angeklickt wird, soll das zuvor geöffnete Untermenü geschlossen und das neue Menü geöffnet werden. In diesem Beitrag archivieren wir ein Snippet, dass diese Aufgabe erledigt.

Untermenü per Klick öffnen und automatisch schließen, wenn ein anderes Untermenü geöffnet wird

Das Snippet stellt folgende Funktionalität her: Per Klick auf ein Elternelement wird das Untermenü geöffnet. Ein erneuter Klickt schliesst es wieder (Toggle-Funktion). Ist ein Untermenü geöffnet und der Anwender klickt ein weiteres Elternelement an, so schließt sich das zuvor geöffnet Untermenü zunächst. Anschließend wird das Submenu des zuletzt angeklickten Elternelements geöffnet.

Beispiel anschauen

<nav class="site-nav">
 <ul>
   <li class="menu-item-has-children">
     <a href="#">Menüpunkt</a>
     <ul class="sub-menu">
       <li><a href="#">Unterpunkt</a></li>
       <li><a href="#">Unterpunkt</a></li>
     </ul>
   </li>
   <!-- weiter nach dem gleichen Muster -->
 </ul>
</nav>
* {
   font-family: Arial, sans-serif;
   box-sizing: border-box;
}

html,
body {
   margin: 0;
   padding: 0;
}

header {
   max-width: 1200px;
   margin: 5em auto;
   transition: all .5s ease-in-out;
   text-align: center;
}

a:hover {
   opacity: .9;
}

.site-nav ul {
   margin: 0;
   padding: 0;
   list-style: none;
}

.site-nav > ul {
   display: flex;
}

.site-nav > ul > li {
   position: relative;
   margin: .2em;
   flex: 1;
}

.site-nav a {
   display: block;
   padding: 1em;
   text-decoration: none;
   color: white;
   border-bottom: 1px solid rgba(255,255,255,.5);
   background: darkcyan;
}

.sub-menu {
   display: none;
}

.sub-menu a {
   background: #333;
}
$('.site-nav > ul > .menu-item-has-children').click(function(e) {
 e.stopPropagation();
 $(this).toggleClass('sub-menu-open');
 var $el = $('ul',this);
 $('.site-nav > ul > li > .sub-menu').not($el).slideUp();
 $('.site-nav > ul > li > .sub-menu').not($el).parent().parent('li').removeClass('sub-menu-open');
 $el.stop(true, true).slideToggle(400);
});

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

CSS Shapes – Textumfluss, Konturenführung und individuelle Formen für Websites

$
0
0
CSS Shapes

Normalerweise erzeugen alle HTML-Elemente auf einer Website eine rechteckige Box. Das geschieht auch, wenn sie nicht rechteckig aussehen, da sie beispielsweise mit der CSS-Eigenschaft border-radius optisch so verändert wurden, dass sie abgerundet wirken. Texte und andere Elemente richten sich nun immer an den rechteckigen Boxen aus, was optisch unschöne Ergebnisse erzeugen kann. Mit den sog. »CSS Shapes« ist es möglich, nicht rechteckige Formen zu erzeugen und beispielsweise Texte exakt um ein Element herumfließen zu lassen. Vergleichbar mit der Konturenführung aus InDesign. Somit sind sehr interessante und magazinähnliche Layouts möglich.

Allgemeine Infos

CSS Shapes funktionieren nur mit gefloateten Elementen. Es stehen einige geometrische Grundformen wie Kreise, Ellipsen und Rechtecke zur Verfügung. Darüber hinaus habt ihr die Möglichkeit Polygone zu zeichnen und Grafiken, die eine Alphamaske besitzen als Shape zu verwenden.

CSS Shape mit »shape-outside« erstellen

Mit der CSS-Eigenschaft shape-outside definieren wir die äußere Form des Elements. Um diese Form kann beispielsweise Text herumfließen.

Für shape-outside stehen uns folgende Funktionen zur Verfügung:

  • circle() erzeugt einen Kreis
  • ellipse() erzeugt eine Ellipse
  • inset() erzeugt ein Rechteck
  • polygon() erzeugt eine beliebige Form mit mehr als drei Ecken
  • url() erzeugt eine Form anhand der transparenten Pixel eines Bildes

Eigenschaften für CSS Shapes

Neben shape-outside existieren noch weitere CSS-Eigenschaften im Zusammenhang mit Shapes

shape-margin
shape-margin legt einen Abstand zwischen dem äußeren Rand der Form und dem umfließenden Text fest. Dabei kann der Abstand nicht über die durch shape-outside erstellte Form hinausgehen
shape-image-treshold
shape-image-treshold legt durch einen Wert zwischen 0.0 und 1.0 fest ab welcher Deckkraft ein Pixel des Bildes zur Erstellung der Form url() genutzt wird. Ein Wert von 0.7 bedeutet, dass Pixel mit einer Deckkraft unter 70% nicht Teil der Form sind
shape-inside
shape-inside ist ein Feature, das zum Veröffentlichungszeitpunkt dieses Beitrags noch nicht in unterstützt wird. Es soll ermöglichen Text passgenau in eine Form zu füllen anstatt ihn außen entlang fließen zu lassen
shape-padding
shape-padding soll zukünftig den inneren Abstand zwischen Text und Form festlegen wenn diese durch shape-inside erstellt wurde
shape-outside 
shape-outside  legt wie bereits beschrieben die äußere Form des Elements fest

Beispiele für CSS Shapes

In den folgenden Beispielen könnt ihr sehen, wie Text um verschiedene CSS Shapes fließt und wie die Eigenschaften eingesetzt werden können.

Beispiele anschauen 

Die umschließende Box und die Shapes könnt ihr mit dem Entwicklertool eures Browser sichtbar machen.

Links: Form ohne Shape. Rechts: Form mit elliptischem Shape

CSS Shapes in den Chrome Entwicklertools. Links: Form ohne Shape. Rechts: Form mit elliptischem Shape

circle()

Mit circle() wird ein Kreis gezeichnet. Der folgende Code erzeugt einen Kreis dessen Radius 50% von Breite und Höhe des Elements beträgt. Folglich ist er genau so groß wie das Element.

<div class="shape-circle"></div>
<p>umfließender Text … </p>
.shape-circle {
  width: 150px;
  height: 150px;
  background: url(circle.png) 0 0 no-repeat;
  shape-outside: circle(50%);
}

ellipse()

Mit ellipse() wird eine Ellipse erzeugt. Innerhalb der runden Klammern wird der Radius der X- und Y-Achse bestimmt. Zusätzlich kann mit dem Schlüsselwort at und darauf folgenden Koordinaten das Zentrum der Ellipse innerhalb der umschließenden Box verschoben werden. Diese Möglichkeit besteht auch für circle();

<div class="shape-ellipse"></div>
<p>umfließender Text … </p>
<div class="shape-ellipse2"></div>
<p>umfließender Text … </p>
.shape-ellipse {
  width: 250px;
  height: 150px;
  background: url(ellipse.png) 0 0 no-repeat;
  shape-outside: ellipse(125px 75px);
}

.shape-ellipse2 {
  width: 250px;
  height: 150px;
  background: url(ellipse.png) -125px 0 no-repeat;
  shape-outside: ellipse(125px 75px at 0% 50%);
}

inset()

Mit inset() kann eine rechteckige oder abgerundete Form erzeugt werden. Die vier Werte definieren jeweils den Abstand der vier Seiten des Rechtecks zum Rand der umschließenden Box. Mit einer zusätzlichen Pixelangabe und dem Schlüsslwort round könnt ihr die Ecken abrunden.

<div class="shape-inset"></div>
<p>umfließender Text … </p>
.shape-inset {
  width: 250px;
  height: 150px;
  background: url(inset.png) 0 0 no-repeat;
  shape-outside: inset(0px 0px 0px 0px round 50px);
}

polygon()

Mit polygon() könnt ihr im Prinzip jede Form erzeugen. Jedes Zahlen-Paar definiert die Position einer Ecke des Vielecks innerhalb der umschließenden Box. Der erste Wert verschiebt die Ecke nach rechts auf der X-Achse und der zweite nach unten auf der Y-Achse.

<div class="shape-polygon"></div>
<p>umfließender Text … </p>
.shape-polygon {
  width: 250px;
  height: 220px;
  background: url(polygon.png) 0 0 no-repeat;
 shape-outside: polygon(0 0, 163px 27px, 200px 100px, 200px 130px, 170px 180px, 110px 210px, 0 220px);
}

url()

Es ist auch möglich eine Form anhand eines Bildes zeichnen. Dieses muss einen Alphakanal enthalten (z. B. transparente Pixel) und aus derselben Quelle stammen (siehe auch CORS). Bei Webseiten, die aus lokal geöffneten Dateien generiert wurden, funktioniert url() nicht.

<img src='herz.png' class="shape-url" />
<p>umfließender Text … </p>
.shape-url {
  shape-margin: 20px;
  width: 250px;
  shape-outside: url('herz.png');
}

Browser-Support & Tools

shape-outside wird derzeit von Chrome und Opera unterstützt. Für Safari wird das Vendor-Prefix -webkit- benötigt. Wenn ihr CSS Shapes auf eurer Webseite nutzen wollt und alle Browser unterstützen möchtet, dann könnt ihr diesen Polyfill von Adobe nutzen. Den exakten Browsersupport entnehmt ihr bitte der Website caniuse.com

Wenn ihr euch die Arbeit mit Shapes erleichtern wollt, werft einen Blick auf den CSS Shape Editor für Chrome, oder auf unsere stetig wachsende Liste mit Web Tools.

Links / Quellen

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

Scrolling-Effekte: CSS-Klasse per JavaScript hinzufügen, wenn sich ein Element im Viewport befindet

$
0
0
scroll-effect-website

Scrolling-Effekte sind ein beliebtes Gestaltungsmittel auf modernen Websites. Sinnvoll eingesetzt können Sie dazu beitragen, dass eine Website gleichermaßen erfolgreich als auch ästhetisch ansprechend ist. In diesem Beitrag findet ihr ein JavaScript-Snippet, mit dem Elemente eine CSS-Klasse erhalten, sobald Sie sich im Viewport befinden. Die Klasse kann optional wieder entfernt werden, sobald sich das Element nicht mehr vollständig im Viewport befindet.

Das JavaScript für den Scrolling-Effekt

Das folgende JavaScript fügt einem Element mit der CSS-Klasse .mein-element zusätzlich die Klasse .visible hinzu, wenn das Element vollständig im Viewport sichtbar ist. Die else-Bedingung innerhalb des JavaScripts kann entfernt werden, um die CSS-Klasse nur hinzuzufügen, aber nicht wieder zu entfernen.

Beispiel anschauen

<div class="mein-element"></div>
<div class="mein-element"></div>
 …
<div class="mein-element"></div>
function isElementInViewport(element) {
 var rect = element.getBoundingClientRect();
 return (
  rect.top >= 0 &&
  rect.left >= 0 &&
  rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
 rect.right <= (window.innerWidth || document.documentElement.clientWidth)
 );
}

var elements = document.querySelectorAll(".mein-element");
 
function callbackFunc() {
 for (var i = 0; i < elements.length; i++) {
  if (isElementInViewport(elements[i])) {
 elements[i].classList.add("visible");
}

 /* Else-Bedinung entfernen, um .visible nicht wieder zu löschen, wenn das Element den Viewport verlässt. */
  else { 
   elements[i].classList.remove("visible");
  }
 }
}
 
window.addEventListener("load", callbackFunc);
window.addEventListener("scroll", callbackFunc);
.mein-element {
  background:red;
  height:50vh;
  max-width: 500px;
  margin:0 auto;
  margin-bottom:2em;
}

.visible {
  background: lime;
}

Elemente beim Scrollen einfaden

Mit ein wenig CSS kann nun sehr einfach ein Fade-In-Effekt hergestellt werden

Beispiel anschauen

.mein-element {
  opacity: 0;
  transition: opacity .5s ease-in-out;
}


.visible {
  opacity: 1;
}

Elemente abwechselnd von links und rechts einfahren lassen

Eine geringe Anpassung am CSS-Code lässt die Elemente abwechselnd von links und rechts einfahren und einfaden.

Beispiel anschauen

.mein-element {
  opacity: 0;
  transition: all .25s ease-in-out;
}

.mein-element:nth-of-type(odd) {
  transform: translateX(-90%);
}

.mein-element:nth-of-type(even) {
  transform: translateX(90%);
}

.mein-element.visible {
  transform:translateX(0);
  opacity: 1;
}

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

Getippter Text mit CSS-Animationen

$
0
0
typing-css

Wenn der Eindruck erweckt werden soll, als würde ein Text getippt, wird häufig auf JavaScript zurückgegriffen. Wir haben selbst einige Tools zu diesem Zweck zusammengetragen. Doch der Effekt lässt sich auch mit einer CSS Keyframe-Animation erstellen. In diesem Beitrag zeigen wir wie es geht und was sich dennoch mit JavaScript optimieren lässt.

Die ch-Einheit und der Monospace-Font

Die Einheit ch definiert in CSS eine Breite, die der Null (0) in der gewählten Schriftart entspricht. Bei einem Monospace-Font sind alle Buchstaben gleich breit. Das machen wir uns zu nutze, indem wir die Länge des Textes von der Breite 0 auf die Breite 48ch animieren. Die 48 kommt hier zustande, da der Text des folgenden Beispiels eine Länge von 48 Zeichen umfasst.

steps()

In einer CSS-Keyframe-Animation kann die timing-function in steps() angegeben werden. Die steps()-Funktion legt fest, wie viele Abstufungen zwischen zwei Schlüsselbildern erzeugt werden sollen. Wenn wir die Anzahl der steps() mit der Anzahl der Buchstaben (48 in unserem Beispiel) gleich setzen, und gleichzeitig die Breite des Textes von 0 auf 48ch animieren, erscheinen die Buchstaben einzeln nacheinander.

white-space: no-wrap;

Wenn der Text aus mehreren Wörtern besteht, bricht die Animation am Leerzeichen ab. Nach dem Leerzeichen werden dann immer ganze Wörter eingeblendet, nicht mehr einzelne Buchstaben, wie eigentlich gewünscht. Mit Hilfe von white-space: no-wrap; beheben wir das Problem.

<h1 class="animated-text">Danke für deinen Besuch auf kulturbanause.de =:)</h1>
.animated-text {
 font-family: monospace;
 overflow: hidden;
 height:1.1em;
 word-wrap: break-word;
 white-space: nowrap;
 animation: typing 4s steps(48) forwards;
}

@keyframes typing {
  from { 
    width: 0;
  }

  to { 
    width: 48ch;
  }
}

Beispiel anschauen

Animation mit JavaScript vereinfachen

Etwas lästig an der oben beschriebenen puren CSS-Variante ist, dass die Anzahl der Buchstaben (48) manuell zwei Mal im Code notiert werden muss: Einmal innerhalb der animation-Eigenschaft und einmal innerhalb der @keyframes.

Mit ein wenig JavaScript (jQuery) können wir Anzahl der Zeichen innerhalb des Selektors .animated-text automatisch auslesen.

var character_count = $('.animated-text').text().length;

Anschließend bauen wir die Zeichenzahl innerhalb der animation-Eigenschaft wieder ein, und ergänzen den Selektor .animated-text entsprechend.

$('.animated-text').css('animation', 'typing 4s steps(' + character_count + ') forwards').css('font-family', 'monospace');

Die @keyframes statten wir ebenfalls mit der ausgelesenen Zahl aus und fügen im <head> einen Style-Abschnitt ein, der die @keyframes-Regel beinhaltet.

$('<style>@keyframes typing {from {width: 0; } to {width: ' + character_count + 'ch; } }</style>').appendTo('head');

 

Beispiel anschauen

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

Textmasken mit CSS erstellen

$
0
0
css-text-maske

Textmasken erfreuen sich im Grafik-Design – insbesondere im Print-Design – größter Beliebtheit. Leider war es mit Webtechnologien lange Zeit kaum möglich eine Textmaske herzustellen, bei der der Text als Reintext im HTML-Code steht. Aber gerade das ist wichtig, damit der Text geändert und übersetzt, sowie von Suchmaschinen und Screenreadern ausgelesen werden kann. In diesem Beitrag zeigen wir, wie ihr mit Hilfe von CSS Blend Modes eine semantisch korrekte Textmaske erstellt.

Das Grundprinzip verstehen

Die Textmaske besteht aus zwei Elementen: Dem Text selbst und einem Element, dass diesen Text überlagert und den Inhalt der Maske bereitstellt. Im Idealfall ist dieses Überlagerungselement ein CSS Pseudoelement.

Mit Hilfe eines CSS Blend Modes wird nun das Element mit dem Text verrechnet. Einen detaillierten Beitrag zu CSS Blend Modes findet ihr hier. Wenn der Hintergrund der Textmaske weiß sein soll, dann benötigt ihr schwarzen Text und den Blendmodus »screen« (In Photoshop »Negativ Multiplizieren«). Wenn der Hintergrund der Textmaske schwarz ist, benötigt ihr weißen Text und den Blendmodus »multiply« (In Photoshop »Multiplizieren«).

css-text-mask

Schwarzer Text auf weißem Grund wird mit einem farbigen Verlauf im Blendmodus »screen« überlagert, um den Verlauf auf den Text zu begrenzen

 

Text mit Farbverlauf weißem Grund

Der folgende CSS-Code ist notwendig, um eine Textmaske auf weißem Grund zu erzeugen. Der Blendmodus »screen« sorgt dafür, dass alle Pixel des Überlagerungselements sichtbar sind, die vor schwarzen Pixeln platziert wurden. Alles was vor weißen Pixeln positioniert wurde ist unsichtbar. Graue Pixel sorgen für Halbtransparenzen.

Beispiel anschauen

<h1>kulturbanause.de</h1>
h1 {
 position: relative;
 color:black;
}

h1:before {
 position: absolute;
 top:0;
 left:0;
 right:0;
 bottom:0;
 content: '';
 background:linear-gradient(45deg, gold, deeppink);
 mix-blend-mode:screen;
}

Text mit Farbverlauf auf schwarzem Grund

Der folgende CSS-Code erzeugt eine Textmaske auf schwarzem Grund. Hier ist es genau umgekehrt. Der Modus »multiply« sorgt dafür, dass nur die Pixel des Überlagerungselements sichtbar sind, die vor weißen Pixeln positioniert werden. Alles was vor schwarz steht ist unsichtbar.

Beispiel anschauen

<h1>kulturbanause.de</h1>
html {
 background:black;
}

h1 {
 position: relative;
 color:white;
}

h1:before {
 position: absolute;
 top:0;
 left:0;
 right:0;
 bottom:0;
 content: '';
 background:linear-gradient(45deg, gold, deeppink);
 mix-blend-mode:multiply;
}

Textmaske aus Bild

Die bisherigen Beispiele arbeiten mit einem Verlauf. Selbstverständlich kann auch ein Bild oder ein Video innerhalb des Textes dargestellt werden.

Beispiel anschauen

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

Webdesign-Trends 2017

$
0
0

Die Entwicklungen im Webdesign stehen nie still - daher haben wir den Jahreswechsel genutzt, um über die Webdesign- und -development-Trends 2017 nachzudenken. Wir möchten mit diesem Beitrag übrigens auf die zahlreichen Anfragen von Lesern dieses Blogs reagieren, die uns darum gebeten haben, einen Artikel zum Thema »Webdesign-Trends 2017« zu veröffentlichen. Wir danken euch sehr für den Besuch unserer Website im vergangen Jahr, euer Feedback und eure Anregungen, und wünschen euch ein großartiges Jahr 2017!

Wie Webdesign-Trends entstehen

Trends im Webdesign sind immer eine Mischung aus Trends in den Bereichen Design, Technologie und Workflow bzw. Marketing. Meistens beeinflussen die technischen Möglichkeiten (z. B. neue CSS-Eigenschaften) auch stark die visuellen Trends. Vor Jahren waren beispielsweise abgerundete Ecken plötzlich beliebt, weil die CSS-Eigenschaft für border-radius neu war. Webdesigner, die diese neue Technologie einsetzten, erschufen ein damals modernes Layout und lösten den Trend somit aus. Auf diesen Zug sprangen andere Designer auf - kurz danach sah man überall abgerundete Ecken und das Feature war »Mainstream«. Eine ähnliche Entwicklung gab es in den letzten Jahren beispielsweise auch beim Parallax-Effekt. Der Webdesign-Trend ist auf seinem Höhepunkt angekommen, wenn Profis sich am Effekt bereits satt gesehen haben, Kunden aber unbedingt genau diesen Stil wünschen. Wenn der Trend seinen Zenit überschritten hat, erfolgt häufig ein krasser Gegentrend. Der Skeomorphismus wurde vom Flat Design abgelöst, abgerundete Ecken vom Metro UI usw.

Abgesehen von den technischen Möglichkeiten beeinflussen auch Veränderungen im Workflow das Erscheinungsbild von Websites. Auch diesen Effekt bekommen wir in den letzten Jahren teils »schmerzhaft« vor Augen geführt. Der schleichende Wechsel von Designern zu Frontend-Developern sowie der massive Einsatz von Themes, Bibliotheken und Frameworks führt zu einem Einheitslook im Web, der nicht nur von Design-Kollegen sondern auch von Kunden zunehmend kritisiert wird.

Der Webdesign-Einheitslook im Jahr 2016

Der Einheitslook der Jahre 2015 und 2016 wird meiner Ansicht nach vor allem dadurch ausgelöst, dass klassische Webdesigner aus dem Workflow verdrängt wurden und Frontend-Developer das Feld übernommen haben. Der Frontend-Developer hat gegenüber dem klassischen Webdesigner den Vorteil, dass er nicht nur ein Gespür für Ästhetik hat, sondern auch in der Lage ist, seine Ideen technisch mit HTML, CSS und JavaScript umzusetzen. Allerdings hat er auch Defizite: Meiner Erfahrung nach ist der Frontendler immer eher ein Techniker als ein Designer. Er kann zwar sehr gekonnt Farben, Iconsets, Grids und Inhalte zu einem visuell ansprechenden Ergebnis kombinieren, doch er entwickelt nur selten Farbset, Icons, Illustrationen oder Gestaltungsraster selbst. Um es an einem Beispiel festzumachen: Der Designer zeichnet ein neues Icon-Set; der Frontend-Developer nutzt eher fertige Icons in Form einer Icon-Bibliothek. Diese Veränderung im Workflow wird letztendlich im Layout sichtbar.

Soweit ein paar einleitende Worte zum Thema Webdesign-Trends ganz allgemein. In diesem Beitrag versuchen wir zu erahnen, was in diesem Jahr Trend im Webdesign werden wird.

»Nearly« Flat Design

Der Flat Design-Trend der letzten Jahre hat bewiesen, dass Flat Design zwar schön anzusehen ist, aber sehr schnell langweilig wird und zu Usability-Problemen führen kann, da der Anwender aufgrund fehlender Plastizität nicht mehr erkennt was angeklickt werden soll. Insbesondere im E-Commerce ist die Conversion Rate zahlreicher Websites nach dem Relaunch im Flat Look in den Keller gerauscht. Aus diesem Grund wurde bereits vor über zwei Jahren über »Nearly Flat« oder »Flat 2.0« berichtet. Hierbei ist von einer Weiterentwicklung des Flat Designs die Rede, bei dem zwar nach wie vor im Flat Look gearbeitet wird, aber wieder Schatten und Verläufe eingesetzt werden um Interaktionen zu kennzeichnen. Google hat mit dem Material Design ein Paradebeispiel für »Nearly Flat« geliefert.

Ich glaube, dass Websites 2017 wieder etwas plastischer werden, ohne dass wir dabei in das Zeitalter des Skeomophismus zurückfallen.

Nearly Flat Design, Animation und ein modernes Farbkonzept – stripe.com/radar

 

Illustrationen & mehrfarbige Icons

Einfarbig überlagerte Stock Images, monochrome Icons und Illustrationen im Flat Look haben maßgeblich zum Einheitslook der letzten Jahre beigetragen. 2017 wird es wieder individueller. Wir werden mehr Illustrationen sehen, die einen charakteristischen Stil haben. Auch Icons werden wieder mehrfarbig, ohne dass der flächige Look verloren geht.

Modernes Webdesign und charakteristisches Design – mojobar.co.uk

Animationen

Illustrationen können dank SVG-Technologie unkompliziert animiert werden. Das werden wir 2017 verstärkt zu sehen bekommen. Ob animierte Hintergründe, Interaktionen bei Icons, Infografiken oder illustratives Schmuckelement. Animierte Illustrationen werden in qualitativ hochwertigen Projekten stark zunehmen.

Übrigens: Der Ammonit ist das Key-Visual von kulturbanause, da er den perfekten goldenen Schnitt in der Natur widerspiegelt und somit stellvertretend für gutes Design steht. Firefox-User hier her.

Im Detailbereich werden sog. Mikroanimationen zunehmen und starken Einfluss auf die Gestaltung von Formularfeldern, Buttons, Navigationsleisten und anderen interaktiven Elementen nehmen. Das Ziel von Mikroanimationen besteht darin, durch dezente Effekte die Benutzerfreundlichkeit und die User Experience zu erhöhen.

Mikroanimation bei der Formulareingabe

Videos

Ob als animierter Hintergrund für den Header einer Website oder informativ eingesetzt im Inhaltsbereich: Videos werden großen Einfluss auf die Gestaltung haben.

Viel Bewegtbild bei conference.awwwards.com

 

Buntere Farben und Verläufe

Die Farben der letzten Jahre waren bunt aber gebrochen. Nun wird es wieder gesättigter, ohne dass wir in den Neon-Look des Web 2.0-Zeitalters zurückfallen.

Auch Verläufe sind wieder wichtig: Im Skeomorphismus wurden Verläufe inflationär eingesetzt um Plastizität zu erzeugen. Im Flat Design waren sie verboten. Nun sind sie wieder da und sorgen für Leuchteffekte und subtile Plastizität.

Organische Formen, kräftige Farben und Verläufe bei 2016.cssconf.com

CSS Grids

Die CSS Grids-Layout-Technik wird 2017 einen praxistauglichen Browser-Support erreichen und wir werden zunehmend Layouts sehen, die auf diesem Layoutmodell basieren. Mit CSS Grids ist eine verschachtelte, abstrakte und komplexe Website-Architektur möglich - wir dürfen uns also auf individuellere Layouts freuen.

Comic-Layout mit CSS Grids: http://codepen.io/tutsplus/pen/pNgZpj

Performance

Der Stellenwert von Performance hat in den letzten Jahren stetig zugenommen. Geschwindigkeit wird heute von vielem Agenturen als Design-Aspekt begriffen und es ist bekannt, dass eine Performance-Optimierung am Ende des Projekts nur begrenzt funktioniert. Der Trend hin zu Websites, bei denen die Performance als wesentliches Element des Workflows verstanden wurde, wird sich auch 2017 fortsetzen. Wir werden daher sehen, dass Designer ihre gestalterischen Entscheidungen auch auf Grundlage von Performance-Werten treffen.

Modulare Denkweise

Im Responsive Design wird das Layout u. a. mit Hilfe von Media Queries angepasst. Das Problem an Media Queries ist, dass sie auf die Größe des Viewports reagieren. Besser wäre es, wenn Breakpoints nicht in Abhängigkeit zur Viewportgröße gesetzt würden, sondern in Abhängigkeit vom Platz, den die jeweilige Komponente zur Verfügung hat. Die sog. »Element Queries« sind ein Ansatz in diese Richtung, der aktuell mittels JavaScript implementiert werden muss. Wichtiger als die technische Umsetzung von Element Queries ist mir jedoch die Denkweise in Komponenten. Designer haben lange Zeit in Geräteklassen und Seitentypen gedacht. Langsam etabliert sich auch in der Design-Szene ein modularer Ansatz.

Größere Webdesign-Projekte werden häufig in Frontend Styleguides dokumentiert, die alle Komponenten der Website mit Text, Demo und Code-Snippet beschreiben. Der Aufbau eines solchen Styleguides ähnelt stark der Dokumentation eines Frameworks wie Bootstrap.

Salesforce-Styleguide – lightningdesignsystem.com

Wir haben bereits im letzten Jahr bemerkt, dass Kunden verstärkt nach modularen Ansätzen wie Atomic Design fragen und von sich aus die Dokumentation der Website in Form eines Frontend-Styleguides wünschen. Dieser Trend wird sich 2017 voraussichtlich spürbar verstärken.

Content und Design im Einklang

Inhalte von Websites werden immer wichtiger und das Layout hat die Aufgabe diese Inhalte bestmöglich zu vermitteln. Inhalte und Layout werden daher immer häufiger gemeinsam entwickelt um das bestmögliche Ergebnis zu erreichen. Ob Storytelling mit Hilfe von Web-Animationen oder Online-Comic dank CSS Grids. Wir werden hier voraussichtlich sehr interessante Projekte sehen.

Moderne Farben, eine individuelle Grafik, sauber gesetzte Typo … riiotlabs.com

Negativ Trends

In den letzten Jahren hat die Qualität von Layouts im Bereich der Usability teils dramatisch abgenommen. Viele gestalterische Trends sehen zwar modern aus, erzeugen aber messbar schlechtere Produkte. Schlanke Schriften oder Icons die nur noch aus dünnen Outlines bestehen sehen beispielsweise modern aus, sind für Menschen mit Sehschwäche aber schlecht erkennbar. Eine Hauptnavigation die am Desktop hinter einem Hamburger-Icon versteckt wird erzeugt zwar ein aufgeräumtes Layout im »Mobile First Look«, erschwert aber möglicherweise die Übersicht und reduziert die Klicks auf weitere Unterseiten.

Ich würde mir für 2017 wünschen, dass Designer wieder mehr über ein Stilmittel nachdenken bevor sie es verwenden.

Beispiel von zu geringem Kontrast

Der Kontrast zwischen Text und Hintergrundfarbe ist zu gering. Das Ergebnis ist ein »Fail« entsprechend der Web Content Accessibility Guidelines

 

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.


SVG-Pfade mit CSS animieren (Path-Morphing/Shape-Morphing)

$
0
0

SVG-Animationen mit Hilfe von CSS Keyframe-Animationen oder Transitions haben in der letzten Jahren stark an Beliebtheit gewonnen. Das Ein- und Ausblenden von Objekten, Drehungen, Verschiebungen und sonstige Transformationen stellen kein Problem dar. Doch für Morphing musste man auf Technologien wie SMIL oder JavaScript zurück greifen. Nun ist Morphing auch mit CSS möglich.

Grundsätzliche Funktionsweise

In einer SVG-Grafik werden die einzelnen Punkte eines Pfads im d-Attribut angegeben. Mit der d-Eigenschaft von CSS ist es möglich diese Pfadpunkte zu überschreiben. Sofern die Anzahl der Punkte gleich bleibt, kann beispielsweise mit Hilfe einer Transition ein interessanter Mouse-Over-Effekt erzeugt werden. Mit Hilfe von CSS Keyframe-Animationen sind selbstablaufende Animationen möglich.

Die Syntax sieht folgendermaßen aus:

svg path {
 d: path("M134.1,0C132.9, … 91.3L134.1,0z");
}

SVG-Path-Morphing beim Mouse-Over

Das folgende Beispiel zeigt die Pfad-Transformation anhand eines Mouse-Over-Effekts.

<svg viewBox="0 0 100 100">
 <path d="M23,9C8.1,18.9-4.2,39.3,1.3,53.6c10.4,27,78.8,18.3,79.5,13.3c0.5-3.5-32.2-4.5-36.7-20.5C39.5,29.9,68.9,13.2,64,4.2
 C60.2-2.7,38.3-1.1,23,9z"/>
</svg>
svg {
  border:2px solid black;
  margin:2em;
  width:400px;
  fill:deeppink;
}

svg path {
  transition:.2s all ease-in-out;
}

svg:hover path {
  d: path("M3.4,9c-14.9,9.9,23.4,18,28.9,32.3c10.4,27,28.3,30.5,28.9,25.5c0.5-3.5,31.7-22.1,27.2-38.1c-4.6-16.4-39.1-15.5-44-24.5,C40.6-2.7,18.7-1.1,3.4,9z"); 
  fill: lime;
}

Beispiel anschauen

Browser-Support

Die path()-Funktion von CSS ist aktuell experimentell und funktioniert zum Veröffentlichungszeitpunkt dieses Beitrags nur in Chrome. Die Funktion ist Teil der Motion Path-Spezifikation von CSS.

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

CSS pointer-events – Click, Tap, Mouse-Over & Co. ignorieren

$
0
0

In komplexen Benutzeroberflächen kann es vorkommen, dass Elemente einander überlagern und die Interaktion mit verdeckten Schaltflächen erschwert wird. Mit der CSS-Eigenschaft pointer-events könnt ihr bewirken, dass Elemente vom Cursor ignoriert werden – ihr also durch ein Element hindurch klicken könnt.

Funktionsweise der CSS-Eigenschaft pointer-events

Mit Hilfe der CSS-Eigenschaft pointer-events könnt ihr steuern wie ein Element auf click- oder tap-Events reagiert. Die folgende Werte werden am häufigsten benötigt:

  • none:
    Jegliche click-, scroll-  und hover-Events werden für das entsprechende Element abgeschaltet. Dazu gehören auch JavaScript gesteuerte click- oder tap-Events.
  • auto: 
    pointer-events: auto; stellt das Standardverhalten wieder her. Dies kann sehr hilfreich sein, um den Effekt von pointer-events:none; für verschachtelte Elemente wieder aufzuheben.

Neben diesen Werten existieren noch die Werte visiblePainted, visibleFill, visibleStroke, visibleStroke, painted, fill, stroke und all, die nur zur Steuerung von SVG benutzt werden.

Beispiel 1: Download von Bildern erschweren

Ihr könnt verhindern, dass Bilder via Drag and Drop oder Rechtsklick > speichern unter vom Benutzer kopiert werden können. Dazu gebt ihr Bildern einfach die CSS-Eigenschaft pointer-events: none;. Fertig. Über den Quellcode können die Bilder natürlich trotzdem heruntergeladen werden.

img { pointer-events: none; }

Beispiel 1 anschauen

Beispiel 2: Durch ein Overlay hindurch klicken

Ein Button wird von einem anderen Element gewollt oder ungewollt überlagert. Das folgende Beispiel zeigt, wie der Button trotzdem geklickt werden kann.

Das Beispiel zeigt zwei Buttons die jeweils von einem Overlay überlagert werden. Es ist nicht möglich den Button unter dem roten Overlay anzuklicken, da der Browser einen Klick auf das darüber liegende Overlay – und nicht auf den Button – registriert.

Der Button unter dem blauen Overlay wiederum ist problemlos zu erreichen, obwohl der Aufbau identisch ist. Hier haben wir auf das Overlay – in unserem Beispiel mit der CSS-Klasse .permeable – die Eigenschaft pointer-events: none; angewandt. Das Overlay wird vom Cursor ignoriert. Dadurch können hover- und click-Events auf den darunter liegenden Button registriert werden.

.permeable { pointer-events: none; }

Beispiel 2 anschauen

Browser-Support

Für die wichtigsten Werte none und auto ist der Browser-Support generell gut. pointer-events: none; wird von allen aktuellen Browsern, mit Ausnahme von Opera Mini, unterstützt. Microsoft unterstützt die Eigenschaft ab dem IE11.

Das Abschalten von scroll-Events mit pointer-events: none; funktioniert allerdings nicht in Firefox. Für IE11 und Edge müssen links auf display: block; oder inline-block gesetzt werden, um click-Events zu verhindern.

Den genauen Browser-Support entnehmt ihr bitte der Website caniuse.com.

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

SVG-Grafiken in Websites/HTML-Seiten einbinden

$
0
0

Das SVG-Format erfreut sich aufgrund kleiner Dateigrößen, verlustfreier Skalierung und Animationsmöglichkeiten großer Beliebtheit. Doch wie kann man SVGs am besten in HTML-Dokumente bzw. Websites eingefügen? In diesem Beitrag beschreiben wir die verschiedenen Möglichkeiten jeweils mit ihren Vor- und Nachteilen.

SVG inline einbinden

Wenn ihr SVG-Grafiken exportiert, steht euch das Dateiformat *.svg oder der SVG-Code zur Verfügung. Der SVG-Code kann direkt in den HTML-Code der Website eingebettet werden.

<svg>
  <!-- hier folgt der Code -->
</svg>

Vorteile

  • Es wird keine externe Datei geladen
  • Animationen und Manipulationen mittels CSS oder JavaScript sind problemlos möglich
  • Verlinkungen innerhalb der SVG sind möglich

Nachteile

  • Der HTML-Code wird aufgebläht und ist unübersichtlich
  • Fehler im SVG-Code haben ggf. Auswirkungen auf die Website

Einbindung als image

Wenn die SVG-Grafik als Datei vorliegt, kann sie auch mittels <img>-Tag in die Website eingebunden werden.

<img src="kulturbanause-logo.svg">

Vorteile

  • Unkomplizierte und bekannte Handhabung
  • Breakpoints in der SVG funktionieren

Nachteile

  • Keine Möglichkeit der Manipulation mittels JavaScript oder CSS außerhalb der Datei
  • JavaScript und Links funktionieren nicht mehr
  • Animationen werden nicht in allen Browsern ausgeführt

Einbindung als background-image

Wie alle anderen Grafikformate auch, sind SVGs als CSS Hintergrundbild möglich.

.site-logo {
  height:200px;
  width:200px;
  background:url(kulturbanause-logo.svg) 50% 50% no-repeat;
}

Vorteile

  • Bekannte Handhabung

Nachteile

  • Keine Möglichkeit der Manipulation mittels JavaScript oder CSS außerhalb der Datei
  • JavaScript und Links funktionieren nicht mehr

Einbindung als object

Mittels <object>-Tag von HTML kann SVG ebenfalls integriert werden. Der Vorteil dieser Methode besteht darin, dass ein Fallback gebaut werden kann.

<object type="image/svg+xml" data="kulturbanause-logo.svg">
  <!-- fallback -->
  <img src="kulturbanause-logo.png" alt="">
</object>

Vorteile

  • Automatischer Fallback möglich
  • Links funktionieren in der SVG
  • JavaScript in der SVG funktioniert

Nachteile

  • Möglicherweise komplizierte Integration im CMS, da der <object>-Tag oft nicht unterstützt wird

Einbindung als embed

Auch der <embed>-Tag von HTML kann zur Integration von SVG verwendet werden.

<embed src="kulturbanause.svg" height="200" width="400"> 

Einbindung als iframe

Das <iframe>-Element von HTML kann ebenfalls genutzt werden um SVGs in die Website zu integrieren.

<iframe height="200" width="400" src="kulturbanause.svg" scrolling="no">
 <!-- fallback -->
 <img src="kulturbanause.png" width="400" height="200" alt />
</iframe>

Vorteile

  • Links in der SVG funktionieren
  • JavaScript in der SVG funktioniert
  • Domainübergreifend einsetzbar

Nachteile

  • Responsive Design und <iframe> sind aufwändig

Kodierung in Base64

SVG-Grafiken können auch in Base64 kodiert in eine Website integriert werden. Dabei wird die Datei mit Hilfe eines Tools in eine DataUri umgewandelt. Diese Zeichenkette kann anschließend wie eine normale SVG in die HTML-Seite integriert werden. Es handelt sich hierbei also nicht um eine zusätzliche Art der Einbindung, sondern um eine alternative »Darstellung« für den Bildpfad. Die Möglichkeiten der Animation und Interaktivität sind folglich abhängig von der gewählten Art der Einbindung.

<img src="data:image/svg+xml;base64,PHN2ZyB4bW … c3ZnPg==" />

Vorteile

  • Kein zusätzlicher HTTP-Request notwendig

Nachteile

  • Es entstehen etwas größere Dateien
  • Der Quellcode wird ggf. unübersichtlich

Browser-Support

Browser SVG als img SVG als background-image Inline SVG
Safari (alle Versionen) ja ja 5+
Chrome (alle Versionen) ja ja ja
Firefox (alle Versionen) ja ja ja
Opera (alle Versionen) ja ja 11.6+
Internet Explorer 9+ 9+ 9+
Alle iOS Browser ja ja 5.1+
Android Browser (bevor Chrome der standard Android Browser wurde) 3+ 3+ 3+
Chrome für Android ja ja ja
Firefox für Android ja ja ja
Opera Mini ja ja nein
Opera Mobile ja ja 12+
IE Mobile ja ja ja

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

Die Filter-Funktion von CSS – Filter nur auf Background-Images anwenden

$
0
0

Die Filter-Effekte von CSS wirken sich normalerweise auf das gesamte Element aus. Wendet man beispielsweise den Weichzeichnungsfilter an, werden sowohl die Textinhalte, als auch Konturen, Hintergrundbilder etc. unscharf. Mit Hilfe der Filter-Funktion von CSS kann ein Filter nur auf das Hintergrundbild angewendet werden.

Übersicht CSS Filter-Effekte

In CSS existieren zahlreiche Filter-Effekte, die allesamt in Kombination mit der Filter-Funktion eingesetzt werden können:

  • blur()
  • brightness()
  • contrast()
  • drop-shadow()
  • grayscale()
  • hue-rotate()
  • invert()
  • opacity()
  • saturate()
  • sepia()

Eine detaillierte Übersicht haben wir in einem eigenen Artikel zusammengestellt: CSS Filter-Effekte

Handhabung der CSS Filter-Funktion

Wie alle CSS-Funktionen wird auch die Filter-Funktion mit runden Klammern geschrieben. Innerhalb der Eigenschaft background wird die Funktion notiert und erwartet dann eine URL sowie mindestens einen Filter.

Der Grundaufbau sieht so aus:

div {
  background: filter(url(<BILD>), <FILTER>, <FILTER2>);
}

Das folgende Beispiel zeichnet das Hintergrundbild weich:

div {
  background: filter(url(image.jpg), blur(8px));
}

Beispiel anschauen

Browser-Support

Die Technik ist experimentell und funktioniert zum Veröffentlichungszeitpunkt dieses Beitrags nur in Safari. Den detaillierten Browser-Support findet ihr auf caniuse.com.

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

Die CSS element()-Funktion – Eine ID als Hintergrundbild verwenden

$
0
0

In CSS ist es möglich einem Element mittels background-image-Eigenschaft ein Hintergrundbild zuzuweisen. Dieses Bild kann in allen webkompatiblen Dateiformaten (z. B. *.jpg, *.svg, *.png) eingebunden werden. Darüber hinaus ist die Umwandlung in Base64 möglich und häufig sinnvoll. Mit Hilfe der element()-Funktion von CSS kann die ID eines anderen Elements als Hintergrundbild angegeben werden.

Syntax und Funktionsweise der element()-Funktion

Wie alle CSS-Funktionen wird auch die element()-Funktion mit runden Klammern geschrieben. Innerhalb der runden Klammern wird die gewünschte ID mit vorangestellter Raute angegeben:

.element {
  background: element(#id);
}

Beispiel

Das folgende Beispiel ist mit zwei <div>-Elementen aufgebaut. Der erste <div> besitzt die ID #source. Dieses Element dient als Quelle. Der zweite <div> mit der ID #target lädt mittels element()-Funktion den Inhalt des ersten <div> als Hintergrund. Da der zweite <div> größer ist, wird das Hintergrundbild gekachelt.

Damit man sehen kann, dass der Hintergrund in Echtzeit gerendert wird, haben wir dem ersten <div> das HTML-Attribut contenteditable mitgegeben. Der Inhalt kann daher editiert werden und Änderungen sind direkt im gekachelten Hintergrund sichtbar.

<div id="source" contenteditable>
Dieser Text kann editiert werden.
</div>

<div id="target"></div>

Der CSS-Code sieht wie folgt aus. Für Firefox ist ein Vendor-Präfix verwendet worden.

#source {
  height:100px;
  width:200px;
  background:linear-gradient(135deg, #024557, #61717e);
  padding:1em;
  color:white;
}

#target {
  height:250px;
  width:100%;
  background: -moz-element(#source);
  background: element(#source);
}

Beispiel anschauen

Browser-Support

Der Browser-Support für die element()-Funkion ist zum Veröffentlichungszeitpunkt dieses Beitrags auf Firefox beschränkt. Obwohl die Funktion bereits seit 2011 existiert, hat kein anderer Browser-Hersteller bisher reagiert. Den aktuellen Browser-Support findet ihr auf caniuse.com.

Links / Quellen

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

Animiertes Hamburger-Icon mit HTML, CSS und JavaScript

$
0
0

Das Hamburger-Icon hat sich als Kennzeichnung für Menüs und Navigationselemente durchgesetzt. Auch wenn das Icon kritisiert wird und nicht in allen Anwendungsfällen gut funktioniert ist es doch in den meisten responsiven Websites anzutreffen. Besonders beliebt sind animierte Hamburger-Icons die per Klick in ein Schließen-Icon überführt werden. In diesem Beitrag archivieren wir ein Code-Snippet das dieses Verhalten herstellt.

HTML-Grundaufbau des Hamburger Icons

Das Hamburger Icon besteht aus einem Container-<div>und einem darin enthaltenen <div>. Der enthaltene <div> erzeugt später die drei Striche für das Icon.

<div id="hamburger" class="hamburger-icon-container">
  <span class="hamburger-icon"></span>
</div>

CSS-Code für das Basis-Styling des Hamburger-Icons

Das Styling des Containers setzt sich aus Breite und Höhe, sowie aus der Farbe zusammen. In diesem Beispiel verwenden wir die CSS-Variable currentColor. Die Variable beinhalte immer automatisch den Farbwert der der color-Eigenschaft zugewiesen wurde. Anschließend weisen wir background und border den currentColor-Wert zu und können somit beide Farben über eine zentrale Position steuern. Damit die einzelnen Striche des Hamburger-Icons absolut positioniert werden können, erhält der Container zusätzlich eine relative Positionierung.
Die einzelnen Striche werden mit ::before und ::after realisiert. Dazu stylen wir den im Container enthaltenen <div> erst einmal wie gewünscht. Anschließend verschieben wir ::before und ::after nach oben und unten.

/* Basis Styling */

.hamburger-icon-container {
  color:red;
  height: 1.7em;
  width: 1.7em;
  position: relative;
  cursor: pointer;
  background: currentColor;
  border:10px solid currentColor;
  border-radius: 3px;
}

.hamburger-icon,
.hamburger-icon:before,
.hamburger-icon:after {
  content: '';
  position: absolute;
  height: 3px;
  width: 1.7em;
  background: white;
  transition: all .2s ease;
}

.hamburger-icon {
  top: 0.75em
}

.hamburger-icon:before {
  top: -0.55em
}

.hamburger-icon:after {
  top: 0.55em
}

CSS-Code für das Schließen-Icon

Wenn der Button geklickt wird, soll er in ein Schließen-Icons umgewandelt werden. Dazu färben wir den Hintergrund und die Rahmenfarbe des Containers um und positionieren ::before und ::after an der selben Stelle, da nur noch zwei Striche benötigt werden.

Der Übergang vom Hamburger- zum Schießen-Icon

Damit aus den zwei verbliebenen Strichen ein Plus-Icon wird, drehen wir das ::before-Element um 90° ein. Gleichzeitig wird der im Container enthaltene <div> um -135° gedreht, damit das Plus-Icon schräg steht und zum Close-Icon wird.

/* Darstellung wenn das Close-Icon angezeigt werden soll */

.hamburger-active .hamburger-icon-container {
  color:lime;
}

.hamburger-active .hamburger-icon {
  background: transparent;
  transform: rotate(-135deg)
}

.hamburger-active .hamburger-icon:before,
.hamburger-active .hamburger-icon:after {
  top: 0
}

.hamburger-active .hamburger-icon:before {
  transform: rotate(90deg)
}

JavaScript-Code für die Klick-Funktion

Der Wechsel vom Hamburger- zum Schließen-Icon wird mittels JavaScript realisiert. Per Klick tauschen wir dazu eine Klasse.

// Klick-Funktion für #hamburger hinzufügen
document.getElementById('hamburger').addEventListener('click', navStatus);

// Prüfen ob die Navigation geöffnet oder geschlossen ist
function navStatus() {
  if (document.body.classList.contains('hamburger-active')) {
   navClose();
 } 
 else {
   navOpen();
 }
}

// Wenn die Navi geschlossen wird, Klasse für »offen« entfernen
function navClose() {
  document.body.classList.remove('hamburger-active');
}

// Wenn die Navi geöffnet wird, Klasse für »geschlossen« entfernen
function navOpen() {
  document.body.classList.add('hamburger-active');
}

Beispiel anschauen

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

CSS backdrop-filter – Filter auf Objekte im Hintergrund anwenden

$
0
0

Mit Hilfe der CSS-Eigenschaft filter lassen sich zahlreiche interessante Effekte realisieren. Für die Eigenschaft backdrop-filter stehen die gleichen Effekte zur Verfügung, allerdings wirken sich die Filter nicht auf das Element selbst aus, sondern auf alles was optisch hinter dem Element liegt. Mit Backdrop Filtern ist es also beispielsweise möglich eine fixierte, halbtransparente Navigationsleiste zu erstellen, hinter der bei Scrollen alle Inhalte leicht unscharf dargestellt werden.

Übersicht CSS Filter-Effekte

In CSS existieren zahlreiche Filter-Effekte, die allesamt in Kombination mit der Eigenschaft backdrop-filter eingesetzt werden können:

  • blur()
  • brightness()
  • contrast()
  • drop-shadow()
  • grayscale()
  • hue-rotate()
  • invert()
  • opacity()
  • saturate()
  • sepia()

Eine detaillierte Übersicht haben wir in einem eigenen Artikel zusammengestellt: CSS Filter-Effekte

Funktionsweise des Backdrop-Filters

Die Funktionsweise ist denkbar einfach. Sobald ein Element auf der Website die Eigenschaft backdrop-filter erhält, wird der festgelegte Filter auf alle Objekte angewandt, die sich dahinter befinden. Sichtbar ist das natürlich nur, wenn das Element transparent oder halbtransparent ist.

nav {
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
}

Beispiel anschauen

Browser-Support

Zum Veröffentlichungszeitpunkt dieses Beitrags funktioniert die Eigenschaft in Safari mit Präfix und in Chrome und Opera sofern die Flag aktiviert ist. Eine detaillierte Übersicht findet ihr auf caniuse.com.

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.


SVG Browser-Support für Animationen und Interaktionen

$
0
0
SVG

Mit Hilfe der SVG-Technologie können interessante Interaktionen und Animationen auf einer Website realisiert werden. Leider ist der Browser-Support höchst unübersichtlich, denn ob etwas funktioniert oder nicht ist davon abhängig wie die SVG eingebunden wurde und welche Sprache (JavaScript, SMIL, CSS) zur Erzeugung der Animation verwendet wurde. Wir haben daher für die interne Nutzung eine Übersicht erstellt, die wir euch natürlich nicht vorenthalten wollen.

Kompatibilität von Animationen und Interaktionen in SVG

Die folgende Tabelle listet die für uns wichtigsten Kriterien im Zusammenhang mit SVG-Animationen und -Interaktionen auf. Wir freuen uns über Ergänzungen und Anmerkungen.

SVG Kompatibilitätstabelle anzeigen

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

Navigation beim Runterscrollen verstecken, beim Hochscrollen anzeigen

$
0
0

Fixierte Navigationsleisten, die sich horizontal über die volle Breite der Website erstrecken sind keine Seltenheit. Um den Blick des Anwenders auf den Inhalt zu lenken und gleichzeitig den wertvollen Platz auf dem Display bestmöglich ausnutzen zu können, wird die Navigation auch häufig beim runterscrollen versteckt und beim hochscrollen wieder angezeigt. Insbesondere sog. Onepager und Landingpages nutzen vermehrt den Effekt. In diesem Beitrag archivieren wir eine CSS/jQuery-Lösung um das Verhalten herzustellen.

HTML-Grundaufbau

Die HTML-Struktur besteht in unserem Beispiel lediglich aus einem leeren <nav>-Element.

<nav></nav>

Scroll-Richtung mit jQuery abfragen

Zunächst prüfen wir mit Hilfe von jQuery in welche Richtung der Anwender scrolled. Wenn er nach unten scrolled, wird dem <body> die Klasse down hinzugefügt. Wenn es nach oben geht wird die Klasse entfernt.

var lastScrollTop = 0;
$(window).scroll(function(event){
  var st = $(this).scrollTop();
  if (st > lastScrollTop){
    if (!$('body').hasClass('down')) {
      $('body').addClass('down');
    }
   } else {
     $('body').removeClass('down');
   }

   lastScrollTop = st;

   if ($(this).scrollTop() <= 0) {
     $('body').removeClass('down');
   };
});

Verstecken der Navigation mit CSS

Der CSS-Code ist ebenfalls recht übersichtlich. Die Navigation wird eingefärbt, oben im Browserfenster fixiert und über die volle Breite ausgedehnt. Zusätzlich erhält sie eine feste Höhe und eine Transition, damit sie später animiert aus dem Viewport fährt, sobald per JavaScript die Klasse hinzugefügt wird.

Sobald die Klasse down vorhanden ist, wird mit der CSS-Eigenschaft transform die Navigation um Ihre Höhe nach oben aus dem Viewport geschoben.

nav {
   height:100px;
   background:lime;
   position: fixed;
   top:0;
   right:0;
   left:0;
   transition: transform .25s .1s ease-in-out;
}

.down nav {
   transform: translate3d(0, -100px, 0); // um 100px nach oben verschieben
}

Beispiel anschauen

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

Responsive Sticky Footer

$
0
0

Wenn der Inhalt einer Website kürzer ist als der Viewport hoch ist, kommt es häufig zu der Fehldarstellung. Es entsteht ein Freiraum unter der Fußzeile, da diese sich an der Länge des Inhalts orientiert. Mit Hilfe eines sog. »Sticky Footers« wird die Fußzeile immer am Ende der Seite bzw. am unteren Ende des Viewports positioniert. In diesem Beitrag zeigen wir verschieden Lösungen.

Sticky Footer mit fester Höhe

Ein Sticky Footer mit fester Höhe ist sehr einfach umzusetzen: Dem Hauptinhalt erhält unten soviel Innenabstand, wie der Footer hoch ist. Anschließend verschiebt man den Footer um den negativen Wert seiner Höhe nach oben.

<!-- relevanter HTML-Code -->

<div class="site">
  <header></header>
  <main></main>
</div>

<footer></footer>
/* relevanter CSS-Code */

html, body {
 height: 100%;
}

.site {
 height: auto; 
 min-height: 100%;
}

main {
 padding-bottom:50px; /* Höhe des Footers */
} 

footer {
 height:50px;
 margin-top: -50px; /* Höhe des Footers */
}

Beispiel anschauen

Ändert sich die Höhe des Footers, versagen viele bekannte Lösungen inkl. der soeben gezeigten. Die folgenden Beispiele ermöglichen einen responsiven Sticky Footer mit flexibler Höhe.

Responsive Sticky Footer mit dem »CSS Table Layout«

Die Umsetzung eines »Sticky Footers« mit dem CSS Table Layout hat den großen Vorteil, dass diese Methode einen sehr hohen Browsersupport aufweist. Alle relevanten Browser bis hin zum Internet Explorer 8 können bei Verwendung dieser Technik abgedeckt werden.

Grundvoraussetzung für die Lösung ist, dass sowohl das <html>-Element sowie das <body>-Element eine Höhe von 100% besitzen. Dem <body> werden nun zusätzlich die Angaben width: 100%; display: table; und table-layout: fixed; zugewiesen. Hierdurch verhält sich der <body> wie eine HTML-Tabelle, die sich über die gesamte Breite des Viewports ausdehnt. Mit der Angabe table-layout: fixed; beugen wir einigen Fehldarstellungen vor, die durch das spätere Einpflegen von verschiedenen Inhalten im Inhaltsbereich auftreten könnten.

Im letzten Schritt bekommen alle zu berücksichtigenden Elemente die Angabe display: table-row;. Im Code-Beispiel handelt es sich bei diesem Elementen um das <header>-, <footer>- und <main>-Element. Alle Elemente haben eine flexible Höhe. Sollte der Inhalt die Seite nicht komplett ausfüllen, soll das <main>-Element soweit ausgedehnt werden, dass der Footer am unteren Rand des Viewports endet. Hierzu geben wir dem <main>-Element zusätzlich noch eine Höhe von 100%.

<!-- relevanter HTML-Code -->

<body>
  <header></header>
  <main></main>
  <footer></footer>
</body>
/* relevanter CSS-Code */

html {
  height: 100%;
}

body {
  height: 100%;
  width: 100%;
  display: table;
  table-layout: fixed;
}

header,
footer {
  display: table-row;
}

main {
  display: table-row;
  height: 100%;
}

Beispiel anschauen

Einen kleinen Nachteil gibt es bei dieser Technik jedoch auch. Durch die Angabe von display: table-row; können Elemente nicht mehr mit margin und padding ausgestattet werden. Abstände müssen demnach über die jeweiligen Kindelemente realisiert werden.

Responsive Sticky Footer mit Flexbox

Wie auch schon beim Tabellen Layout ist die Höhenangebe von 100% beim <html>- und <body>-Element Grundvoraussetzung. Mit display: flex; aktiviert ihr das Flexbox-Modell für den <body> und seine direkten Kindelemente und mit flex-direktion: column; ordnet ihr die Elemente untereinander an.
Anschließend sagt ihr dem <main>-Element mit flex: 1;, dass es sich über den kompletten verfügbaren Bereich ausdehnen soll.

Das Flexbox-Modell hat einen sehr guten Browsersupport und funktioniert in allen modernen Browsern. Im Vergleich zur Umsetzung mit dem Tabellen Layout spart ihr hier einige Zeilen Code und könnt Abstände mit margin und padding direkt auf die Elemente anwenden. Wollt ihr eure Website jedoch auch für ältere Versionen des Internet Explorers optimieren, stoßt ihr hier auf Probleme.

<!-- relevanter HTML-Code -->

<body>
  <header></header>
  <main></main>
  <footer></footer>
</body>
/* relevanter CSS-Code */

html {
  height: 100%;
}

body {
  height: 100%;
  display: flex;
  flex-direction: column;
}

main {
  flex: 1;
}

Beispiel anschauen

Responsive Sticky Footer mit dem »CSS Grid Layout«

Die Grundvoraussetzung ist auch hier, dass das <html>- und das <body>-Element eine Höhe von 100% erhalten. Nun wird mit der Angabe display: grid; das CSS Grid-Layout aktiviert.
Über grid-template-row: auto 1fr auto; wird den einzelnen Grid-Zeilen (im Beispiel sind das <header>, <main> und <footer>) eine Höhe zugewiesen. Der Wert auto entspricht dem Inhalt des Elements. 1fr füllt den anschließend noch verbliebenen Platz auf.

<!-- relevanter HTML-Code -->

<body>
  <header></header>
  <main></main>
  <footer></footer>
</body>

 

html {
  height: 100%;
}

body {
  height: 100%;
  display: grid;
  grid-template-rows: auto 1fr auto;
}

Beispiel anschauen

Links / Quellen

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

Container Queries & Element Queries im Responsive Web Design

$
0
0

Eine der drei Grundvoraussetzungen, die Ethan Marcotte 2010 in seinem legendären Artikel »Responsive Webdesign« als Grundlage für selbiges aufgeführt hat, sind die Media Queries. Mit Media Queries kann man das Layout einer Website anhand von Geräteeigenschaften verändern. Beispielsweise, wenn der Viewport eine bestimmte Größe über- oder unterschreitet. Seit 2010 ist einige Zeit vergangen und es hat sich in der Praxis herausgestellt, dass für die Veränderung des Layouts die Viewportgröße nicht immer der ideale Ausgangspunkt ist. Häufig wäre es besser, wenn ein Element immer dann verändert werden könnte, wenn der Raum für dieses spezielle Element einen bestimmten Punkt über- oder unterschreitet. Genau das sollen sog. Element Queries bzw. Container Queries erledigen. Und noch vieles mehr.

Der Weg zum modularen Design

Früher haben Webdesigner ein Projekt vorrangig in Unterseiten geplant und gelayoutet. Es wurden z. B. eine Startseite, eine Produktansicht, eine Textseite usw. erstellt. Dann kam ab 2011 das Thema Responsive Design auf und erforderte ein flexibles Layout, dass auf verschiedenen Bildschirmgrößen funktioniert.

Breakpoints für Geräteklassen

Designer ohne HTML- und CSS-Kenntnisse konnten in Photoshop & Co. keine wirklich flexiblen Layouts gestalten. Daher haben Sie zusätzliche Layouts für verschiedene Geräteklassen entworfen. Im Ergebnis hatte man dann beispielsweise das Layout der Startseite auf dem Smartphone, dem Tablet und dem Desktop gestaltet. Bei der Breite dieser verschiedenen Layouts orientierte man sich meist an der Größe typischer Geräte wie dem iPhone oder dem iPad. Das Ergebnis war daher oft ein sog. adaptives Layout mit wenigen globalen Breakpoints.

Wenige globale Breakpoints in einem adaptiven Layout (Extrembeispiel)

Auch entstanden zahlreiche Layout-Dateien, die immer wieder die gleichen Bestandteile besaßen. Beispielsweise ist der Header meist auf allen Unterseiten identisch – musste aber doppelt gepflegt werden. Auch wenn Photoshop und Co. sich größte Mühe gaben den veränderten Bedingungen gerecht zu werden, stellte sich der Workflow als zunehmend träge, fehleranfällig und teuer heraus.

Erstellen Sie Übergangspunkte auf Grundlage der Inhalte und niemals auf Grundlage bestimmter Geräte, Produkte oder Marken. (Google Web Fundamentals)

Breakpoints für Komponenten und gestalterische/Inhaltliche Anforderungen

Designer mit HTML und CSS-Kenntnissen begannen parallel damit Layouts direkt im Browser zu gestalten und während der Arbeit permanent die Viewportgröße zu verändern. Unterstützt wurden Sie von immer besseren Entwickler-Tools in den Browsern. »Echte« responsive Layouts mit einem flüssigen Gestaltungsraster waren die Folge. Auch wurden die Breakpoints zunehmend dort gesetzt, wo der Content oder ein bestimmter Teilbereich des Layouts (die Komponente) eine Veränderung brauchte. Die Vorgehensweise dieser Designer führte daher zu einem robusteren und modularen Ergebnis mit deutlich mehr Breakpoints.

Modulare Breakpoint-Struktur in einem modernen, responsiven Projekt

 

Design-Pattern und -Systeme

Die Vorgehensweise Layouts nicht für Geräteklassen zu gestalten, sondern modular zu entwickeln setzte sich durch, und schlaue Leute begannen damit Konzepte für diesen Workflow zu entwickeln.

Bei Atomic Design-Ansatz werden aus kleineren Einheiten größere Komponenten entwickelt, die später zu Layouts zusammengebaut werden. Auch Frameworks wie Bootstrap und Foundation gehen in diese Richtung. Foundation hat beispielsweise mit den Building Blocks eine entsprechende Bibliothek veröffentlicht. Auch im kulturbanause-Blog findet ihr zahlreiche Design-Pattern – beispielsweise für Navigationen.

Ob nun Atomic Design oder andere modulare Ansätze. Der Trend geht eindeutig in die Richtung responsiver Komponenten, die zu immer größeren Modulen kombiniert werden und gemeinsam mit einem flexiblen Gestaltungsraster letztendlich ein ganzes Projekt ergeben.

Media Queries am Limit

Bei einem derart modularen Aufbau passen Media Queries nicht gut ins Konzept. Mit einem Media Query kann man abfragen, ob ein bestimmtes Gerät (z. B. der Bildschirm) eine bestimmte Eigenschaft (z. B. die Viewport-Breite) besitzt und anschließend darauf reagieren. Doch die Viewport-Breite ist oft nicht relevant für eine Komponente die nur in einem Teilbereich des Layouts platziert wird. Wenn man sich mit responsiven Layouts beschäftigt, merkt man schnell, dass Media Queries an ihre Grenzen stoßen.

Das folgende Beispiel zeigt warum. Das Layout beinhaltet eine typische responsive Komponente – die sog. Card, die aus Bildbereich und Inhalt besteht. Wenn die Card wenig Platz zur Verfügung hat, ist sie blau und das Bild soll über dem Inhalt stehen. Wenn mehr Raum verfügbar ist, soll das Bild nach links rutschen und die Card grün umgefärbt werden.

Das Beispiel Layout mit vier Layoutvarianten

Wenn wir das Projekt technisch mobile First aufbauen, stellt die blaue Card das Standardverhalten dar. Um bei einer Viewportbreite von 500 Pixeln auf die grüne Card umzuschalten, schreiben wir einen Media Query. Leider müssen wir ab 800 Pixeln das Verhalten widerrufen. Daher bietet es sich an, eine sog. »Media Query Range« zu verwenden, die von 500 bis 800 Pixeln die grüne Card erzeugt. Damit springt ab 800 Pixeln wieder das Standardverhalten ein. Doch bei 1000 Pixeln Viewportbreite müssen wir den Code für die grüne Card erneut schreiben. Vereinfacht dargestellt sieht der Code so aus:

.card {
 /* blau */
}

@media screen and (min-width: 500px) and (max-width:800px) {
 .card {
 /* grün */
 }
}

@media screen and (min-width: 1000px) {
 .card {
 /* grün */
 }
}

Die Wiederholung der Stile für »grün« könnten wir in diesem Beispiel durch Zusammenfassen der Media Queries zwar noch vermeiden, doch spätestens wenn eine weitere Unterseite mit alternativem Layout hinzukommt, müssen wir eine Sonderregel schreiben.

Folgendes Verhalten ist für zwei weitere Unterseiten gewünscht:

Auf anderen Seiten soll die Card in der Desktop-Version blau sein und den Bildbereich über dem Text zeigen

Wie man sieht, soll die Card nun in der Desktopversion blau sein. Doch da wir die Optik des Elements bisher mit einem Media Query anhand der Viewportbreite festlegen, werden die falschen Stile angewandt. Erst einmal erhalten wir folgendes Ergebnis:

Fehldarstellung durch den Einsatz des Media Queries

Wir müssen folglich für diese beiden Unterseiten die unerwünschten Stile in den größeren Layoutvarianten überschreiben. In diesem Beispiel ab dem Breakpoint bei 800 Pixeln. Das ist weder flexibel noch robust.

@media screen and (min-width: 801px) {
 .page-1 .card, 
 .page-2 .card {
   /* blau */
 }
}

Praktischer wäre in diesem Fall eine Komponente die eigene Breakpoints besitzen kann – also beispielsweise auf den verfügbaren Raum im Elternelement reagiert. In unserem Beispiel hätte die Komponente »Card« dann zwei Zustände und einen Breakpoint (Live-Beispiel).

Die Card als Komponente mit eigenem Breakpoint

Der Code könnte beispielsweise so aussehen:

.card {
  /* blau */
}

/* Schreibweise nach github.com/marcj/css-element-queries */
.card[min-width~="500px"] {
  /* grün */
}

Oder so:

.card {
  /* blau */
}

/* Schreibweise nach github.com/tomhodgins/element-queries-spec */
@element .card and (min-width:500px) {
  $this {
    /* grün */
  }
}

Oder so:

.card {
  /* blau */
}

/* Schreibweise nach github.com/ausi/cq-prolyfill */
.card:media(min-width:500px) {
    /* grün */
}

Element Queries & Container Queries

Es gibt im Zusammenhang mit dem oben beschriebenen Wunsch nach einer komponentenbasierten Herangehensweise zahlreiche Gruppen und Entwickler die seit geraumer Zeit an Lösungen arbeiten. KEINE davon ist final und es gibt aktuell keine standardisierte Syntax! Es gibt auch unterschiedliche Ansätze wie das gewünschte Element angesprochen werden kann und daraus haben sich verschieden Begrifflichkeiten entwickelt, die teilweise synonym verwendet werden. Ich nutze für die folgenden Beispiele die Syntax und das Wording des Scripts EQCSS, auf das ich später noch detailliert eingehe.

Was sind »Scoped Styles«?

Ein sog. »Scoped Style« begrenzt die Stile auf einen bestimmten Wirkungsbereich.

/* Wenn .sidebar irgendwo im Dokument existiert … */ 
@element .sidebar {

   /* … reduziere die Breite von .content. Wichtig: .content muss kein Kind-Element von .sidebar sein! */
   .content {
     width: 60%;
   }
}

Sog. »Scoped CSS« gab es in anderer Form übrigens schon einmal – der Browser-Support hat allerdings nachgelassen.

Was sind »Responsive Conditions«?

»Responsive Conditions« erweitern einen Scoped Style um eine Bedingung.

/* Wenn .card existiert und breiter als 500px ist … */ @element .card and (min-width:500px) {
   
  /* … ordne .card-header und .card-content nebeneinander an */
  .card-header, .card-content {
    flex:1; 
  }
}

Was sind »Element Queries«?

Die Kombination von Scoped Style und Responsive Condition nennt man »Element Query«. Man kann einen Element Query verwenden um andere Elemente zu stylen oder das gleiche Element. Im letzten Code-Beispiel haben wir beispielsweise die Breite der .card abgefragt und anschließend die enthaltenen Elemente verändert, wenn die .card mehr als 500 Pixel Platz hat. Wir haben also eine Abfrage für das Container-Element (die .card) verwendet, um die Kind-Elemente (.card-header und .card-content) zu stylen.

Was sind »Container Queries«?

Aus technischer Sicht ist ein Container Query ein Element Query, der dazu benutzt wird enthaltene Elemente zu stylen. Die Abfrage einer Bedingung erfolgt über einen Container – daher der Name. Container Queries passen gut zusammen mit Namenskonventionen wie BEM. Streng betrachtet sind die klassischen Media Queries auch Container Queries, da man das Styling der Website über die Abfrage einer Container-Eigenschaft verändert.

Vom Konzept her sind Container Queries gegenüber Element Queries eingeschränkt, da ein Element Query immer auch ein Container Query sein kann – aber nicht umgekehrt.

Es ist mit einem Container Query beispielsweise nicht möglich ein Element anzusprechen, dass keine Kindelemente besitzt oder besitzen kann. Ein <input>-Feld grün umzufärben, wenn es mindestens 20 Zeichen enthält, gestaltet sich mit einem Container Query daher schwierig. Ein Element Query würde beispielsweise folgende Syntax mit dem Schlüsselwort $this nutzen:

/* Wenn <input> mindestens 20 Zeichen enthält … */
@element input and (min-characters:20) {

  /* … ändere die Farbe auf grün */
  $this {
    color:lime;
  }

}

EQCSS – Element Query CSS

Wie bereits mehrfach erwähnt, gibt es in CSS noch keine Element Queries, Container Queries oder ähnliches. Es kursieren verschiedene Ideen in diesem Zusammenhang und es existieren einige JavaScript-Bibliotheken die die verschiedenen Ideen mehr oder weniger einsatzfähig machen.

Eine dieser Bibliotheken ist EQCSS. EQCSS ermöglicht Element Queries mit zahlreichen Bedingungen ab dem Internet Explorer 9 und aufwärts. Ein zusätzliches Skript rüstet den Support bis zum IE8 nach. EQCSS ist auf der Website elementqueries.com bzw. containerqueries.com (… ein Beweis für die Uneinigkeit hinsichtlich des Wordings) und in der zugehörigen (nicht offiziellen!) Spezifikation detailliert erklärt.

EQCSS – Funktionsweise

Das JavaScript kann auf der Website heruntergeladen oder über ein CDN bezogen werden. Es reicht aus, dass Skript im Footer zu laden.

<script src="eqcss.js"></script>

Anschließend können Element Queries im CSS-Code verwendet werden. Ob ihr dazu einen <style>-Abschnitt im selben Dokument verwendet oder ein über <link> referenziertes Stylesheet ist euch überlassen. Solltet ihr Element Queries strikt vom restlichen CSS-Code trennen wollen, so stehen auch dafür einige Optionen zur Verfügung.

EQCSS – Syntax

Element Queries nach EQCSS-Spezifikation werden wie folgt geschrieben:

@element SELEKTOR and (RESPONSIVE CONDITION) { 
  SELEKTOR {
    EIGENSCHAFT: WERT;
  }
}

Wenn also beispielsweise der <header> blau eingefärbt werden soll, wenn der <body> eine Höhe von 800 Pixeln hat, genügt folgender Code:

@element body and (min-height:800px) { 
  header {
    background: blue;
  }
}

EQCSS – Responsive Conditions

In EQCSS stehen eine Reihe interessanter Bedingungen für die Abfrage zur Verfügung:

  • min-width & max-width
  • min-height & max-height
  • min-children & max-children
  • min-characters & max-characters
  • min-lines & max-lines
  • min-scroll-x, max-scroll-x, min-scroll-y & max-scroll-y
  • orientation
  • min-aspect-ratio & max-aspect-ratio

EQCSS – Meta Selectors

Wenn man EQCSS nutzen möchte um das abgefragte Element direkt anzusprechen, kommt das Schlüsselwort $this ins Spiel. Das folgende Beispiel zeigt den Code, der notwendig ist um den <header> blau einzufärben, wenn er selbst breiter als 600 Pixel wird.

@element header and (min-width:600px) { 
  $this {
    background: blue;
  }
}

Neben $this existieren auch noch die Meta Selektoren $prev für das vorherige Element, $next für das nächste Element, $parent für das Elternelement (!!), und $root für das Root-Element.

Da es beim Dollarzeichen zu Konflikten im Zusammenhang mit Sass kommen kann, möchte ich hier auf eine Lösung hinweisen.

EQCSS – CSS Einheiten

Wenn EQCSS im Einsatz ist, können auch neue Einheiten verwendet werden. Die Einheit ew steht für die Breite des Elements (element width), eh für die Höhe (element height). emin und emax stehen für den jeweils kleineren bzw. größeren Wert – genauso wie bei den verwandten CSS-Einheiten vh, vw, vmin und vmax.

EQCSS – CSS Funktionen

In EQCSS kann auch eine neue CSS-Funktion namens eval() verwendet werden. Damit ist es möglich JavaScript einzuschleusen.

EQCSS Beispiel 1 – Mehrspaltige Komponenten

Das folgende Beispiel zeigt einen Hauptinhalt und eine Seitenleiste, die jeweils drei Boxen enthalten.

<main class="container">
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
</main>

<aside class="container">
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
</aside>

Mit Flexbox wird dafür gesorgt, dass die Seitenleiste neben dem Inhaltsbereich sitzt und dass die Boxen jeweils die volle Höhe des Container-Elements einnehmen.

* { box-sizing: border-box; }

body {
  display: flex;
  justify-content: space-between;
}

main { width: 70%; }

aside { width: 25%; }

.box {
  background: white;
  margin:.5em;
  padding:1em;
  flex:1;
}

.container {
  padding:.5em;
  height:300px;
  background:#8cb11c;
  display: flex;
  flex-direction: column;
}

Nun sollen die Boxen innerhalb des Containers nebeneinander angezeigt werden, sobald der Container 600 Pixel breit ist. Dafür nutzen wir folgenden Element Query:

@element .container and (min-width: 600px) {
  $this {
    flex-direction: row;
  }
}

Das Layout nach Einsatz des Element Queries

Beispiel anschauen

EQCSS Beispiel 2 – Formulareingabe

Das folgende Formular besteht aus drei <label>/<input>-Kombinationen.

<label for="field-1">Bitte gib mehr als 10 Zeichen ein. </label>
<input type="text" id="field-1">

…

Mit einem Element Query prüfen wir, ob in das <input>-Feld mindestens 10 Zeichen eingegeben wurden. Wenn das der Fall ist, färben wir das Feld grün ein und fügen den Hinweis »Vielen Dank!« mittels Pseudoelement an das vorausgegangene Element (das <label>) an.

@element input and (min-characters: 10) {
  $this {
    background:#8cb11c;
    color:white;
  }

  $prev::after {
    content:'Vielen Dank!';
  }
}

Mit einem Element Query wird das Eingabefeld gefärbt und ein Hinweis eingeblendet

Beispiel anschauen

EQCSS Beispiel 3 – Sticky Navigation

Im nächsten Beispiel sitzt die Navigation unter dem Header. Wenn gescrolled wird, soll die Navigation fixiert werden, sobald ihre Oberkante die Oberkante des Viewports erreicht hat.

/* relevanter CSS Code */
@element body and (min-scroll-y: 600px) {
  nav {
    position: fixed;
    top:0;
    left:0;
    right:0;
  }
}

Beispiel anschauen

EQCSS Beispiel 5 – Viewport- und Elementgröße auslesen

Mit Hilfe von JavaScript und der Funktion eval() ist es möglich die Viewport-Breite oder die Höhe eines Elements auszulesen. Mittels Pseudoelement ::after wird die Abmessung dann sichtbar gemacht.

<body>
  <div class="resizeable"></div>
</body>
@element body {
  $this::after {
    position:fixed;
    top:1em;
    left:1em;
    content: 'eval("'Viewport: '+window.innerWidth+' x '+window.innerHeight")';
  }
}

@element .resizeable {
  $this::after {
    content: 'eval("'Element: '+offsetWidth+' x '+offsetHeight")';
  }
}

Höhe und Breite von Element und Viewport werden mittels eval() angezeigt

Beispiel anschauen

Alternative Lösungen

Neben der hier beschrieben Lösung mittels EQCSS gibt es auch alternative Ansätze, die ich euch nicht vorenthalten möchte.

Kritikpunkte

Auch wenn der Ruf nach einer Element/Container Query-Lösung laut ist, so gibt es doch auch Kritik.

Beispielsweise sind in allen mir aktuell bekannten Lösungsansätzen Endlosschleifen möglich. Der folgende Code erzeugt beispielsweise einen solchen Konflikt durch Selbstreferenzierung:

// Wenn der div breiter ist als 1000 Pixel …
@element div and (min-width: 1000px) {

  // … verkleinere ihn auf 999 Pixel
  $this {
    width: 999px;
  }
}

Das ist in der Tat ein Problem, aber möglicherweise nicht ein solcher Blocker für die Weiterentwicklung von Element- bzw. Container Queries wie es oft dargestellt wird. Denn erstens ist ein solcher Konflikt auch mit validem Standard-CSS möglich (siehe Beispiel) und zweitens springt der Browser bei einem Element Query-Konflikt nicht permanent zwischen zwei Bedingungen hin und her. Das bedeutet, dass es zwar ggf. nicht so aussieht wie gewünscht, aber es gibt keine Endlos-Schleife die in einem Browser-Absturz oder ähnlichem resultiert. Zuletzt löst der CSS-Befehl contain: strict; viele Probleme, wenn der Browser-Support vorhanden ist.

Ein weiterer Kritikpunkt ist, dass Element Queries durch neue Layoutlösungen wie Flexbox oder CSS Grids teilweise überflüssig sind bzw. dass sie nur das Styling betreffen, nicht aber das Verhalten eines Elements. Das stimmt zwar – wäre für mich aber kein Grund nicht trotzdem an der Technologie zu arbeiten, da es haufenweise sinnvolle Anwendungsfälle gibt.

Fazit

Wir sind zwar noch weit entfernt von standardisierten CSS Element Queries – aber das Konzept ist höchst interessant und funktioniert mit JavaScript bereits erstaunlich gut. Ob man sich traut EQs in einem Projekt einzusetzen, muss im Einzelfall entschieden werden, aber es lohnt sich allemal mit der Technologie zu spielen und sie ggf. sogar aktiv mit voranzutreiben.

Links / Quellen

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

Interaction Type Media Queries – Unterstützung für Hover-Effekte und Bedienkonzept abfragen

$
0
0

In Level 4 der CSS Media Query-Spezifikation sind die sog. »Interaction Type Media Queries« hinzugefügt worden. Es ist nun möglich abzufragen ob Mouse-Over-Zustände unterstützt werden und wie fein die Spitze des Eingabegeräts ist. Somit lassen sich auch Rückschlüsse auf das verwendete Endgerät ziehen.

hover & any-hover Interaction Type Media Queries

Mit den Abfragen hover bzw. any-hover bringt man in Erfahrung ob und wenn welche Art von Mouse-Over-Effekt unterstützt wird. Der Unterschied zwischen hover und any-hover besteht darin, dass any-hover reagiert, sobald einer der folgenden Werte unterstützt wird.

Es sind folgende Werte möglich:

none
Das Gerät unterstützt keine Mouse-Over-Effekte beispielsweise, weil es keinen Cursor und keinen Touch Screen besitzt.
on-demand
Das Gerät zeigt Mouse-Over-Effekte nach einem Tippen/Klicken auf das Element an. Das Verhalten ist bekannt von Touch-Screens. Der Wert on-demand wird nicht länger unterstützt.
hover
Das Gerät unterstützt »normale« Mouse-Over-Effekte wie es von einer Bedienung mittels Cursor bekannt ist.

Wenn ihr also einen Button gestrichelt umranden wollt, wenn das Gerät Mouse-Over-Effekte unterstützt, reicht folgender CSS-Code:

@media (hover:hover) {
  button {
    border:1px dashed black;
  }
}

pointer & any-pointer Interaction Type Media Queries

Mit pointer bzw. any-pointer fragt ihr ab wie fein die Spitze des Eingabegeräts ist. Der Unterschied zwischen pointer und any-pointer besteht auch hier darin, dass any-pointer reagiert, sobald einer der Werte unterstützt wird.

Es sind folgende Werte möglich:

none
Das Gerät verfügt über keinen Cursor o.ä., beispielsweise weil es über Tasten gesteuert wird und keinen Touch Screen hat.
coarse
Die Spitze des Eingabegeräts ist relativ grob, beispielsweise weil der Finger als Eingabegerät genutzt wird.
fine
Die Spitze des Eingabegeräts ist fein, beispielsweise weil ein Stift oder ein Cursor genutzt wird.

Wenn ihr also einen Button größer gestaltet wollt, wenn das Gerät per Finger bedient wird, und kleiner wenn es per Cursor bedient wird, verwendet folgenden CSS-Code:


@media (pointer:coarse) {
  button {
    font-size:1.5em;
  }
}

@media (pointer:fine) {
  button {
    font-size:1em;
  }
}

Demo

Wir haben eine Demo-Datei gebaut, die alle oben beschriebenen Funktionen abfragt und visualisiert. Somit könnt ihr sehen auf welche Media Queries euer aktuell verwendetes Gerät reagiert. Zusätzlich ziehen wir in der Demo einen Rückschluss auf das von euch verwendete Gerät.

Beispiel anschauen

Browser-Support

Der Browser-Support sieht bis auf Firefox sehr gut aus. Details findet ihr auf caniuse.com

Jetzt bist Du gefragt

Gefällt Dir dieser Beitrag oder bist du anderer Meinung? Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

Viewing all 173 articles
Browse latest View live