Ol’ Trent postete einen kurzen Tipp-Post über die Verwendung von `inset` box-shadow für einige einfache, aber klassische Effekte. Eine dieser Techniken führte zu einem Vignettierungseffekt über einem Bild. So:
Ja, das könnte man in Photoshop machen, aber wenn man es über CSS macht, bedeutet das 1) es ist nicht-destruktiv 2) kann es programmatisch geändert werden 3) ist es super konsistent.
Als ich das Beispiel zum ersten Mal sah, dachte ich: „Hey, das ist ziemlich cool, aber warum die umgebende div?“ Browser erlauben box-shadow für <img>-Elemente, also warum nicht einfach einen inset box-shadow darauf anwenden. Das wäre saubereres HTML.
<img src="amazinglandscape.jpg" alt="ooooh ahhhh" class="vignette">
.vignette {
-webkit-box-shadow: inset 0px 0px 85px rgba(0,0,0,0.4);
-moz-box-shadow: inset 0px 0px 85px rgba(0,0,0,0.4);
box-shadow: inset 0px 0px 85px rgba(0,0,0,0.4);
}
Es stellt sich heraus, dass man inset box-shadows auf Bildern verwenden kann, nur dass der Browser sie hinter das Bild setzt, was bedeutet, dass man den Schatten überhaupt nicht sieht, wenn man ein vollständig opakes Bild verwendet (was sehr wahrscheinlich ist, wenn man daran interessiert ist, es zu vignettieren). Worauf Trent sagt:
Während dies ziemlich nutzlos erscheint, ergibt es Sinn, wenn man andere Arten von Inhalten betrachtet. Zum Beispiel würde man, wenn man einen Schatten einfügt, wahrscheinlich nicht wollen, dass er den Text darin überschattet.
Ich stimme auch einem anderen Punkt von Trent zu: Vielleicht sollte die offizielle Spezifikation für box-shadow geändert werden, um zu besagen, dass der Schatten, wenn er direkt auf ein Bild angewendet wird, oben liegen sollte. Nun, weder die Spezifikation noch die Implementierungen tun dies.
Dann dachte ich: „Hey, Moment mal, lass uns noch nicht zu einem umgebenden Element greifen.“ Schließlich ist es ein ehrenwertes Ziel, unser HTML frei von nicht-semantischen Umgebungen zu halten. Warum verwenden wir nicht ein Pseudo-Element auf dem Bild, das wir zwingen können, oben zu sitzen und die genaue Größe des Bildes zu haben, und wenden den inset box-shadow darauf an?
.vignette:after {
-webkit-box-shadow: inset 0px 0px 85px rgba(0,0,0,0.4);
-moz-box-shadow: inset 0px 0px 85px rgba(0,0,0,0.4);
box-shadow: inset 0px 0px 85px rgba(0,0,0,0.4);
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
content: "";
}
Als ich an einer Demo dafür arbeitete, funktionierte es immer wieder nicht und verwirrte mich total. Für einen Moment dachte ich: „Ich frage mich, ob :before und :after Pseudo-Elemente einfach nicht auf Inline-Elemente funktionieren*“, aber ich habe bewiesen, dass sie mit Spans funktionieren, also war das ausgeschlossen.
Dann hörte ich von Nicholas Gallagher
Keine Elemente mit einem „leeren“ Inhaltsmodell unterstützen generierten Inhalt über Pseudo-Elemente.
Damit meint Nicolas im Wesentlichen jedes Element, das keinen innerHTML hat. Denk an
<br />
<br />
<input />
<img />
Dies liegt anscheinend daran, dass die Spezifikation nicht erklärt hat, wie mit Elementen dieser Art umzugehen ist.
Ähnlich wie bei der Sache mit dem inset box-shadow ergibt es irgendwie Sinn. Man kann sich ein :before Pseudo-Element als innerhalb der Tags, aber vor anderem Inhalt vorstellen, und ein :after Pseudo-Element als innerhalb der Tags, aber nach anderem Inhalt.
<div>
<!-- :before pseudo element -->
Hi! I'm content!
<!-- :after pseudo element -->
</div>
<img /> <!-- Where would pseudo content go? -->
Für jQuery-Leute erklärt Tim Wright
es ist so, dass :after mehr wie das .append() von jQuery ist als .after(), so dass man nichts in die Mitte von
<img>werfen kann.
Wenn Sie denken: „Alter, pack die Pseudo-Elemente EINFACH NACH oder VOR das verdammte Element“, sind Sie nicht allein. Das Problem ist, dass dies nicht mit anderen Elementen übereinstimmt und die Spezifikation dies nicht abdeckt. Um die Sache noch komplizierter zu machen, ist dies tatsächlich das, was Opera tut.
Also, das war's für Ideen, wie man es sauber machen kann. Nehmen wir einfach die umgebende div und machen wir es hinter uns.
<div class="vignette">
<img src="handsomepeople.jpg" alt="ooooh ahhhh">
</div>
.vignette {
-webkit-box-shadow: inset 0px 0px 85px rgba(0,0,0,0.4);
-moz-box-shadow: inset 0px 0px 85px rgba(0,0,0,0.4);
box-shadow: inset 0px 0px 85px rgba(0,0,0,0.4);
line-height: 0; /* ensure no space between bottom */
display: inline-block; /* don't go wider than image */
}
.vignette img {
position: relative;
z-index: -1; /* position beneath */
}
Ein möglicherweise wünschenswerter, möglicherweise ärgerlicher Nebeneffekt? Mit dem div-Overlay kann man nicht mit der rechten Maustaste klicken, um das Bild zu speichern, oder es auf den Desktop ziehen. Super primitiver Bildschutz.
Verwandt
- Eine weitere Technik von Dudley Storey, bei der das Bild als Hintergrundbild des vignettierten Elements verwendet wird. Wahrscheinlich besser für einmalige Anlässe, aber schwieriger für Websites, auf denen man es einfach überall verwenden möchte, ohne ständig CSS ändern zu müssen.
* Übrigens habe ich Introducing HTML5 gelesen und einen interessanten Punkt gelernt. In HTML5 gibt es wirklich keinen Unterschied zwischen einem „Inline“-Element und einem „Block“-Element. Alle Elemente sind inline, bis sie anderweitig von einem Browser- oder Benutzerstylesheet spezifiziert werden.
Danke für diesen Artikel. Ich hatte keine Ahnung, dass man „inset“ für box shadows angeben kann! Ich kann es kaum erwarten, das auszuprobieren.
Es ist cool, dass Sie zeigen, wie das geht, und es ist sicherlich eine clevere Technik. Konzeptionell bin ich kein großer Fan davon, CSS zu verwenden, um Bilder tatsächlich zu „verändern“. Es ist anders, wenn man einen normalen Schatten oder einen Rahmen um das Bild anwendet, aber das tatsächliche Styling des Bildinhalts klingt für mich nicht richtig. Ich denke nicht, dass Bildinhalte gestylt werden müssen. Wenn sie es brauchen, sollte es Teil des Bildes selbst sein.
Dies ist natürlich nur eine Meinung und ich kann verstehen, wie man damit coole Hover-Effekte und so erzielen könnte.
Schnelle Warnung – es scheint, dass höhere Blur-Werte zu einer leichten Geschwindigkeitsreduzierung führen.
Auf Ihrer Demoseite verursacht das einfache Scrollen mit meinem Mausrad eine spürbare Belastung für den Browser. Wenn ich die Weichzeichnungen im Web-Inspektor deaktiviere – ist alles wieder reibungslos.
Es ist ein schöner Effekt und leicht genug zu stylen – aber mit Vorsicht verwenden.
Ja, und es macht die Dinge wirklich träge, wenn man mehrere box shadows wie diese hat.
Ich habe den Vignettierungseffekt einmal auf dem Hintergrund einer Inhaltsspalte ausprobiert (mit etwa 45 Pixel Blur) und er hat so stark geruckelt, dass ich ihn entfernen musste. Hoffentlich werden wir in Zukunft Leistungsverbesserungen sehen, es kann wirklich toll aussehen.
Ich liebe inset box shadows. Ich finde mich heutzutage mehr beim Designen in CSS als in Photoshop.
3. Option (und meiner Meinung nach die beste im Jahr 2010): Erstellen Sie ein transparentes PNG für die Vignettierung und überlagern Sie es mit absoluter Positionierung. Funktioniert jetzt in allen Browsern, ist nicht-destruktiv/programmatisch, gibt Ihnen mehr künstlerische Kontrolle und kann für Rollover verwendet werden.
allerdings auch
…erzeugt einen zusätzlichen HTTP-Request,
…erzeugt mehr Bandbreite,
…erzeugt zusätzlichen Markup (der, im Gegensatz zur umgebenden div, nicht so einfach programmatisch geändert werden kann – die Umgebende kann effektiv ignoriert werden, indem man einfach die CSS-Regel auskommentiert)
am wichtigsten ist, dass die CSS-Methode ein konsistenteres Ergebnis liefert: der Blur wird immer 85px (oder was auch immer) sein. Bei Bildüberlagerungen, wenn Sie mehrere Bildgrößen haben, müssen Sie entweder mehrere Overlay-Bilder erstellen oder mit einigen Schatten umgehen, die größer (und von anderer Auflösung) als andere sind.
Ich stimme Ihnen hier nicht ganz zu. Legen Sie einfach die .PNG-Überlagerung in einen Sprite und die größere Bandbreite ist fast weg. Und damit auch der zusätzliche HTTP-Request. Und was den zusätzlichen Markup angeht. Ich sehe es nicht als großes Problem an. Man könnte etwas Raffiniertes mit jQuery machen, um den Markup zu erstellen, so dass er in Ihrem Markup unsichtbar ist, wenn Sie an der Datei arbeiten.
Was die verschiedenen Größen angeht. Da stimme ich Ihnen zu. Es ist viel schwieriger, das mit .PNG zu machen, als es mit CSS zu machen. Aber ein konsistenteres Ergebnis? Das weiß ich nicht, denn das Rendern von Box Shadow unterscheidet sich in Browsern. Und sogar Betriebssystemen. Und ich würde wahrscheinlich die Vignettierung für Thumbnails verwenden, die normalerweise die gleiche Größe haben. Also würde ich im Moment auch zu .PNG greifen.
Sie haben Recht, aber ich habe nie gesagt, dass ich ein Purist bin. Da CSS3 noch jahrelang in 50% der weltweit genutzten Browser nicht unterstützt wird… wird meine Version mit der einen zusätzlichen Codezeile das tun. Sicher, es wäre schön, wenn CSS3 so funktionieren würde, wie es sollte, aber dank Ihnen wissen Sie, dass es das nicht tut.
Rick – gute Punkte. Der Hauptvorteil ist meiner Meinung nach die Konsistenz. Und obwohl es möglicherweise nicht browserübergreifend konsistent ist, wird es konsistent für jedes Bild auf der *Seite* sein – und einfacher zu erreichen.
j – absolut.
Wahrscheinlich eine gute Idee, das umgebende Element on the fly mit JS zu erstellen, um den Markup sauber zu halten. Verwenden Sie einfach die Klasse, um das Bild zu finden. Es ist sowieso kein wesentlicher Inhalt, daher würde die Verwendung von JS zur Erstellung keinen Schaden für die Barrierefreiheit bedeuten.
Ich dachte an ein bisschen jQuery in der Art von;
…wäre eine einfacher zu verwaltende Lösung.
Genau das, was ich mir gedacht habe. Kein Grund, den Markup für einen solchen Effekt zu verschmutzen.
Anstatt eines div-Tags wäre ein figure-Tag mit der Klasse „vignette“ HTML5-freundlicher, da es sich um semantischeren Markup handelt. Toller Beitrag übrigens..
Ich habe noch nie vom figure-Tag gehört… und ich lese ziemlich viel über HTML5… nun, man lernt jeden Tag etwas Neues!
Ich stimme dem Figure-Tag zu. Daran habe ich gedacht, nachdem ich Ihren dritten Absatz gelesen hatte, aber nur, weil ich kürzlich mit figure-Tags gearbeitet hatte.
Exzellente Ausarbeitung, Diskussion der Ansätze und die endgültige Idee.
Es scheint, dass Pseudo-Elemente mit Dingen wie Eingabefeldern funktionieren… das ist aber schade.
Wäre es möglich, das Bild mit einem öffnenden und schließenden Tag zu machen? Das scheint möglich zu sein? Ehrlich gesagt, ich bin mir nicht sicher, ob das gültig ist.
Sehr clever, aber ich denke immer noch, dass Photoshop der richtige Weg ist. Die Verwendung ist nur dann destruktiv, wenn man keine Ebenen verwenden kann. Es ist auch nicht konsistenter als die Verwendung von Photoshop – mehrere Browser, nur 1 Photoshop. Der einzige wirkliche Vorteil, den Sie nennen, ist, dass Sie es programmatisch machen können.
Ich denke, wo dies zum Tragen kommen könnte, wäre die Nachrüstung einer alten Website. Interessanter Artikel
In Bezug auf Ihren letzten Punkt über Inline-Elemente in HTML5 – bedeutet das, dass Sie jedes Element in ein anderes Element einbetten können? Zum Beispiel kann man normalerweise kein
<a>um ein<div>wickeln, aber ist das in HTML5 legal?Man kann nicht *irgendein* Element in ein anderes einbetten, aber der spezielle Fall von <a> ist wahr: http://html5doctor.com/block-level-links-in-html-5/
Browser haben dieses Verhalten schon seit Jahren – jetzt ist es nur Teil eines Standards :)
Dies kann mit nur einem Element gemacht werden (bisher hatte ich Zeit, es nur in FF zu testen, ich sehe keinen Grund, warum es nicht in verschiedenen Browsern funktionieren sollte). Stellen Sie einfach das Bild auf den Hintergrund und wenden Sie den inset-Schatten an. Klarerer Markup, erfordert aber die Angabe der Abmessungen.
Bei der Verwendung von zwei Elementen können Sie mit einem radialen Gradienten sogar eine bessere Vignettierung erzielen.
Danke.
Mit dieser Technik können keine Bilder auf der Seite gespeichert werden.
Danke für das Teilen, Chris. Technisch gut durchdacht und funktioniert sicher.
Aber als Designer und Fotograf ist der CSS3-Innenschatten ein perfektes Beispiel dafür, wie eine echte Foto-Vignettierung *nicht* aussehen sollte.
Innenschatten: einfarbige Ebene mit fallender Opazität von den Seiten
Vignettierung: radialer negativer Klarheitsabfall zu den Ecken
Aber ich weiß, es ist nicht Ihr Ziel, eine realistische Vignettierung zu zeichnen, sondern einen einfachen vignette-ähnlichen Effekt mit CSS zu zeigen. Also nochmals vielen Dank für das Teilen!
Wirklich schön. Das beseitigt das „Oh, ich habe vergessen, diesen Schatten hinzuzufügen..“. Auch ein cooler Hover-Effekt .vignette:hover {…}
Es ist wichtig zu beachten, dass Chrome unter Windows ein Problem hat, wenn man einen inset box-shadow mit abgerundeten Ecken kombiniert. Beispiel hier: http://darcrobotics.org/?page=11
Der Fehler wurde gemeldet, Sie können den (mangelnden) Fortschritt bei der Behebung dieses Problems hier einsehen: http://jordandobson.com/_expirements/css/vignette/
Einfacher Bildschutz? In Safari auf dem Mac kann man das Bild immer noch einfach per Drag & Drop auf den Desktop ziehen.
Ich sehe nicht ein, warum das klassisch sein soll, da ich mich erinnere, dass wir diese Insets schon als Teenager in PS7 gemacht haben und niemand es wirklich mochte. Vielleicht ist Inset in anderen Situationen nützlicher? :)
Mir gefällt übrigens der neue Footer sehr gut…
Nachdem ich diesen Beitrag gelesen hatte, habe ich eine Weile recherchiert, um zu sehen, ob ich etwas entwickeln könnte, das einer echten Vignettierung näher kommt.
Ich habe an verschiedenen Methoden gearbeitet, um Vignettierungs-Fotos zu erstellen, und die Details und den Code hier veröffentlicht: http://cl.ly/3Nxc.
Ich habe mich weitgehend für CSS-Verläufe entschieden, um den Effekt zu erzielen. Ich finde, es ist ziemlich gut geworden. Ich hoffe, Sie oder jemand anderes findet das nützlich!
Vor langer Zeit habe ich versucht, top: 0; bottom: 0; & eine Breite als Alternative zu Faux Columns auf Basis von background-image zu verwenden. Es schien gut zu funktionieren, aber viele Leute sagten mir, ich solle nicht erwarten, dass es in Zukunft funktioniert.
Was denkst du?
Sie verwenden im Grunde die gleiche Technik mit Ihrem top: 0; left: 0; bottom: 0; right: 0;
Ich verwende es ständig und es ergibt für mich total Sinn. Ich bin mir nicht sicher, warum jemand denken würde, dass das entfernt wird. Es funktioniert gut und man sollte es verwenden!
Was ich mir mehr als nur box-shadows über Inhalt wünschen würde, ist ein tatsächliches Vordergrundbild!
Ich hatte einmal ein Projekt, bei dem sie ein dekoratives Element in der unteren Ecke jedes Profilfotos des Benutzers haben wollten. Keine legale Wasserzeichen, nur ein dekoratives Element. Ich hätte dafür ein Vordergrundbild verwenden können, anstatt zusätzliche divs zur Vorlage hinzufügen zu müssen.
Es könnte auch nützlich sein, einen inset box-shadow als Maske zu verwenden.
Was ist der Stand der Dinge bei den Maskierungsarbeiten, an denen Apple für Safari gearbeitet hat?
Dafür möchte man ::before und ::after für diese Art von „Vordergrundbildern“ verwenden. Es wäre ähnlich wie der Ansatz, den ich verwendet habe, um das CSS3-Verlaufsbild zu überlagern.
Leider kann man keinen inset box-shadow als Maske verwenden, da er nicht als „Bild“ betrachtet wird… und man ein Bild mit einer Maske verwenden muss.
Die Maskierung in Safari funktioniert hervorragend. Und von den Demos, die ich von Firefox für CSS + SVG für Masken gesehen habe, scheint es auch gut zu funktionieren. Hier ist ein Beispiel für die Verwendung von Masken zur Nachbildung der iOS-Tabbar von Apple: http://cl.ly/2Hyj – Stellen Sie sicher, dass Sie es in Webkit ansehen.
Die Leistung ist in Safari wirklich schlecht!
Ich weiß nicht warum, aber alle Schattenmanipulationen über CSS funktionieren auf meinem Safari / iMac 2.3GHz-CoreDuo schlecht.
Ist etwas mit meiner installierten Version von Safari falsch oder entdecken andere das gleiche Problem?
Nein… die Leistung ist mit box-shadows ziemlich schlecht… irgendwo um die 20-30 Pixel Blur verlangsamt Safari wirklich. Deshalb war einer meiner Versuche, einen CSS3-Verlauf zu verwenden.
Das Problem dabei ist jedoch, dass es nicht W3C-konform ist, und was die Sorge angeht, dass Photoshop destruktiv ist, stellen Sie einfach sicher, dass Sie das Original speichern, das ist keine Raketenwissenschaft, Leute!
Ich kann den Sinn des Weggehens von Photoshop und destruktiv, wo immer möglich, verstehen. Haben Sie jemals einen Kunden gehabt, der Sie um Änderungen bat, aber die Quelldateien nicht bereitstellen konnte, weil der alte Designer sie behalten hat? Außerdem ist dies 2010 und die Ära des sozialen Netzwerks. Viele Bilder werden von Benutzern ohne technische Fähigkeiten eingereicht, um eine Vignettierung oder einen Schatten hinzuzufügen. Dann gibt es noch die schnellere Arbeitsweise. HTML5/CSS3 wird Photoshop nicht so schnell ersetzen, aber weil es mit ein paar Codezeilen so einfach ist, ein ansonsten schlichtes Design aufzupeppen, sehen wir bereits, wie das Web in Bezug auf das Design einen Schritt nach vorne macht….
Tolle Erklärung. Jetzt weiß ich, warum :before oder :after Probleme mit oder ähnlichen leeren Elementen haben.
Habe „Super primitiven Bildschutz“ auch ziemlich genossen :)
Vielen Dank für das Teilen! Ich genieße Ihre Beiträge und lynda.com-Kurse sehr. Ich habe das Gefühl, dass ich mich mit Ihnen identifizieren kann, was es einfacher macht, den Stoff zu lernen.
Toller Beitrag! Ich hatte keine Ahnung, dass man das kann. Ich hoffe, das in meiner nächsten Webgalerie-Website zu verwenden. Danke Chris!