2015-04-24 1 views
1

Je suis en train de créer, avec CSS pur, un effet où:CSS Filtre + couleur Niveaux de gris dégradé

  1. Une image d'arrière-plan de couleur est grayscaled et a un gradient appliquée; et

  2. En vol stationnaire, le gradient disparaît et la couleur apparaît en fondu.

Ci-dessous, je l'ai essayé deux techniques, dont chacun semble résoudre la moitié du problème. Le fallback serait de faire des versions en couleur et en niveaux de gris de l'image, mais évidemment je voudrais éviter cela pour minimiser les temps de chargement. J'apprécierais toutes les pensées que vous pourriez avoir - je suis un peu perplexe.

Merci!

Technique 1: dégradé, plus Arrière-plan-Blend Mode

Ici, j'ai appliqué le dégradé à l'image de fond directement et l'effet en niveaux de gris est atteint avec la combinaison d'un fond blanc et la Background- Propriété blend-mode. Il en résulte une image globalement plus sombre, mais c'est bien - le plus gros problème est que la transition ne semble pas fonctionner, et donc l'image saute d'un mode à l'autre instantanément plutôt que par un fondu lent.

https://jsfiddle.net/Lparts4j/1/

HTML:

<div class="test"></div> 

CSS:

.test { 
    width: 400px; 
    height: 400px; 
    background: linear-gradient(135deg, rgb(0, 47, 75) 0%, rgb(220, 66, 37) 80%), url("http://i.imgur.com/ulb7EVg.jpg"); 
    background-color: white; 
    background-blend-mode: multiply, luminosity; 
    background-size: cover; 
    -webkit-transition: all .5s ease-in-out; 
    -moz-transition: all .5s ease-in-out; 
    -o-transition: all .5s ease-in-out; 
    transition: all .5s ease-in-out; } 

.test:hover { 
    background: url("http://i.imgur.com/ulb7EVg.jpg"); 
    background-color: white; 
    background-blend-mode: normal; 
    background-size: cover; } 

Technique 2: Filtre Niveaux de gris, plus dégradé dans: Avant Élément

Ici, j'ai appliqué le dégradé avec un: be L'effet de gris est obtenu avec la propriété de filtre.

Le fondu fonctionne avec cette approche. Cependant, je suis incapable de combiner le dégradé avec le niveau de gris - le filtre en niveaux de gris finit par s'appliquer à l'élément: before, de sorte que le dégradé perd toute sa couleur. Dans le fichier jsfiddle, l'image de gauche comporte à la fois un filtre en dégradé et en nuances de gris, tandis que l'image de droite a uniquement un dégradé.

https://jsfiddle.net/548afgjf/4/

HTML:

<div class="img img-one"></div> 
<div class="img img-two"></div> 

CSS:

.img { 
    position: relative; 
    display: inline-block; 
    width: 300px; 
    height: 400px; } 

.img-one { 
    background: url('http://i.imgur.com/ulb7EVg.jpg') center center/cover no-repeat; 
    -webkit-filter: grayscale(100%); 
    filter: grayscale(100%); 
    -webkit-transition: all .5s ease-in-out; 
    -moz-transition: all .5s ease-in-out; 
    -o-transition: all .5s ease-in-out; 
    transition: all .5s ease-in-out; 
} 
.img-one:before { 
    content:''; 
    position: absolute; 
    top: 0; 
    right: 0; 
    bottom: 0; 
    left: 0; 
    opacity: .6; 
    background: rgb(0, 47, 75); 
    background: -moz-linear-gradient(-45deg, rgb(0, 47, 75) 0%, rgb(220, 66, 37) 100%); 
    background: -webkit-gradient(linear, left top, right bottom, color-stop(0%, rgb(0, 47, 75)), color-stop(100%, rgb(220, 66, 37))); 
    background: -webkit-linear-gradient(-45deg, rgb(0, 47, 75) 0%, rgb(220, 66, 37) 100%); 
    background: -o-linear-gradient(-45deg, rgb(0, 47, 75) 0%, rgb(220, 66, 37) 100%); 
    background: -ms-linear-gradient(-45deg, rgb(0, 47, 75) 0%, rgb(220, 66, 37) 100%); 
    background: linear-gradient(135deg, rgb(0, 47, 75) 0%, rgb(220, 66, 37) 100%); 
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#002f4b', endColorstr='#dc4225', GradientType=1); 
    -webkit-transition: opacity .6s ease-in-out; 
    -moz-transition: opacity .6s ease-in-out; 
    -o-transition: opacity .6s ease-in-out; 
    transition: opacity .6s ease-in-out; 
} 
.img-one:hover { 
    -webkit-filter: grayscale(0%); 
    filter: grayscale(0%); 
} 
.img-one:hover:before { 
    opacity: 0; } 

.img-two { 
    background: url('http://i.imgur.com/ulb7EVg.jpg') center center/cover no-repeat; 
    -webkit-transition: all .5s ease-in-out; 
    -moz-transition: all .5s ease-in-out; 
    -o-transition: all .5s ease-in-out; 
    transition: all .5s ease-in-out; 
} 
.img-two:before { 
    content:''; 
    position: absolute; 
    top: 0; 
    right: 0; 
    bottom: 0; 
    left: 0; 
    opacity: .6; 
    background: rgb(0, 47, 75); 
    background: -moz-linear-gradient(-45deg, rgb(0, 47, 75) 0%, rgb(220, 66, 37) 100%); 
    background: -webkit-gradient(linear, left top, right bottom, color-stop(0%, rgb(0, 47, 75)), color-stop(100%, rgb(220, 66, 37))); 
    background: -webkit-linear-gradient(-45deg, rgb(0, 47, 75) 0%, rgb(220, 66, 37) 100%); 
    background: -o-linear-gradient(-45deg, rgb(0, 47, 75) 0%, rgb(220, 66, 37) 100%); 
    background: -ms-linear-gradient(-45deg, rgb(0, 47, 75) 0%, rgb(220, 66, 37) 100%); 
    background: linear-gradient(135deg, rgb(0, 47, 75) 0%, rgb(220, 66, 37) 100%); 
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#002f4b', endColorstr='#dc4225', GradientType=1); 
    -webkit-transition: opacity .6s ease-in-out; 
    -moz-transition: opacity .6s ease-in-out; 
    -o-transition: opacity .6s ease-in-out; 
    transition: opacity .6s ease-in-out; 
} 
.img-two:hover { 
} 
.img-two:hover:before { 
    opacity: 0; } 
+0

Wow! Nous essayons tous deux de faire presque la même chose. Comme les pseudo éléments semblent hériter des filtres, je les ai séparés en ajoutant le filtre d'arrière-plan img et en niveaux de gris à: before, puis le dégradé à: after. En survol le: avant que le filtre ne passe à zéro, et que: après le dégradé s'estompe jusqu'à l'opacité zéro. Cela semble fonctionner, sauf que maintenant je recherche un type de backface blanc qui apparaît. Vous n'avez pas ce problème, donc vous pouvez avoir une longueur d'avance sur moi à cet égard;) Votre violon s'estompe aussi bien pour moi, alors soit vous l'avez réparé ou c'est un problème de navigateur? http://codepen.io/chasebank/pen/VLYPyq/ – Chase

+1

Chase, je pense que nous pourrions l'avoir. Ce scintillement blanc est lié à la face arrière et ne semble provenir que des navigateurs Webkit. Ajoutez "-webkit-transform-style: preserve-3d" à votre classe. Bien sûr, maintenant je dois faire face à la question de l'IE, mais la réponse ci-dessous pourrait donner l'exemple. – Platypus3333

+0

Génial! J'ai essayé backface-visibilité sans la moindre chance, et j'ai décidé à tort que préserver-3d n'avait rien à voir puisque je ne manipulais pas de perspective sur quoi que ce soit. Clairement j'avais tort! Maintenant que je suis à la recherche d'IE, les versions NO supportent les modes de fusion, ce qui est vraiment nul. Vous pouvez mélanger les filtres SVG, mais pas de support IE pour cela non plus. Cependant, Jeff a raison sur les niveaux de gris. Jusqu'à présent, le plus proche est un img en ligne, un filtre SVG qui le définit en niveaux de gris,: après un élément avec un dégradé, et un arrière-plan css img. Puis fondu le SVG et: après le vol stationnaire, révélant l'arrière-plan en couleur. Vérifiez à nouveau le stylo. – Chase

Répondre

1

j'avais essayé de faire l'effet d'échelle de gris dans le passé, et la seule façon que je pouvais obtenir de travailler ensemble tous les navigateurs devaient envelopper l'image dans un élément SVG, et appliquer des filtres SVG à l'élément. Vous devrez peut-être faire la même chose pour que cela fonctionne.

Sur votre page, vous devrez définir le filtre SVG (ceci ne fait que des niveaux de gris ...vous aurez besoin de rechercher comment coloriser aussi ...)

<svg> 
    <defs> 
    <filter id="greyscale"> 
     <feColorMatrix type="matrix" values="0.3333 0.3333 0.3333 0 0 
     0.3333 0.3333 0.3333 0 0 
     0.3333 0.3333 0.3333 0 0 
     0 0 0 1 0" /> 
    </filter> 
    </defs> 
</svg> 

Suivant envelopper votre image dans un élément SVG:

<svg class="filterThis" width="100px" height="100px"> 
    <image class="svgImg" xlink:href="image.png" height="100px" width="100px" /> 
</svg> 

Et appliquer le filtre dans votre CSS:

svg.filterThis .svgImg { 
    filter: url(#greyscale); 
} 
+0

on devrait éviter d'utiliser 'xlink: href' voir [ici] (https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href). –