Efeito de sobreposição turva do iOS 7 usando CSS?


161

Parece que a sobreposição da Apple é mais do que apenas uma transparência. Alguma idéia de como obter esse efeito com CSS e possivelmente com JS?

Mais do que apenas transparência


2
Uma preocupação mais premente na minha opinião é como configurar um elemento que aplica um desfoque dinâmico a qualquer objeto por trás dele. Portanto, se você tivesse um objeto que pudesse deslocar e aplicar zoom, o elemento na parte superior embaçaria dinamicamente com baixo desempenho.
Rhodes

1
Veja também esta pergunta para um problema semelhante.
Keith

43
Acho que talvez seja mais preocupante que isso seja desejado como um 'recurso IOS7', enquanto a interface do Windows Vista Aero faz exatamente a mesma coisa com seus cromos de janela desde 2006.
Niels Keurentjes

1
@NielsKeurentjes Heh, um ponto verdadeiro. Eu incorporei o efeito em um design alguns anos atrás, depois de me inspirar no Windows. No entanto, naquela época, segui a rota decididamente mais simples de apenas inserir o efeito nas imagens. ryanwilliams.co.uk/previews/made2race/1.html
Ryan Williams

Respostas:


145

É possível com CSS3:

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

Exemplo aqui => jsfiddle


119
Isso não atinge o efeito, como no iOS7, onde um elemento desfoca partes do plano de fundo.
Design by Adrian

9
Eu editei a minha jsFiddle, agora ele faz o truque como iOS7;) => efeito CSS3 iOS7
Cana

34
Como Adrian observou, o filtro apenas desfaz um elemento e é filho. Ele não pode ser usado para uma sobreposição para desfocar elementos-pai ou elementos adjacentes; portanto, o efeito iOS 7 não é possível com CSS.
21413 Jason As

10
Se você acha que está apenas desfocando para alcançar esse efeito, estará errado. Eu estou trabalhando em um repositório de código aberto simples que atinge este efeito usando tanto JS e CSS 3, fique atento :)
Ryan Brodie

5
Isso não funciona no FX - eles não suportam -moz-filter: blur(). Em vez disso, você precisa usar um filtro SVG, consulte minha resposta para obter detalhes.
Keith

48

Você me fez querer tentar, então tentei, veja o exemplo aqui:

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

Usando:

  1. Filtros CSS acelerados por HW
  2. JS para atribuição de classe e eventos de teclas de seta
  3. Propriedade de clipe de CSS de imagens

é isso aí.

Eu também acredito que isso poderia ser feito dinamicamente para qualquer tela se estiver usando a tela para copiar o domínio atual e desfocá-lo.


40

[Editar] No futuro (móvel) Safari 9, haverá -webkit-backdrop-filterexatamente isso. Veja esta caneta que fiz para mostrá-la.

Pensei nisso nas últimas 4 semanas e criei esta solução.

Demonstração ao vivo

[Editar] Eu escrevi um post mais aprofundado sobre CSS-Tricks

Essa técnica está usando regiões CSS, portanto, o suporte ao navegador não é o melhor no momento. ( http://caniuse.com/#feat=css-regions )

A parte principal desta técnica é separar o conteúdo do layout usando a região CSS. Primeiro defina um .contentelemento com flow-into:contente, em seguida, use a estrutura apropriada para desfocar o cabeçalho.

A estrutura do layout:

<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>

As duas partes importantes desse layout são .header__backgrounde .phone__content- esses são os contêineres para os quais o conteúdo deve fluir.

Usando regiões CSS, é simples como flow-from:content( .contentestá fluindo para a região nomeada content)

Agora vem a parte complicada. Queremos sempre transmitir o conteúdo através do .header__backgroundarquivo porque essa é a seção em que o conteúdo será manchado. (usando webkit-filter:blur(10px);)

Isto é feito através transfrom:translateY(-$HeightOfTheHeader)do .contentpara garantir que o conteúdo vai fluir sempre que o .header__background. Essa transformação sempre oculta algum conteúdo abaixo do cabeçalho. Corrigir isso é fácil adicionar

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

para acomodar a transformação.

Atualmente, ele está trabalhando em:

  • Chrome 29 ou superior (ative 'recursos experimentais do kit da web' / 'ative recursos experimentais da plataforma da web')
  • Safari 6.1 Semente 6
  • iOS7 ( lento e sem rolagem )

1
A demonstração ao vivo não funciona mais. O conteúdo vai abaixo o telefone, e eu recebo o erro "TypeError: sheet.addRule não é uma função" JS
BoffinBrain

Funciona bem com o Safari no Mac e iOS.
Carlos Silva

16

Agora isso é possível com o FireFox, graças ao atributo de estilo do elemento .

Esse atributo experimental permite usar qualquer conteúdo HTML como imagem de plano de fundo. Portanto, para criar o plano de fundo, você precisa de três sobreposições:

  1. Sobreposição simples com fundo sólido (para ocultar o conteúdo real da sobreposição).
  2. Sobreposição com um -moz-elementplano de fundo que define o conteúdo. Observe que o FX não suporta o filter: blur()atributo, portanto, precisamos de um SVG.
  3. Sobreposição com conteúdo não desfocado.

Então, junte:

Filtro de desfoque SVG (funciona em FX, outros navegadores poderiam usar filter:blur()):

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

Estilo de desfoque CSS:

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

Finalmente 3 camadas:

<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>

Então, para mudar isso, basta definir o background-position(exemplo em jQuery, mas você pode usar qualquer coisa):

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

Aqui está como JS Fiddle, apenas FX.


1
Sua solução é semelhante à que eu tinha em mente. Corrigi a falha ( jsfiddle.net/RgBzH/30 ) estendendo a fatia do fundo desfocado, para que o desfoque realmente ocorra com conteúdo real, não com fatias. Boa execução, pelo menos.
Pier Paolo Ramon

@PierPaoloRamon bom ajuste - se eu fosse usar isso, provavelmente estenderia um pouco o filtro SVG para incluir o aumento do brilho / contraste reduzido que o iOS7 também faz, mas FX significa apenas uma caixa de areia nesse momento. Eu fiz outra pergunta sobre soluções alternativas.
24513 Keith

BTW, sua solução traz apenas o blur ios7 para o Firefox OS, e isso é legal (eu tenho que testar isso).
Pier Paolo Ramon

14

Confira esta página de demonstração.
Esta demonstração usa html2canvas para renderizar documentos como uma imagem.

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

  1. Quando o link "Mostrar pop-up" é clicado, a função 'makePopup' é chamada.
  2. 'makePopup' executa o html2canvas para renderizar o documento como uma imagem.
  3. A imagem é convertida em string de URL de dados e é pintada como imagem de fundo do pop-up.
  4. A BG do pop-up é borrada pelo -webkit-filter: blur
  5. Anexe o pop-up ao documento.
  6. Enquanto você arrasta o pop-up, ele muda sua própria posição de fundo.

1
Forneça uma explicação sobre o que a demo realmente faz, pois, uma vez desativada, não ajudará em nada.
Jonathan Drapeau

Essa é uma ideia muito boa - infelizmente, o html2canvas é experimental demais para ser utilizado e provavelmente muito grande, a menos que as capturas de tela sejam o objetivo do seu aplicativo.
Keith

5
@JonathanDrapeau como você previu.
Mark

Woo! Eu amo apodrecer link!
Evolução-

Ainda usa imagens borradas, não vejo como isso funcionaria em algo como uma barra de navegação pegajosa.
maninak

10

Essa caneta que encontrei no outro dia parecia fazer muito bem, apenas um pouco de css e 21 linhas de javascript. Eu não tinha ouvido falar do comando cloneNode js até encontrar isso, mas funcionou totalmente para o que eu precisava, com certeza.

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

Detalhe: A. Basicamente, ele analisa a sua div de conteúdo e chama um cloneNode para criar uma duplicata que, em seguida, coloca dentro do estouro: objeto de cabeçalho oculto localizado na parte superior da página. B. Em seguida, ele simplesmente escuta a rolagem para que ambas as imagens pareçam coincidir e desfoque a imagem do cabeçalho ... e anexe o BAM. Efeito alcançado.

Não é realmente totalmente capaz de executar CSS, até que eles tenham o mínimo de capacidade de script embutido na linguagem.


Parece ótimo! Embora isso obviamente não funcione muito bem com conteúdo dinâmico, a menos que você atualize a duplicata toda vez que algo mudar - o que provavelmente seria um grande impacto no desempenho.
Nass 27/03

Suponho, mas não tenho certeza de onde você alteraria as imagens e tentaria fazer esse efeito? Se feito corretamente, não será um grande sucesso se você reciclar o clone. Talvez você possa detalhar um caso para conversar com isso? Digamos, por exemplo, que você faça um feed de imagem e deseje que algumas opções de menu surjam esse efeito para um menu de imagem para cada item ... execute isso ao revelar o painel e o painel que se sobrepõe parecerá com o pôster desejado. Adicione um reciclador pequenino para que o dom não duplique infinitamente as imagens toda vez que você abre menus e ele deve ter um bom desempenho.
usar o seguinte código

5
  • clonar o elemento que você deseja desfocar
  • anexá-lo ao elemento que você deseja colocar no topo (a janela fosca)
  • borrar elemento clonado com filtro de kit da web
  • verifique se o elemento clonado está posicionado absoluto
  • ao rolar o pai do elemento original, pegue scrollTop e scrollLeft
  • usando requestAnimationFrame, agora defina a transformação de kit da web dinamicamente para translate3d com os valores x e y para scrollTop e scrollLeft

O exemplo está aqui:

  • certifique-se de abrir no navegador da webkit
  • rolar para dentro da visualização do telefone (melhor com o mouse da apple ...)
  • veja rodapé embaçado em ação

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


4

ontem fiz uma demonstração rápida que realmente faz o que você está falando. http://bit.ly/10clOM9 esta demo faz o paralaxe com base no acelerômetro, para que funcione melhor no próprio iPhone. Basicamente, apenas copio o conteúdo que estamos sobrepondo em um elemento de posição fixa que fica desfocado.

nota: deslize para cima para ver o painel.

(Eu usei ids css horríveis, mas você entendeu)

#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

Não tenho muita certeza disso, acredito que o CSS não é capaz de fazer isso no momento

No entanto, Chris Coyier publicou um blog sobre uma técnica antiga com várias imagens para obter esse efeito, http://css-tricks.com/blurry-background-effect/


o instantâneo da tela na tela pode funcionar e 'bloquear' os ícones e o plano de fundo juntos antes de fazer isso, mas não consegui ver se o plano de fundo ainda tinha o efeito de paralaxe sob os ícones quando estava embaçado ... se não então, no minuto em que você começar a mover o painel de controle (sobreposição transparente), o dispositivo criará uma imagem da tela e executará esse truque por cima. lembre-se, eles não se limitam apenas a coisas baseadas na Web, como o canvas, ao fazer isso, pois está no nível do sistema operacional e podem não se limitar ao material do webkit.
Nosarious

3

Verifique este http://codepen.io/GianlucaGuarini/pen/Hzrhf Parece que faz o efeito sem duplicar a imagem de plano de fundo do elemento em si. Veja os textos estão borrando também no exemplo.

Vague.js

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

1
Ele duplica o conteúdo (há duas iframe no exemplo codepen é ligada). Tente clicar em um item de menu, o iframe desfocado não é atualizado.
Guglie

É uma espécie de solução de qualquer maneira.
Onur Çelik

2

Boas notícias

A partir de hoje, 11 de abril de 2020 , isso é facilmente possível com a backdrop-filterpropriedade CSS, que agora é um recurso estável no Chrome, Safari & Edge.

Eu queria isso em nosso aplicativo móvel híbrido, também disponível no Android / Chrome Webview e Safari WebView.

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

Exemplo de código:

Basta adicionar a propriedade CSS:

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

Exemplo 1 da interface do usuário

Veja-o trabalhando nesta caneta ou tente a demonstração:

#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>

Exemplo 2 da interface do usuário

Vamos dar um exemplo do aplicativo McDonald's, porque é bastante colorido. Tirei a captura de tela e a adicionei como pano de fundo no bodyaplicativo.

Eu queria mostrar um texto em cima dele com o efeito brilhante. Usando backdrop-filter: blur(20px);a sobreposição acima, pude ver isso: 😍

Captura de tela principal insira a descrição da imagem aqui


backdrop-filterainda não funciona automaticamente no Firefox. Duvido que os usuários ativem as opções para ativar backdrop-filterdeliberadamente apenas para ver esse efeito.
Richard

0

Eu tenho usado filtros svg para obter efeitos semelhantes para 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>
  • O atributo viewBox selecionará apenas a parte da sua imagem incluída que você deseja.
  • Apenas mude o filtro para o desejado, como no <feGaussianBlur stdDeviation="10"/>exemplo de Keith .
  • Use a <image ...>tag para aplicá-la a qualquer imagem ou até mesmo usar várias imagens.
  • Você pode criar isso com js e usá-lo como uma imagem ou usar o ID em seu css.

Você tem um exemplo disso em algum lugar? Talvez um jsFiddle ou similar? Obrigado
Blaker


-1

Aqui está minha opinião sobre isso com o jQuery. A solução não é universal, o que significa que seria necessário ajustar algumas posições e outras coisas, dependendo do design real.

Basicamente, o que eu fiz foi: ao disparar clone / remova todo o plano de fundo (o que deveria estar desfocado) para um contêiner sem conteúdo desfocado (que, opcionalmente, oculta o estouro se não tiver largura total) e posicione-o corretamente. Advertência é que, no redimensionamento da janela, a divisão borrada não corresponderá ao original em termos de posição, mas isso pode ser resolvido com algumas funções de redimensionamento na janela (sinceramente, não posso me preocupar com isso agora).

Eu realmente aprecio sua opinião sobre esta solução!

obrigado

Aqui está o violino , não testado no 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');
    }
});
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.