L'effet de superposition floue d'iOS 7 en utilisant CSS?


161

Il semble que la superposition d'Apple est plus qu'une simple transparence. Des idées sur la façon d'obtenir cet effet avec CSS et éventuellement JS?

Plus qu'une simple transparence


2
Une préoccupation plus urgente à mon avis est de savoir comment configurer un élément qui applique un flou dynamique à n'importe quel objet derrière lui. Donc, si vous aviez un objet qui pouvait effectuer un panoramique et un zoom, l'élément du dessus serait flou dynamiquement avec une faible performance.
Rhodes

1
Voir également cette question pour un problème similaire.
Keith

43
Je trouve peut-être plus inquiétant que cela soit voulu comme une `` fonctionnalité IOS7 '' alors que l'interface Windows Vista Aero fait exactement la même chose avec ses chromes de fenêtre depuis 2006.
Niels Keurentjes

1
@NielsKeurentjes Heh, un vrai point. J'ai incorporé l'effet dans un design il y a quelques années après m'être inspiré de Windows. Cependant, à l'époque, je suis allé pour la voie décidément plus simple de simplement cuire l'effet dans les images. ryanwilliams.co.uk/previews/made2race/1.html
Ryan Williams

Réponses:


145

C'est possible avec CSS3:

#myDiv {
    -webkit-filter: blur(20px);
    -moz-filter: blur(20px);
    -o-filter: blur(20px);
    -ms-filter: blur(20px);
    filter: blur(20px);
    opacity: 0.4;
}

Exemple ici => jsfiddle


119
Cela ne produit pas l'effet comme dans iOS7 où un élément brouille certaines parties de l'arrière-plan.
Design by Adrian le

9
J'ai édité mon jsfiddle, maintenant il fait l'affaire comme IOS7;) => Effet CSS3 IOS7
Cana

34
Comme l'a noté Adrian, le filtre ne brouille qu'un élément et ses enfants. Il ne peut pas être utilisé pour une superposition pour brouiller les éléments parents ou les éléments adjacents, de sorte que l'effet iOS 7 n'est pas possible avec CSS.
Jason

10
Si vous pensez que c'est juste flou pour obtenir cet effet, vous vous trompez. Je travaille sur un simple référentiel open source qui réalise cet effet en utilisant à la fois JS et CSS 3, restez à l'écoute :)
Ryan Brodie

5
Cela ne fonctionne pas dans FX - ils ne prennent pas en charge -moz-filter: blur(). Au lieu de cela, vous devez utiliser un filtre SVG, voir ma réponse pour plus de détails.
Keith

48

Vous m'avez donné envie d'essayer, alors je l'ai fait, regardez l'exemple ici:

http://codepen.io/Edo_B/pen/cLbrt

En utilisant:

  1. Filtres CSS accélérés HW
  2. JS pour l'attribution de classes et les événements de touches fléchées
  3. Images Propriété CSS Clip

c'est tout.

Je pense également que cela pourrait être fait de manière dynamique pour n'importe quel écran si vous utilisez une toile pour copier le dom actuel et le brouiller.


40

[Modifier] Dans le futur (mobile) Safari 9, il y aura -webkit-backdrop-filterexactement cela. Voir ça stylo que j'ai créé pour le mettre en valeur.

J'ai pensé à cela pendant les 4 dernières semaines et j'ai trouvé cette solution.

Démo en direct

[Edit] J'ai écrit un article plus détaillé sur CSS-Tricks

Cette technique utilise des régions CSS, donc la prise en charge du navigateur n'est pas la meilleure pour le moment. ( http://caniuse.com/#feat=css-regions )

L'élément clé de cette technique consiste à séparer le contenu de la mise en page à l'aide de la région CSS. Définissez d'abord un .contentélément avecflow-into:content , puis utilisez la structure appropriée pour brouiller l'en-tête.

La structure de mise en page:

<div class="phone">
 <div class="phone__display">
  <div class="header">
    <div class="header__text">Header</div>
    <div class="header__background"></div>
  </div>
  <div class="phone__content">
  </div>
 </div>
</div>

Les deux parties importantes de cette mise en page sont .header__backgroundet.phone__content - ce sont les conteneurs dans lesquels le contenu doit circuler.

En utilisant les régions CSS, c'est simple car flow-from:content( .contentcoule dans la région nommée content)

Maintenant vient la partie délicate. Nous voulons toujours faire passer le contenu à travers le .header__backgroundcar c'est la section où le contenu sera estompé. (en utilisant webkit-filter:blur(10px);)

Ceci est fait par transfrom:translateY(-$HeightOfTheHeader)le .contentpour garantir que le contenu circulera toujours à travers le .header__background. Cette transformation cache toujours du contenu sous l'en-tête. Résoudre ce problème est facile à ajouter

.header__background:before{
  display:inline-block;
  content:'';
  height:$HeightOfTheHEader
}

pour s'adapter à la transformation.

Cela fonctionne actuellement dans:

  • Chrome 29+ (activer "experimental-webkit-features" / "enable-experimental-web-platform-features")
  • Safari 6.1 Graine 6
  • iOS7 ( lent et sans défilement )

1
La démo en direct ne fonctionne plus. Le contenu passe sous le téléphone et j'obtiens l'erreur JS "TypeError: sheet.addRule is not a function"
BoffinBrain

Fonctionne bien avec Safari sur Mac et iOS.
Carlos Silva

16

C'est en quelque sorte possible avec FireFox maintenant grâce à l' attribut de style d' élément .

Cet attribut expérimental vous permet d'utiliser n'importe quel contenu HTML comme image d'arrière-plan. Donc, pour créer l'arrière-plan, vous avez besoin de trois superpositions:

  1. Superposition simple avec un arrière-plan uni (pour masquer le contenu réel de la superposition).
  2. Superposition avec un -moz-elementarrière-plan qui définit le contenu. Notez que FX ne prend pas en charge l' filter: blur()attribut, nous avons donc besoin d'un SVG.
  3. Superposition avec un contenu non flou.

Alors, rassemblez:

Filtre de flou SVG (fonctionne dans FX, d'autres navigateurs pourraient utiliser filter:blur()):

<svg>
  <defs>
    <filter id="svgBlur">
      <feGaussianBlur stdDeviation="10"/>
    </filter>
  </defs>
</svg>

Style de flou CSS:

.behind-blur 
{
    filter         : url(#svgBlur); 
    opacity: .4;
    background: -moz-element(#content);
    background-repeat: no-repeat;
}

Enfin 3 couches:

<div class="header" style="background-color: #fff">&nbsp;</div>
<div class="header behind-blur">&nbsp;</div>
<div class="header">
    Header Text, content blurs behind
</div>

Ensuite, pour déplacer cela, définissez simplement le background-position(exemple dans jQuery mais vous pouvez utiliser n'importe quoi):

$('.behind-blur').css({
    'background-position': '-' + left + 'px -' + top + 'px'
}); 

Ici, c'est comme un JS Fiddle, FX uniquement.


1
Votre solution est similaire à celle que j'avais en tête. J'ai corrigé le problème ( jsfiddle.net/RgBzH/30 ) en étendant la tranche de l'arrière-plan floue, de sorte que le flou se produit réellement sur le contenu réel, pas sur celui découpé. Bonne exécution, en tout cas.
Pier Paolo Ramon

@PierPaoloRamon joli tweak - si j'allais l'utiliser, j'étendrais probablement un peu le filtre SVG pour inclure l'augmentation de la luminosité / du contraste réduit qu'iOS7 fait aussi, mais FX ne signifie strictement que bac à sable à ce stade. J'ai posé une autre question sur les solutions de contournement.
Keith

BTW, votre solution apporte simplement un flou de type ios7 à Firefox OS, et c'est bien (je dois le tester).
Pier Paolo Ramon

14

Consultez cette page de démonstration.
Cette démo utilise html2canvas pour rendre le document sous forme d'image.

http://blurpopup.labs.daum.net/

  1. Lorsque le lien "Afficher la fenêtre contextuelle" est cliqué, la fonction 'makePopup' est appelée.
  2. 'makePopup' exécute html2canvas pour rendre le document sous forme d'image.
  3. L'image est convertie en chaîne data-url et elle est peinte comme image d'arrière-plan de la fenêtre contextuelle.
  4. Le bg de Popup est flouté par -webkit-filter: blur
  5. Ajoutez la fenêtre contextuelle au document.
  6. Pendant que vous faites glisser le popup, il change sa propre position d'arrière-plan.

1
Veuillez fournir une explication de ce que fait réellement la démo, car une fois qu'elle tombe en panne, elle ne sera d'aucune utilité.
Jonathan Drapeau

C'est une très bonne idée - malheureusement, html2canvas est encore trop expérimental pour être invoqué et probablement trop volumineux, à moins que les captures d'écran ne soient ce que votre application est.
Keith

5
c'est bas @JonathanDrapeau comme tu l'avais prédit
Mark le

Courtiser! J'adore la pourriture des liens!
evolutionxbox

Utilise toujours le flou sur les images, je ne vois pas comment cela pourrait fonctionner sur quelque chose comme une barre de navigation collante.
maninak

10

Ce stylo que j'ai trouvé l'autre jour semblait le faire à merveille, juste un peu de css et 21 lignes de javascript. Je n'avais pas entendu parler de la commande cloneNode js jusqu'à ce que je trouve cela, mais cela a totalement fonctionné pour ce dont j'avais besoin à coup sûr.

http://codepen.io/rikschennink/pen/zvcgx

Détail: A. Fondamentalement, il regarde votre div de contenu et invoque un cloneNode dessus afin de créer un doublon qu'il place ensuite à l'intérieur du débordement: objet d'en-tête caché assis en haut de la page. B. Ensuite, il écoute simplement le défilement afin que les deux images semblent correspondre et brouille l'image d'en-tête ... annnnd BAM. Effet obtenu.

Pas vraiment entièrement faisable en CSS jusqu'à ce qu'ils aient le petit peu de scriptabilité intégré dans le langage.


Ça a l'air génial! Bien que cela ne fonctionne évidemment pas très bien avec du contenu dynamique, à moins que vous ne mettiez à jour le doublon à chaque fois que quelque chose change - ce qui serait probablement un gros problème de performances.
Nass

Je suppose, mais vous ne savez pas vraiment où vous allez changer les images et essayer de faire cet effet? Si cela est fait correctement, cela ne devrait pas être un grand succès si vous recyclez le clone. Peut-être pouvez-vous détailler un cas à ce sujet? Supposons, par exemple, que vous créez un flux d'image et que vous souhaitez que certaines options de menu proposent cet effet pour un menu d'image pour chaque élément ... exécutez-le lorsque vous révélez le panneau et le panneau qui se superpose ressemblerait alors à l'affiche souhaitée. Ajoutez un petit recycleur pour que dom ne duplique pas les images à chaque fois que vous ouvrez des menus et qu'il fonctionne correctement.
Lux.Capacitor

5
  • cloner l'élément que vous souhaitez brouiller
  • ajoutez-le à l'élément que vous souhaitez placer au-dessus (la fenêtre givrée)
  • flou élément cloné avec webkit-filter
  • assurez-vous que l'élément cloné est positionné de manière absolue
  • lors du défilement du parent de l'élément d'origine, attrapez scrollTop et scrollLeft
  • en utilisant requestAnimationFrame, définissez maintenant le webkit-transform dynamiquement sur translate3d avec les valeurs x et y pour scrollTop et scrollLeft

L'exemple est ici:

  • assurez-vous d'ouvrir dans le navigateur webkit
  • faire défiler la vue du téléphone (mieux avec la souris Apple ...)
  • voir le pied de page flou en action

http://versie1.com/TEST/ios7/


4

a fait une démo rapide hier qui fait ce dont vous parlez. http://bit.ly/10clOM9 cette démo fait la parallaxe basée sur l'accéléromètre afin qu'elle fonctionne mieux sur un iPhone lui-même. Je copie simplement le contenu que nous superposons dans un élément de position fixe qui devient flou.

Remarque: faites glisser votre doigt vers le haut pour voir le panneau.

(j'ai utilisé d'horribles identifiants css mais vous voyez l'idée)

#frost{
 position: fixed; 
 bottom: 0; 
 left:0; 
 width: 100%; 
 height: 100px; 
 overflow: hidden;
 -webkit-transition: all .5s;
}
#background2{
 -webkit-filter: blur(15px) brightness(.2);
}

#content2fixed{
 position: fixed;
 bottom: 9px;
 left: 9px;
 -webkit-filter: blur(10px);
}

3

Je ne suis pas très sûr de cela, je pense que CSS n'est pas capable de le faire pour le moment

Cependant Chris Coyier a blogué sur une ancienne technique avec plusieurs images pour obtenir un tel effet, http://css-tricks.com/blurry-background-effect/


un instantané de l'écran sur la toile peut fonctionner et `` verrouiller '' les icônes et l'arrière-plan ensemble avant de faire cela, mais je n'ai pas pu voir si l'arrière-plan avait toujours l'effet de parallaxe sous les icônes lorsqu'il était flou ... si ce n'était pas le cas 't, puis dès que vous commencez à déplacer le panneau de contrôle (superposition transparente), l'appareil crée une image de l'écran et exécute cette supercherie. remarquez, ils ne sont pas seulement limités par des éléments basés sur le Web, comme le canevas, car c'est au niveau du système d'exploitation et peuvent ne pas être limités aux trucs du webkit.
nosarious le

3

Vérifiez celui-ci sur http://codepen.io/GianlucaGuarini/pen/Hzrhf On dirait qu'il fait l'effet sans dupliquer l'image de fond de l'élément sous lui-même. Voir les textes sont flous également dans l'exemple.

Vague.js

var vague = $blurred.find('iframe').Vague({
  intensity:5 //blur intensity
});
vague.blur();

1
Il duplique le contenu (il y a deux iframes dans l'exemple de codepen que vous avez lié). Essayez de cliquer sur un élément du menu, l'iframe floue ne se met pas à jour.
Guglie

C'est une sorte de solution de toute façon.
Onur Çelik

2

Bonnes nouvelles

À partir d'aujourd'hui, le 11 avril 2020 , cela est facilement possible avec la backdrop-filterpropriété CSS qui est maintenant une fonctionnalité stable dans Chrome, Safari et Edge.

Je voulais cela dans notre application mobile hybride donc également disponible dans Android / Chrome Webview et Safari WebView.

  1. https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter
  2. https://caniuse.com/#search=backdrop-filter

Exemple de code:

Ajoutez simplement la propriété CSS:

.my-class {
    backdrop-filter: blur(30px);
    background: transparent;     // Make sure there is not backgorund
}

Exemple d'interface utilisateur 1

Voyez-le fonctionner dans ce stylo ou essayez la démo:

#main-wrapper {
  width: 300px;
  height: 300px;
  background: url("https://i.picsum.photos/id/1001/500/500.jpg") no-repeat center;
  background-size: cover;
  position: relative;
  overflow: hidden;
}

.my-effect {
  position: absolute;
  top: 300px;
  left: 0;
  width: 100%;
  height: 100%;
  font-size: 22px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: black;
  -webkit-backdrop-filter: blur(15px);
  backdrop-filter: blur(15px);
  transition: top 700ms;
}

#main-wrapper:hover .my-effect {
  top: 0;
}
<h4>Hover over the image to see the effect</h4>

<div id="main-wrapper">
  <div class="my-effect">
    Glossy effect worked!
  </div>
</div>

Exemple d'interface utilisateur 2

Prenons un exemple de l'application McDonald's car elle est assez colorée. J'ai pris sa capture d'écran et ajouté comme arrière-plan dans lebody de mon application.

Je voulais montrer un texte par-dessus avec l'effet brillant. En utilisant backdrop-filter: blur(20px);la superposition au-dessus, j'ai pu voir ceci: 😍

Capture d'écran principale entrez la description de l'image ici


backdrop-filterne fonctionne toujours pas automatiquement dans Firefox. Je doute que les utilisateurs activent les options pour activer backdrop-filterdélibérément juste pour voir cet effet.
Richard

0

J'utilise des filtres svg pour obtenir des effets similaires pour les sprites

<svg id="gray_calendar" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 48 48 48">
  <filter id="greyscale">
    <feColorMatrix type="saturate" values="0"/>
  </filter>
  <image width="48" height="10224" xlink:href="tango48i.png" filter="url(#greyscale)"/>
</svg>
  • L'attribut viewBox sélectionnera uniquement la partie de votre image incluse que vous souhaitez.
  • Changez simplement le filtre pour celui que vous voulez, comme l' <feGaussianBlur stdDeviation="10"/>exemple de Keith .
  • Utilisez le <image ...> balise pour l'appliquer à n'importe quelle image ou même utiliser plusieurs images.
  • Vous pouvez créer cela avec js et l'utiliser comme image ou utiliser l'id dans votre css.

Avez-vous un exemple concret de cela quelque part? Peut-être un jsFiddle ou similaire? Merci
Blaker


-1

Voici mon point de vue à ce sujet avec jQuery. La solution n'est pas universelle, ce qui signifie qu'il faudrait modifier certaines positions et certains éléments en fonction de la conception réelle.

Fondamentalement, ce que j'ai fait est: lors du déclenchement, clonez / supprimez tout l'arrière-plan (ce qui devrait être flou) dans un conteneur avec un contenu non flou (qui, éventuellement, a un débordement caché s'il n'est pas pleine largeur) et positionnez-le correctement. La mise en garde est que lors du redimensionnement de la fenêtre, le div flou ne correspondra pas à l'original en termes de position, mais cela pourrait être résolu avec une fonction de redimensionnement de la fenêtre (honnêtement, cela ne me dérangeait pas maintenant).

J'apprécierais vraiment votre avis sur cette solution!

Merci

Voici le violon , non testé dans IE.

HTML

<div class="slide-up">
<div class="slide-wrapper">
    <div class="slide-background"></div>
    <div class="blured"></div>
    <div class="slide-content">
         <h2>Pop up title</h2>

        <p>Pretty neat!</p>
    </div>
</div>
</div>
<div class="wrapper">
<div class="content">
     <h1>Some title</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque molestie magna elit, quis pulvinar lectus gravida sit amet. Phasellus lacinia massa et metus blandit fermentum. Cras euismod gravida scelerisque. Fusce molestie ligula diam, non porta ipsum faucibus sed. Nam interdum dui at fringilla laoreet. Donec sit amet est eu eros suscipit commodo eget vitae velit.</p>
</div> <a class="trigger" href="#">trigger slide</a>

</div>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<filter id="blur">
    <feGaussianBlur stdDeviation="3" />
</filter>
</svg>

CSS

body {
margin: 0;
padding: 0;
font-family:'Verdana', sans-serif;
color: #fff;
}
.wrapper {
position: relative;
height: 100%;
overflow: hidden;
z-index: 100;
background: #CD535B;
}
img {
width: 100%;
height: auto;
}
.blured {
top: 0;
height: 0;
-webkit-filter: blur(3px);
-moz-filter: blur(3px);
-ms-filter: blur(3px);
filter: blur(3px);
filter: url(#blur);
filter:progid:DXImageTransform.Microsoft.Blur(PixelRadius='3');
position: absolute;
z-index: 1000;
}
.blured .wrapper {
position: absolute;
width: inherit;
}
.content {
width: 300px;
margin: 0 auto;
}
.slide-up {
top:10px;
position: absolute;
width: 100%;
z-index: 2000;
display: none;
height: auto;
overflow: hidden;
}
.slide-wrapper {
width: 200px;
margin: 0 auto;
position: relative;
border: 1px solid #fff;
overflow: hidden;
}
.slide-content {
z-index: 2222;
position: relative;
text-align: center;
color: #333333;
}
.slide-background {
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-color: #fff;
z-index: 1500;
opacity: 0.5;
}

jQuery

// first just grab some pixels we will use to correctly position the blured element
var height = $('.slide-up').outerHeight();
var slide_top = parseInt($('.slide-up').css('top'), 10);
$wrapper_width = $('body > .wrapper').css("width");
$('.blured').css("width", $wrapper_width);

$('.trigger').click(function () {
    if ($(this).hasClass('triggered')) { // sliding up
        $('.blured').animate({
            height: '0px',
            background: background
        }, 1000, function () {
            $('.blured .wrapper').remove();
        });
        $('.slide-up').slideUp(700);
        $(this).removeClass('triggered');
    } else { // sliding down
        $('.wrapper').clone().appendTo('.blured');
        $('.slide-up').slideDown(1000);
        $offset = $('.slide-wrapper').offset();
        $('.blured').animate({
            height: $offset.top + height + slide_top + 'px'
        }, 700);
        $('.blured .wrapper').animate({
            left: -$offset.left,
            top: -$offset.top
        }, 100);
        $(this).addClass('triggered');
    }
});
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.