Efekt rozmytej nakładki w iOS 7 przy użyciu CSS?


161

Wygląda na to, że nakładka Apple to coś więcej niż tylko przezroczystość. Jakieś pomysły, jak osiągnąć ten efekt za pomocą CSS i ewentualnie JS?

Więcej niż tylko przejrzystość


2
Moim zdaniem bardziej palącym problemem jest ustawienie elementu, który zastosuje dynamiczne rozmycie do dowolnego obiektu za nim. Więc jeśli masz obiekt, który może przesuwać i powiększać, element na górze rozmazałby się dynamicznie przy niskiej wydajności.
Rodos,

1
Zobacz także to pytanie dotyczące podobnego problemu.
Keith,

43
Wydaje mi się, że najbardziej niepokojące jest to, że jest to pożądane jako „funkcja IOS7”, podczas gdy interfejs Windows Vista Aero robi dokładnie to samo z chromowanymi okienkami od 2006 roku.
Niels Keurentjes

1
@NielsKeurentjes Heh, prawdziwa uwaga. Wprowadziłem ten efekt do projektu kilka lat temu po zainspirowaniu się systemem Windows. Jednak wtedy wybrałem zdecydowanie prostszą drogę, polegającą na wtopieniu efektu w obrazy. ryanwilliams.co.uk/previews/made2race/1.html
Ryan Williams

Odpowiedzi:


145

Z CSS3 jest to możliwe:

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

Przykład tutaj => jsfiddle


119
Nie daje to efektu jak w iOS7, gdzie element rozmywa części tła.
Projekt: Adrian,

9
Edytowałem mój jsfiddle, teraz działa jak IOS7;) => CSS3 Efekt IOS7
Cana

34
Jak zauważył Adrian, filtr rozmywa tylko element i jego dzieci. Nie można go używać do nakładania, aby zamazać elementy nadrzędne lub sąsiednie, więc efekt iOS 7 nie jest możliwy w przypadku CSS.
Jason

10
Jeśli myślisz, że to tylko rozmycie, aby osiągnąć ten efekt, byłbyś w błędzie. Pracuję nad prostym repozytorium open source, które osiąga ten efekt przy użyciu zarówno JS, jak i CSS 3, bądźcie czujni :)
Ryan Brodie

5
To nie działa w FX - nie obsługują -moz-filter: blur(). Zamiast tego musisz użyć filtra SVG, zobacz moją odpowiedź po szczegóły.
Keith,

48

Sprawiłeś, że chciałem spróbować, więc tak zrobiłem, sprawdź tutaj przykład:

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

Za pomocą:

  1. HW Accelerated CSS filtry
  2. JS do przypisywania klas i zdarzeń klawiszy strzałek
  3. Obrazy CSS Clip Właściwość

Otóż ​​to.

Uważam również, że można to zrobić dynamicznie dla dowolnego ekranu, jeśli użyjesz płótna do skopiowania bieżącej domeny i zamazania jej.


40

[Edytuj] W przyszłości (mobilna) Safari 9 będzie -webkit-backdrop-filterwłaśnie do tego. Zobacz to długopis, który zrobiłem, aby go zaprezentować.

Myślałem o tym przez ostatnie 4 tygodnie i wpadłem na takie rozwiązanie.

Live Demo

[Edytuj] Napisałem bardziej dogłębny post na temat CSS-Tricks

Ta technika wykorzystuje regiony CSS, więc obsługa przeglądarki nie jest w tej chwili najlepsza. ( http://caniuse.com/#feat=css-regions )

Kluczową częścią tej techniki jest oddzielenie treści od układu za pomocą regionu CSS. Najpierw zdefiniuj .contentelement za pomocąflow-into:content a następnie użyj odpowiedniej struktury, aby rozmyć nagłówek.

Struktura układu:

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

Dwie ważne części tego układu to .header__backgroundi.phone__content - są to kontenery, przez które powinna przepływać zawartość.

Korzystanie z regionów CSS jest proste, ponieważ flow-from:content( .contentpłynie do nazwanego regionu content)

Teraz najtrudniejsza część. Chcemy zawsze przepływać zawartość przez .header__backgroundsekcję, ponieważ jest to sekcja, w której zawartość zostanie zamazana. (używając webkit-filter:blur(10px);)

Robi transfrom:translateY(-$HeightOfTheHeader)to, .contentaby upewnić się, że zawartość zawsze będzie przepływać przez .header__background. Ta transformacja zawsze ukrywa zawartość pod nagłówkiem. Naprawienie tego jest łatwe w dodawaniu

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

aby dostosować się do transformacji.

Obecnie to działa w:

  • Chrome 29+ (włącz „experimental-webkit-features” / „enable-experimental-web-platform-features”)
  • Rozstawienie Safari 6.1 6
  • iOS7 ( wolne i bez przewijania )

1
Demo na żywo już nie działa. Treść znajduje się pod telefonem i pojawia się błąd JS „TypeError: sheet.addRule is not a function”
BoffinBrain

Działa dobrze z Safari na Macu i iOS.
Carlos Silva,

16

Jest to możliwe w przypadku FireFox teraz dzięki atrybutowi stylu elementu .

Ten eksperymentalny atrybut umożliwia użycie dowolnej treści HTML jako obrazu tła. Tak więc, aby stworzyć tło, potrzebujesz trzech nakładek:

  1. Prosta nakładka z jednolitym tłem (w celu ukrycia prawdziwej zawartości nakładki).
  2. Nakładka z -moz-elementtłem, które ustawia zawartość. Zwróć uwagę, że FX nie obsługuje tego filter: blur()atrybutu, więc potrzebujemy pliku SVG.
  3. Nakładka z niewyraźną zawartością.

Więc połącz:

Filtr rozmycia SVG (działa w FX, inne przeglądarki mogą używać filter:blur() ):

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

Styl rozmycia CSS:

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

Wreszcie 3 warstwy:

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

Następnie, aby to przenieść, po prostu ustaw background-position (przykład w jQuery, ale możesz użyć wszystkiego):

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

Tutaj jest jako JS Fiddle, tylko FX.


1
Twoje rozwiązanie jest podobne do tego, które miałem na myśli. Naprawiłem usterkę ( jsfiddle.net/RgBzH/30 ), rozszerzając fragment rozmytego tła, więc rozmycie faktycznie występuje na rzeczywistej zawartości, a nie na pociętej. W każdym razie dobre wykonanie.
Pier Paolo Ramon

@PierPaoloRamon niezłe ulepszenie - zamierzałem tego użyć, prawdopodobnie rozszerzyłbym nieco filtr SVG, aby uwzględnić zwiększoną jasność / zmniejszony kontrast, który robi również iOS7, ale FX oznacza w tym momencie tylko piaskownicę. Zadałem inne pytanie dotyczące obejść.
Keith

BTW, twoje rozwiązanie po prostu wprowadza rozmycie podobne do ios7 do Firefox OS i to jest fajne (muszę to przetestować).
Pier Paolo Ramon

14

Sprawdź tę stronę demonstracyjną.
To demo wykorzystuje html2canvas do renderowania dokumentu jako obrazu.

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

  1. Po kliknięciu łącza „Pokaż wyskakujące okienko” wywoływana jest funkcja „makePopup”.
  2. „makePopup” uruchamia html2canvas do renderowania dokumentu jako obrazu.
  3. Obraz jest konwertowany na łańcuch data-url i malowany jako obraz tła wyskakującego okienka.
  4. Pole bg wyskakującego okienka jest rozmyte przez -webkit-filter: blur
  5. Dołącz wyskakujące okienko do dokumentu.
  6. Podczas przeciągania wyskakującego okienka zmienia swoje własne położenie w tle.

1
Proszę podać wyjaśnienie, co faktycznie robi demo, ponieważ po awarii nie będzie ono pomocne.
Jonathan Drapeau

To naprawdę fajny pomysł - niestety html2canvas jest po prostu zbyt eksperymentalny, aby można było na nim polegać i prawdopodobnie po prostu zbyt duży, chyba że zrzuty ekranu są tym, o co chodzi w twojej aplikacji.
Keith,

5
jego w dół @JonathanDrapeau, jak przewidziałeś.
Mark

Zabiegać! Uwielbiam gnicie linków!
evolutionxbox,

Nadal używa rozmywania obrazów, nie widzę, jak to może działać na czymś w rodzaju lepkiego paska nawigacyjnego.
maninak

10

Ten długopis, który znalazłem poprzedniego dnia, wydawał się robić to pięknie, tylko trochę css i 21 linii javascript. Nie słyszałem o poleceniu cloneNode js, dopóki tego nie znalazłem, ale na pewno działało to na pewno.

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

Szczegóły: A. W zasadzie przegląda element div z zawartością i wywołuje na nim cloneNode, więc tworzy duplikat, który następnie umieszcza w przepełnieniu: ukryty obiekt nagłówka znajdujący się na górze strony. B. Następnie po prostu nasłuchuje przewijania, więc oba obrazy wydają się pasować i rozmywa obraz nagłówka ... annnnd BAM. Efekt osiągnięty.

Nie do końca wykonalne w CSS, dopóki nie uzyskają odrobiny skryptowalności wbudowanej w język.


Wygląda świetnie! Chociaż oczywiście nie działałoby to zbyt dobrze w przypadku zawartości dynamicznej, chyba że aktualizujesz duplikat za każdym razem, gdy coś się zmieni - co prawdopodobnie byłoby dużym hitem wydajności.
Nass

Przypuszczam, ale nie do końca jestem pewien, gdzie będziesz zmieniać obrazy i próbować osiągnąć ten efekt? Jeśli zrobisz to poprawnie, nie powinno to być wielkim hitem, jeśli powtórzysz klon. Może mógłbyś szczegółowo opisać przypadek odwrotny do tego? Załóżmy na przykład, że tworzysz źródło obrazu i chcesz, aby niektóre opcje menu zawierały ten efekt dla menu obrazu dla każdego elementu ... uruchom to, gdy odsłaniasz panel i panel, który nakłada się wtedy tak, jak chciałby plakat. Dodaj mały recykler, aby dom nie powielał w nieskończoność obrazów za każdym razem, gdy otwierasz menu, i powinien działać dobrze.
Lux.Capacitor,

5
  • sklonuj element, który chcesz zamazać
  • dołącz go do elementu, na którym chcesz się znaleźć (matowe okienko)
  • rozmycie sklonowanego elementu za pomocą filtra webkit
  • upewnij się, że sklonowany element jest ustawiony bezwzględnie
  • podczas przewijania elementu nadrzędnego oryginalnego elementu przechwyć scrollTop i scrollLeft
  • używając requestAnimationFrame, ustaw dynamiczną transformację zestawu webkit na translate3d z wartościami x i y na scrollTop i scrollLeft

Przykład jest tutaj:

  • upewnij się, że otwierasz w przeglądarce webkit
  • przewiń widok telefonu (najlepiej z myszką Apple ...)
  • zobacz rozmytą stopkę w akcji

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


4

zrobiłem wczoraj szybkie demo, które faktycznie robi to, o czym mówisz. http://bit.ly/10clOM9 to demo wykonuje paralaksę w oparciu o akcelerometr, więc działa najlepiej na samym iPhonie. Po prostu kopiuję zawartość, którą nakładamy, do elementu o stałej pozycji, który się rozmywa.

uwaga: przesuń palcem w górę, aby zobaczyć panel.

(Użyłem okropnych identyfikatorów CSS, ale masz pomysł)

#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

Nie jestem tego pewien, uważam, że CSS nie jest w stanie tego zrobić w tej chwili

Jednak Chris Coyier napisał na blogu o starej technice z wieloma obrazami, aby osiągnąć taki efekt, http://css-tricks.com/blurry-background-effect/


migawka ekranu do płótna może działać i `` blokować '' ikony i tło razem przed zrobieniem tego, ale nie byłem w stanie sprawdzić, czy tło nadal miało efekt paralaksy pod ikonami, gdy było rozmyte ... jeśli tak się nie stało W momencie, gdy zaczniesz przesuwać panel sterowania (przezroczysta nakładka), urządzenie tworzy obraz ekranu i wykonuje tę sztuczkę na wierzch. pamiętaj, że nie ograniczają się one tylko do rzeczy opartych na sieci, takich jak płótno, ponieważ jest to na poziomie systemu operacyjnego i mogą nie ograniczać się do rzeczy z webkitami.
wścibski

3

Sprawdź ten http://codepen.io/GianlucaGuarini/pen/Hzrhf Wygląda na to, że działa bez duplikowania obrazu tła elementu pod nim. Zobacz też, jak w przykładzie teksty się zacierają.

Vague.js

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

1
To powiela treść (istnieją dwie iframes w codepen przykład ty linked). Spróbuj kliknąć pozycję menu, rozmyta ramka iframe nie aktualizuje się.
Guglie

W każdym razie jest to rozwiązanie.
Onur Çelik

2

Dobre wieści

Od dziś 11 kwietnia 2020 r. Jest to łatwo możliwe dzięki backdrop-filterwłaściwości CSS, która jest teraz stabilną funkcją w Chrome, Safari i Edge.

Chciałem to w naszej hybrydowej aplikacji mobilnej, która jest również dostępna w Android / Chrome Webview i Safari WebView.

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

Przykład kodu:

Po prostu dodaj właściwość CSS:

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

Przykład interfejsu użytkownika 1

Zobacz, jak działa w tym piórze lub wypróbuj demo:

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

Przykład interfejsu użytkownika 2

Weźmy przykład aplikacji McDonald's, ponieważ jest dość kolorowa. Zrobiłem zrzut ekranu i dodałem jako tło w bodymojej aplikacji.

Chciałem pokazać na nim tekst z błyszczącym efektem. Korzystając backdrop-filter: blur(20px);z nakładki powyżej, mogłem to zobaczyć: 😍

Główny zrzut ekranu wprowadź opis obrazu tutaj


backdrop-filternadal jednak nie działa automatycznie w przeglądarce Firefox. Wątpię, aby użytkownicy backdrop-filtercelowo włączali opcje aktywacji, aby zobaczyć ten efekt.
Richard

0

Używałem filtrów svg, aby osiągnąć podobne efekty dla duszków

<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>
  • Atrybut viewBox wybierze tylko żądaną część dołączonego obrazu.
  • Po prostu zmień filtr na dowolny, na <feGaussianBlur stdDeviation="10"/>przykład przykład Keitha .
  • Użyj <image ...>tagu, aby zastosować go do dowolnego obrazu, a nawet użyć wielu obrazów.
  • Możesz to zbudować za pomocą js i użyć go jako obrazu lub użyć identyfikatora w swoim css.

Czy masz gdzieś działający przykład? Może jsFiddle lub podobny? Dzięki
Blaker

0

To może ci pomóc !!

To dynamicznie zmienia tło, tak jak robi to IOS

.myBox {
  width: 750px;
  height: 500px;
  border: rgba(0, 0, 0, 0.5) 1px solid;
  background-color: #ffffff;
}

.blurBg {
  width: 100%;
  height: 100%;
  overflow: hidden;
  z-index: 0;
}

.blurBg img {
  -webkit-filter: blur(50px);
  margin-top: -150px;
  margin-left: -150px;
  width: 150%;
  opacity: 0.6;
}

-1

Oto moje spojrzenie na to z jQuery. Rozwiązanie nie jest uniwersalne, co oznacza, że ​​należałoby dostosować niektóre pozycje i rzeczy w zależności od faktycznego projektu.

Zasadniczo to, co zrobiłem, to: klonowanie na wyzwalaczu / usuwanie całego tła (co powinno być rozmyte) do pojemnika z niewyraźną zawartością (który opcjonalnie ma ukryte przepełnienie, jeśli nie ma pełnej szerokości) i ustawianie go poprawnie. Uwaga jest taka, że ​​przy zmianie rozmiaru okna rozmyty element div będzie niezgodny z oryginałem pod względem pozycji, ale można to rozwiązać za pomocą niektórych funkcji zmiany rozmiaru okna (szczerze mówiąc, nie mogłem się tym przejmować).

Byłbym bardzo wdzięczny za opinię na temat tego rozwiązania!

Dzięki

Oto skrzypce , nie testowane w 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');
    }
});
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.