Reflecties kunnen een interessante dimensie toevoegen aan objecten, een vleugje realisme verlenen en context in hun omgeving geven. Laten we eens kijken naar het bereiken van reflecties met CSS en we zullen gloeiende en cross-browser vervaging ook voor een goede maatregel onderzoeken.
Het volgen van deze tutorial werkt op een aantal veronderstellingen:
box-shadow
werken. Het is niet de sleutel tot deze tutorial, dus u zult het zelf moeten uitzoeken. Als je een verklaring nodig hebt, raad ik je aan CSS3 versus Photoshop te bekijken: afgeronde hoeken en rechthoekige vakjes.Box-reflect is een CSS-eigenschap die precies voor dit doel is bedoeld: reflecties maken. We zullen niet gebruiken box-weerspiegelen
en mask-afbeelding
, omdat:
Toen Microsoft hun filtereffecten introduceerde (denk aan het IE 4-tijdperk, geneste tabellen voor lay-out en afbeeldingen voor reflecties), waren de smerige filters niet van toepassing op het geheel van een bepaald element. Ik vermoed dat ze een soort grensvak gebruikten van de linkerbovenhoek tot de rechteronderhoek van het element, wat logisch was, want voor zover ik weet was er geen manier om dit kader te overschrijden. Ze hebben het echter nooit gecorrigeerd.
Nu, in het Chrome 17-tijdperk, heeft webkit dezelfde fout gemaakt. Masker afbeeldingen, de sleutel tot -webkit-box-weerspiegelen
, maak een soort dynamische momentopname binnen het grensvak, plak het hieronder en wijzig de dekking. Ik heb geprobeerd de demo opnieuw te maken met behulp van -webkit-box-reflecteer:
Ik ben er nog niet klaar mee, maar het probleem is duidelijk. Het ETBR heeft border-radius
en box-shadow
. De doosschaduw is zichtbaar binnen, maar niet buiten het grensvak.
In mijn methode matrixtransformaties vervangen box-shadow en transparantie door box-reflect en mask-image. De beperkingen:
Fiddle | Volledig scherm
De tekstkleur wordt niet donkerder op de achtergrond. Dus het lijkt erop dat je geen andere kleur kunt hebben en de doosschaduw samen.
Terwijl we het hebben over matrices en reflecties ...
Je neemt de blauwe pil - ik laat je zien hoe je de demo word-voor-woord opnieuw kunt maken. Je neemt de rode pil - ik zal je laten zien hoe je reflecties kunt maken en ik zal je vertellen waar je deze reflecterende kleuren voor een zeer interessante prijs kunt kopen.
Simpel gezegd; sommige van de volgende stappen zijn optioneel, afhankelijk van of u de demopixel voor pixel opnieuw wilt maken.
De demo begint met een HTML5-sjabloon ...
index.html
CSS3 reflecties
... en dit CSS-bestand.
style.css
html height: 100%; body text-align: center; regelhoogte: 1; marge: 0; opvulling: 0; hoogte: 100%; p line-height: 1.2;
En natuurlijk voegen we een link toe aan het stylesheet:
CSS-reflecties!
De demo is 2D. Geen enkel 3D-element. We weten het, maar ons doel is om te maken hen denk dat we dit hebben gebouwd en vervolgens het vooraanzicht hebben gefotografeerd.
Als we willen dat ze geloven dat het 3D is, moeten we bepalen hoe de objecten in de 3D-ruimte worden geplaatst en geroteerd. De demo heeft een horizon. De top 10% is zwarte 'lucht', de andere 90% is een nep 3D-vlak. The Element to be Reflected (hierna aangeduid in onze demo als EtBr) en het vlak staan loodrecht op elkaar (de hoek is 90 °), de reflectie moet evenwijdig zijn aan de ETBR.
De HTML:
reflectie
De ETBR is een kind van het vliegtuig. Op deze manier blijft het in dezelfde positie gezien vanuit het vlak en blijft de gloed in het vlak.
body text-align: center; regelhoogte: 1; marge: 0; opvulling: 0; achtergrondkleur: # 000; hoogte: 100%; p line-height: 1.2; #plane links: 0; top 10%; breedte: 100%; onderkant: 0; minimale breedte: 1080 px; minimale hoogte: 600 px; positie: absoluut; overloop verborgen; overflow-x: zichtbaar;
Notitie:
Lokaliseer het object (ETBR), kopieer het, plak het in zichzelf en hernoem het om te refl (ection):
reflectiereflectie
Maak nu binnen de css de selector van het object. Voeg #refl toe aan de selector, zodat onze stijlen op beide elementen worden toegepast:
#ETBR, #refl
Kortom, de CSS en HTML van de reflectie moeten hetzelfde zijn als de CSS en HTML van de ETBR. We zullen de reflectie vanaf stap 5 positioneren, spiegelen en mooier maken. Maar voorlopig verbergen we de reflectie.
#ETBR, #refl #refl weergave: geen;
Als Internet Explorer Internet Explorer is, moeten we een voorwaardelijke HTML toevoegen:
CSS3 reflecties reflectiereflectie
Je vraagt je misschien af waarom, gewoon kaal met mij. Omdat je in een ziekenhuis verblijft, zal deze eerste Fiddle helemaal zwart zijn. Wil je de invloed van het vliegtuig zien? Verklein het.
Fiddle | Volledig scherm
Dit behoeft geen uitleg:
#ETBR, #refl color: # 004; font-family: Impact, 'Arial Black', Helvetica, Arial, sans-serif; text-transform: hoofdletters; lettergrootte: 200 px; achtergrondkleur: #FFE; lettertype: vet; opvulling: 30px; weergave: inline-block; #refl display: geen;
OK, een kleine uitleg. De combinatie van text-align: center;
en weergave: inline-block;
centreert een element oude skool, maar het is niet de heilige graal; inline-items mogen geen blokitems bevatten. Ik heb het gebruikt, omdat ik voor dit voorbeeld geen duizenden drijvende containers wilde toevoegen. Over het algemeen is dit echter de manier om te gaan.
Fiddle | Volledig scherm
De gloed bestaat uit drie schaduwen: een grote, uitgerekte schaduw (die meer lijkt op de reflectie van het licht op het vlak), de echte gloed (een witte schaduw met een korter onscherptebereik) en een zwarte inzetschaduw (waardoor de schaduw ETBR ziet eruit alsof het gloeit). Zoals ik eerder al zei, ga ik niet uitleggen hoe vakschaduw werkt en grensradius spreekt tegenwoordig voor zich.
#ETBR, #refl color: # 004; font-family: Impact, 'Arial Black', Helvetica, Arial, sans-serif; text-transform: hoofdletters; lettergrootte: 200 px; achtergrondkleur: #FFE; lettertype: vet; opvulling: 30px; weergave: inline-block; box-shadow: rgba (255,255,240, .2) 0 0 200px 100px, rgba (255,255,240, .3) 0 0 40px, inzet rgba (0,0,0, .8) 0 0 20px; grensradius: 30px;
Fiddle | Volledig scherm
Maak de #refl selector leeg om de reflectie zichtbaar te maken. Omdat reflecties niet 'echt' zijn, zal onze reflectie geen deel uitmaken van de documentenstroom; het zou moeten drijven. De voor de hand liggende keuze is om de positie in te stellen op absoluut, wat betekent dat het element wordt gepositioneerd ten opzichte van het eerst geplaatste (niet statische) voorouderelement. Omdat er geen eerste gepositioneerde voorouder van de reflectie is, wordt deze gepositioneerd ten opzichte van de body-tag.
Het is veel gemakkelijker om de reflectie te positioneren ten opzichte van de echte tekst, die ook een voorloper is van de reflectie (toeval?). Om dit te doen, moeten we eerst het ETBR "positioneren":
#ETBR, #refl color: # 004; font-family: Impact, 'Arial Black', Helvetica, Arial, sans-serif; text-transform: hoofdletters; lettergrootte: 200 px; achtergrondkleur: #FFE; lettertype: vet; opvulling: 30px; weergave: inline-block; box-shadow: rgba (255,255,240, .2) 0 0 200px 100px, rgba (255,255,240, .3) 0 0 40px, inzet rgba (0,0,0, .8) 0 0 20px; grensradius: 30px; positie: relatief;
Dit verandert de positie niet echt, maar is gepositioneerd. Nu:
#refl positie: absoluut; top 100%; links: 0;
De bovenkant van de reflectie is gerelateerd aan de hoogte en de positie van de ETBR. 0% geeft ze dezelfde top, 200% laat een gat zo groot als de hoogte van de ETBR en 100% plaatst de top van de reflectie onderaan het ETBR. Links is hetzelfde, maar neemt het percentage van de breedte.
Fiddle | Volledig scherm
Bijna elke veelgebruikte browser heeft deze functies, van IE6 tot Google Chrome. De implementatie is echter anders. Moderne browsers zijn erg eenvoudig, voor elke eigenschap één eigenschap: transformeren, vervagen en dekking. We zullen ook boksschaduw gebruiken, maar eerst spiegelen.
#refl positie: absoluut; top 100%; links: 0; -moz-transform: scaleY (-1); -webkit-transform: scaleY (-1); -ms-transformatie: scaleY (-1);
Met transformatie kunnen we een element aanpassen aan elk parallellogram dat u maar kunt bedenken. Heel veel parallellogrammen, dat weet ik. Maar we hoeven alleen de weerspiegeling te spiegelen, dus laten we de meeste transformatiefuncties ongebruikt.
Elke ontwerper moet weten dat schaalvergroting met -1 op de Y-as hetzelfde is als spiegeling. Schalen op de Y-as is het vermenigvuldigen van de afstand tussen de bovenkant (en onderkant) en het midden. Als we met 2 op de Y-as schalen, is de afstand van de bovenkant tot het midden twee keer zo groot. Als je schaalt met -1, zal de afstand hetzelfde zijn, maar boven is waar de bodem was en onderaan was waar de bovenkant was. Gefeliciteerd, je weet hoe je moet spiegelen!
Alle moderne browsers zullen zeer snel filters, -webkit-filter of SVG-filters ondersteunen. FF, Opera & IE10 ondersteunen de laatste al, Safari en Chrome bouwen net de spanning op voordat ze worden vrijgegeven. Een van de SVG-filters is de goede oude Gaussiaanse vervaging. Het is traag, maar het is iets ...
Maak een bestand "filter.svg" in dezelfde map als style.css. De inhoud:
Formaliteiten, behalve regels 6 tot 8. Het filter "vervaging" (u mag het alles noemen) vervaagt 2 pixels horizontaal en 3 pixels verticaal. Terug naar het stylesheet!
#refl positie: absoluut; top 100%; links: 0; -moz-transform: scaleY (-1); -webkit-transform: scaleY (-1); -ms-transformatie: scaleY (-1); filter: url (filter.svg # vervaging); / * FF, IE10 & Opera * / -webkit-filter: vervagen (2px);
filter.svg # blur
betekent het element 'vervagen' in filter.svg. Als de ID van het filter 'anything' was, zou de URL dat zijn filter.svg # iets
. De vervagingsradius wordt gedefinieerd in het SVG-bestand. Webkit-browsers leggen dit allemaal in één regel.
Transparantie bestaat al veel langer, dus we hoeven maar één eigenschap te specificeren:
#refl positie: absoluut; top 100%; links: 0; -moz-transform: scaleY (-1); -webkit-transform: scaleY (-1); -ms-transformatie: scaleY (-1); filter: url (filter.svg # vervaging); / * FF, IE10 & Opera * / -webkit-filter: vervagen (2px); dekking: .25;
Ik kan het SVG-bestand niet in de fiddle stoppen. (Ik moet het goede voorbeeld geven, dus ik kan semantiek en presentatie niet combineren.) Het zou de dingen toch gecompliceerder maken ...) Maar ik maak SVG niet vervaagd ...
Fiddle | Volledig scherm
Het is niet compleet. Toen Apple de reflectie op de derde dag creëerde, was het bedoeld om minder reflecterend te zijn. De reflectie moet minder helder verder weg van het oppervlak zijn. Laat er duisternis zijn!
Dit werkt alleen als het oppervlak een effen kleur heeft en de kleur van het lettertype vergelijkbaar is met die van deze kleur: we verduisteren het door een nieuwe boxschaduw toe te voegen. Deze doosschaduw overschrijft de oude in de #ETBR, #refl
selector. We zullen dit tegengaan door de inzetschaduw van de oude selector opnieuw te melden. De tweede schaduw is de nieuwe schaduw. Onthoud dat elke schaduw die we aan de reflectie toevoegen, gespiegeld is.
#refl positie: absoluut; top 100%; links: 0; -moz-transform: scaleY (-1); -webkit-transform: scaleY (-1); -ms-transformatie: scaleY (-1); filter: url (filter.svg # vervaging); / * FF, Opera + IE10 * / -webkit-filter: vervaging (2px); / * webkit * / dekking: .25; box-shadow: inzet rgba (0,0,0, .8) 0 0 20px, inzet # 000 0 50px 100px; / * eerste schaduw is oud * /
De offset van de tweede schaduw is 50 pixels, maar het element is altijd gespiegeld na de schaduw wordt toegepast. De schaduw beweegt niet naar beneden, hij komt omhoog.
Kijk hier eens even naar:
Fiddle | Volledig scherm
Super goed! Bekijk het nu met IE8 (of geloof me): het zijn in feite twee exemplaren van het ETBR boven elkaar, die niet gespiegeld, transparant of wazig zijn.
We hebben een aantal voorwaardelijke opmerkingen toegevoegd toen we begonnen; drie groepen.
Als IE9 de nieuwe dingen niet zou ondersteunen, zou het veel eenvoudiger zijn. (Begrijp me niet verkeerd, ik ben blij dat Internet Explorer probeert te veranderen, maar het zou eenvoudiger zijn ...) En om het gecompliceerder te maken, zijn er verschillen tussen smerige filters in IE9 en IE8. Genoeg van het klagen, laten we er iets aan doen. Voeg voor elke groep een #refl selector toe en verplaats de dekkingseigenschap naar modern.
#refl positie: absoluut; top 100%; links: 0; -moz-transform: scaleY (-1); -webkit-transform: scaleY (-1); -ms-transformatie: scaleY (-1); filter: url (filter.svg # vervaging); / * FF, Opera + IE10 * / -webkit-filter: vervaging (2px); / * webkit * / vakje-schaduw: inzet rgba (0,0,0, .8) 0 0 20px, inzet # 000 0 50px 100px; .modern #refl opacity: .25; .ie9 #refl .oldie #refl
Filamorfilters houden niet van de dekking van CSS2. En als we het over vuile filters hebben, gaan we deze gebruiken:
DXImageTransform.Microsoft.BasicImage
stelt ons in staat de afbeelding te spiegelen en de dekking te veranderenDXImageTransform.Microsoft.MotionBlur
en DXImageTransform.Microsoft.MotionBlur
is geweldig.DXImageTransform.Microsoft.Gradient
als een vervanging voor de tweede doosschaduw.Het eerste filter, BasicImage, heeft eigenlijk de eigenschap "mirror"! JA! Helaas is het instellen van deze eigenschap op 1 spiegels van de inhoud horizontaal, niet verticaal. Maar dat betekent niet dat het voor ons nutteloos is. Een element 180 ° draaien en horizontaal spiegelen, is hetzelfde als verticaal spiegelen. En dit is mogelijk:
.oldie #refl filter: progid: DXImageTransform.Microsoft.BasicImage (mirror = 1, rotation = 2);
Deze rotatie wordt niet gemeten in graden: 0 is 0 °, 1 is 90 °, 2 is 180 ° en 3 is 270 °. Alleen de oudjes hebben dit nodig. IE9 ondersteunt -ms-transformatie
.
We kunnen de dekking in hetzelfde filter specificeren ...
.ie9 #refl -ms-filter: "progid: DXImageTransform.Microsoft.BasicImage (opacity = .25);" .oldie #refl filter: progid: DXImageTransform.Microsoft.BasicImage (mirror = 1, rotation = 2, onacity = .35);
IE9 (en IE8, maar ik denk dat Internet Explorer al voldoende aandacht krijgt) ondersteunt -ms-filter. De waarde is één grote reeks. Dit zorgt voor begrip door de andere browsers (Firefox gaat elke vrijdag naar een psychiater vanwege Internet Explorer).
... maar we hebben een nieuw filter nodig voor de vervaging. Meerdere filters, als we het er goed willen laten uitzien. Geen komma's, nee filter:
s tussen de filters, alleen een spatie of een nieuwe regel. -ms-filter krijgt geen nieuwe regels meer ...
.ie9 #refl -ms-filter: "progid: DXImageTransform.Microsoft.BasicImage (opacity = .25) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow =" false ") progid: DXImageTransform.Microsoft.MotionBlur (sterkte = 15, richting = 0) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow = "false"); " .oldie #refl filter: progid: DXImageTransform.Microsoft.BasicImage (mirror = 1, rotation = 2, onacity = .35) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow = "false") progid : DXImageTransform.Microsoft.MotionBlur (sterkte = 15, richting = 0) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow = "false");
Als we het eenmaal vervagen met een straal van 6 pixels, lijkt het alsof iemand 4 exemplaren van de reflectie heeft genomen en een 6 pixels boven, een 6 pixels onder, een 6 pixels naar links en een 6 pixels naar rechts heeft verplaatst. Als je wilt pronken in de pub, moet je de naam weten: Box Blur. Door iteraties toe te voegen (vervaagt het vaag) wordt Box Blur weergegeven als een normale vervaging. De tweede iteratie is bewegingsonscherpte, omdat het er goed uitziet.
Fiddle | Volledig scherm
Deze keer zijn niet één, maar twee dingen fout:
Ten tweede het eerste probleem: omdat de oldies geen box-shadow ondersteunen, gebruiken we een smerige alfagradiënt als vervanging. Dit zijn, voor zover ik weet, de eerste RGBA-achtige waarden in CSS, maar als de w3c-specificaties helemaal niets zeiden over rgba-waarden in die tijd, luisterde Internet Explorer niet. Ze gebruikten 8 hexadecimale plaatsen in plaats van 6. De eerste twee stellen de alfa voor; smerige hellingen nemen ARGB in plaats van RGBA, wat, moet ik toegeven, veel beter klinkt:
.ie9 #refl -ms-filter: "progid: DXImageTransform.Microsoft.BasicImage (opacity = .25) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow =" false ") progid: DXImageTransform.Microsoft.MotionBlur (sterkte = 15, richting = 0) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow = "false"); " .oldie #refl filter: progid: DXImageTransform.Microsoft.Gradient (startColorstr = # 99000000, endColorstr = # 00000000) progid: DXImageTransform.Microsoft.BasicImage (mirror = 1, rotation = 2, onacity = .35) progid: DXImageTransform .Microsoft.Blur (PixelRadius = '3', MakeShadow = "false") progid: DXImageTransform.Microsoft.MotionBlur (strength = 15, direction = 0) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow = " false ");
Het verloop moet ook vervaagd zijn, dus dat is de eerste keer. Filthy Filterverlopen zijn standaard vertikaal. startColorstr
is de verloopkleur bovenaan en startColorstr
de kleur aan de onderkant, maar het is gespiegeld! # 99000000 is hetzelfde als rgba (0, 0, 0, 153). Let op: hoe hoger we de dekking van het verloop instellen, hoe lager de dekking van de reflectie lijkt te zijn.
De positionering is gewoon een kwestie van vallen en opstaan. Omdat de reflectie al in percentages is ingesteld, kunnen we deze niet binnen de pixel aanpassen met de eigenschappen left en top. In plaats daarvan gebruiken we de marge:
.ie9 #refl margin-top: 20px; margin-left: -10px; -ms-filter: "progid: DXImageTransform.Microsoft.BasicImage (opacity = .25) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow =" false ") progid: DXImageTransform.Microsoft.MotionBlur (sterkte = 15 , richting = 0) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow = "false"); " .oldie #refl margin-top: -20px; marge links: -7px; filter: progid: DXImageTransform.Microsoft.Gradient (startColorstr = # 99000000, endColorstr = # 00000000) progid: DXImageTransform.Microsoft.BasicImage (mirror = 1, rotation = 2, onacity = .35) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow = "false") progid: DXImageTransform.Microsoft.MotionBlur (strength = 15, direction = 0) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow = "false");
Fiddle | Volledig scherm
We zullen twee kleine dingen veranderen voordat je je tijd besteedt aan iets beters, zoals het kijken naar niezen panda's op youtube.
De oplossingen:
Hier is het CSS-bestand. De laatste wijzigingen zijn gemarkeerd:
style.css
html height: 100%; body text-align: center; regelhoogte: 1; marge: 0; opvulling: 0; achtergrondkleur: # 000; hoogte: 100%; p line-height: 1.2; #plane padding-top: 5%; links: 0; top 10%; breedte: 100%; onderkant: 0; minimale breedte: 1080 px; minimale hoogte: 600 px; positie: absoluut; overloop verborgen; overflow-x: zichtbaar; #ETBR, #refl kleur: # 004; font-family: Impact, 'Arial Black', Helvetica, Arial, sans-serif; text-transform: hoofdletters; lettergrootte: 200 px; achtergrondkleur: #FFE; lettertype: vet; opvulling: 30px; weergave: inline-block; box-shadow: rgba (255,255,240, .2) 0 0 200px 100px, rgba (255,255,240, .3) 0 0 40px, inzet rgba (0,0,0, .8) 0 0 20px; grensradius: 30px; positie: relatief; #refl positie: absoluut; z-index: -1; top 100%; links: 0; -moz-transform: scaleY (-1); -webkit-transform: scaleY (-1); -ms-transformatie: scaleY (-1); filter: url (filter.svg # vervaging); / * FF, Opera + IE10 * / -webkit-filter: vervaging (2px); / * webkit * / vakje-schaduw: inzet rgba (0,0,0, .8) 0 0 20px, inzet # 000 0 50px 100px; .modern #refl opacity: .25; .ie9 #refl margin-top: 20px; margin-left: -10px; -ms-filter: "progid: DXImageTransform.Microsoft.BasicImage (opacity = .25) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow =" false ") progid: DXImageTransform.Microsoft.MotionBlur (sterkte = 15 , richting = 0) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow = "false"); " .oldie #refl margin-top: -20px; marge links: -7px; filter: progid: DXImageTransform.Microsoft.Gradient (startColorstr = # 99000000, endColorstr = # 00000000) progid: DXImageTransform.Microsoft.BasicImage (mirror = 1, rotation = 2, onacity = .35) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow = "false") progid: DXImageTransform.Microsoft.MotionBlur (strength = 15, direction = 0) progid: DXImageTransform.Microsoft.Blur (PixelRadius = '3', MakeShadow = "false");
index.html
CSS3 reflecties reflectiereflectie
filter.svg
En dat is alles! Dit is de laatste Fiddle, zonder de vervaging van het SVG-filter.
Fiddle | Volledig scherm
Als iets extra's, hier is een pure CSS (behalve de sterren op de achtergrond) die met deze techniek op de Mac Dock staan.
Ik hoop dat je deze tutorial leuk vond en ik hoop dat je iets nieuws hebt geleerd. Laat gerust vragen achter in de comments!