Эффект размытого наложения в iOS 7 с использованием CSS?


161

Похоже, оверлей Apple - это больше, чем просто прозрачность. Любые идеи о том, как добиться этого эффекта с помощью CSS и, возможно, JS?

Больше, чем просто прозрачность


2
На мой взгляд, более насущной проблемой является настройка элемента, который применяет динамическое размытие к любому объекту позади него. Таким образом, если бы у вас был объект, который мог бы перемещаться и масштабироваться, элемент сверху динамически размывался бы при низком уровне производительности.
Родос

1
Смотрите также этот вопрос для аналогичной проблемы.
Кит

43
Я нахожу это, пожалуй, самым тревожным из-за того, что это требуется как «функция IOS7», в то время как интерфейс Windows Vista Aero делает то же самое со своими окнами с 2006 года.
Niels Keurentjes

1
@NielsKeurentjes Хех, правда. Я включил этот эффект в дизайн несколько лет назад, вдохновившись Windows. Однако в то время я пошел по более простому пути - просто запечатлел эффект на изображениях. ryanwilliams.co.uk/previews/made2race/1.html
Райан Уильямс

Ответы:


145

Это возможно с CSS3:

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

Пример здесь => jsfiddle


119
Это не дает такого эффекта, как в iOS7, где элемент размывает части фона.
Дизайн Адриана

9
Я отредактировал мой jsfiddle, теперь он работает так же, как IOS7;) => CSS3 эффект IOS7
Cana

34
Как заметил Адриан, фильтр только размывает элемент, и это дочерние элементы. Его нельзя использовать для наложения, чтобы размыть родительские элементы или смежные элементы, поэтому эффект iOS 7 невозможен с CSS.
Джейсон

10
Если вы думаете, что достижение этого эффекта просто размыто, вы ошибаетесь. Я работаю над простым репозиторием с открытым исходным кодом, который достигает этого эффекта, используя как JS, так и CSS 3, следите за обновлениями :)
Райан Броди,

5
Это не работает в FX - они не поддерживают -moz-filter: blur(). Вместо этого вы должны использовать SVG-фильтр, подробности смотрите в моем ответе.
Кит

48

Вы заставили меня хотеть попробовать, поэтому я сделал, посмотрите пример здесь:

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

С помощью:

  1. HW Ускоренные CSS фильтры
  2. JS для назначения классов и событий со стрелками
  3. Свойство CSS Картинки Картинки

Это оно.

Я также считаю, что это может быть сделано динамически для любого экрана, если использовать canvas для копирования текущего объекта и размывания его.


40

[Редактировать] В будущем (мобильный) Safari 9 будет именно -webkit-backdrop-filterдля этого. Посмотрите на эту ручку, которую я сделал, чтобы продемонстрировать это.

Я думал об этом последние 4 недели и придумал это решение.

Live Demo

[Редактировать] Я написал более глубокий пост на CSS-хитрости

В этом методе используются CSS-регионы, поэтому поддержка браузеров в данный момент не самая лучшая. ( http://caniuse.com/#feat=css-regions )

Ключевой частью этой техники является разделение контента от макета с помощью CSS Region. Сначала определите .contentэлемент с помощью, flow-into:contentа затем используйте соответствующую структуру, чтобы размыть заголовок.

Структура макета:

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

Две важные части этого макета .header__backgroundи .phone__content- это контейнеры, в которых должен передаваться контент.

Используя CSS Regions это просто как flow-from:content( .contentперетекает в названную область content)

Теперь самое сложное. Мы хотим всегда .header__backgroundпередавать содержимое через, потому что это раздел, где содержимое будет размыто. (используя webkit-filter:blur(10px);)

Это делается , чтобы убедиться , что содержание всегда будет течь , хотя . Это преобразование всегда скрывает некоторый контент под заголовком. Исправить это легко добавивtransfrom:translateY(-$HeightOfTheHeader).content.header__background

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

разместить для преобразования.

В настоящее время это работает в:

  • Chrome 29+ (включить «Экспериментальные функции-webkit» / «Включить-экспериментальные-функции-веб-платформы»)
  • Safari 6.1 Seed 6
  • iOS7 ( медленная и без прокрутки )

1
Живая демоверсия больше не работает. Содержание идет ниже телефона, и я получаю сообщение об ошибке JS «Ошибка типа: sheet.addRule не является функцией»
BoffinBrain,

Хорошо работает с Safari на Mac и iOS.
Карлос Сильва

16

Теперь это возможно с FireFox благодаря атрибуту style элемента .

Этот экспериментальный атрибут позволяет использовать любой контент HTML в качестве фонового изображения. Итак, для создания фона вам понадобятся три наложения:

  1. Простое наложение со сплошным фоном (чтобы скрыть реальное содержимое наложения).
  2. Наложение на -moz-elementфон, который устанавливает содержимое. Обратите внимание, что FX не поддерживает filter: blur()атрибут, поэтому нам нужен SVG.
  3. Наложение с не размытым содержимым.

Итак, соберите:

Фильтр размытия SVG (работает в FX, другие браузеры могут использовать filter:blur()):

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

CSS стиль размытия:

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

Наконец 3 слоя:

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

Затем, чтобы переместить это, просто установите background-position(пример в jQuery, но вы можете использовать что угодно):

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

Вот это как JS Fiddle, только FX.


1
Ваше решение похоже на то, что я имел в виду. Я исправил ошибку ( jsfiddle.net/RgBzH/30 ), расширив размытую часть фона, так что размытие фактически происходит на реальном контенте, а не нарезанном. Хорошее исполнение, в любом случае.
Пьер Паоло Рамон

@PierPaoloRamon хороший твик - если я собираюсь использовать это, я бы, вероятно, немного расширил SVG-фильтр, включив в него повышенную яркость / пониженную контрастность, что и в iOS7, но FX на этом этапе означает только «песочницу». Я задал еще один вопрос об обходных путях.
Кит

Кстати, ваше решение просто добавляет ios7-подобное размытие в Firefox OS, и это здорово (я должен это проверить).
Пьер Паоло Рамон

14

Проверьте эту демонстрационную страницу.
Эта демонстрация использует html2canvas для рендеринга документа в виде изображения.

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

  1. При нажатии на ссылку «Показать всплывающее окно» вызывается функция «makePopup».
  2. makePopup запускает html2canvas для рендеринга документа в виде изображения.
  3. Изображение преобразуется в строку data-url и раскрашивается как фоновое изображение всплывающего окна.
  4. BG всплывающего окна размыта фильтром -webkit: blur
  5. Добавьте всплывающее окно в документ.
  6. Когда вы перетаскиваете всплывающее окно, оно меняет свое собственное положение фона.

1
Пожалуйста, предоставьте объяснение того, что на самом деле делает демо, так как, когда оно выйдет из строя, оно не поможет.
Джонатан Драпо

Это действительно хорошая идея - к сожалению, html2canvas слишком экспериментален, чтобы на него можно было полагаться, и, вероятно, слишком велик, если только скриншоты не предназначены для вашего приложения.
Кит

5
вниз @JonathanDrapeau, как вы и предсказывали.
Марк

Woo! Я люблю ссылку гниль!
evolutionxbox

Все еще используется размытие изображений, я не понимаю, как это может работать на чем-то вроде липкой панели навигации.
Манинак

10

Это перо, которое я нашел на днях, казалось, прекрасно, просто немного CSS и 21 строчка JavaScript. Я не слышал о команде cloneNode js до тех пор, пока не нашел ее, но она точно работала для того, что мне было нужно.

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

Подробно: A. По сути, он просматривает ваш контент div и вызывает для него cloneNode, поэтому создает дубликат, который затем помещает в переполненный скрытый объект заголовка, расположенный в верхней части страницы. B. Затем он просто слушает прокрутку, так что оба изображения, кажется, совпадают и размывает изображение заголовка ... и BAM. Эффект достигнут.

На самом деле не полностью выполнимо в CSS, пока они не получат небольшую встроенную поддержку языка.


Выглядит отлично! Хотя это, очевидно, не будет работать слишком хорошо с динамическим контентом, если вы не будете обновлять дубликаты каждый раз, когда что-то меняется - что, вероятно, сильно ухудшит производительность.
Насс

Я полагаю, но не совсем уверен, где вы будете менять изображения и пытаться сделать этот эффект? Если все сделано правильно, это не должно быть большим успехом, если вы перерабатываете клон. Возможно, вы можете подробно рассказать об этом случае? Скажем, например, что вы создаете ленту изображений и хотите, чтобы некоторые пункты меню предлагали этот эффект для меню изображений для каждого элемента ... запустите его, когда откроете панель и панель, наложение которых будет выглядеть так, как хотел плакат. Добавьте крошечный утилизатор, чтобы dom не создавал бесконечные копии изображений каждый раз, когда вы открываете меню, и он должен работать хорошо.
Lux.Capacitor

5
  • клонировать элемент, который вы хотите размыть
  • добавить его к элементу, который вы хотите быть сверху (замерзшее окно)
  • размытие клонированного элемента с помощью webkit-фильтра
  • убедитесь, что клонированный элемент расположен абсолютно
  • при прокрутке родительского элемента оригинала, перехватите scrollTop и scrollLeft
  • используя requestAnimationFrame, теперь динамически устанавливаем webkit-transform для translate3d со значениями x и y в scrollTop и scrollLeft

Пример здесь:

  • обязательно откройте в webkit-браузере
  • прокрутка внутри телефона (лучше всего с яблочной мышью ...)
  • увидеть размытый колонтитул в действии

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


4

Вчера сделал короткую демонстрацию, которая на самом деле делает то, о чем вы говорите. http://bit.ly/10clOM9 эта демонстрация выполняет параллакс на основе акселерометра, поэтому лучше всего работает на самом iPhone. Я просто копирую содержимое, которое мы накладываем, в элемент фиксированной позиции, который становится размытым.

примечание: проведите пальцем вверх, чтобы увидеть панель.

(Я использовал ужасные идентификаторы CSS, но вы поняли идею)

#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

Я не очень уверен в этом, я считаю, что CSS не способен сделать это в данный момент

Однако Крис Койер писал о старой технике с несколькими изображениями для достижения такого эффекта, http://css-tricks.com/blurry-background-effect/


Снимок экрана на холст может сработать и «заблокировать» значки и фон перед тем, как сделать это, но я не смог увидеть, был ли фон по-прежнему иметь эффект параллакса под значками, когда он был размытым ... если это не так t, то в ту минуту, когда вы начинаете перемещать панель управления (прозрачное наложение), устройство создает изображение экрана и выполняет эту хитрость поверх. имейте в виду, что они не ограничиваются такими веб-вещами, как canvas, когда это делают, поскольку они находятся на уровне операционной системы, и могут не ограничиваться веб-наборами.
Ненавистный

3

Проверьте это http://codepen.io/GianlucaGuarini/pen/Hzrhf Похоже, что это делает эффект без дублирования фонового изображения элемента под себя. См тексты размыты и в примере.

Vague.js

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

1
Он дублирует содержимое (в приведенном вами примере с кодовым блоком есть два iframe). Попробуйте нажать на пункт меню, размытый iframe не обновляется.
Гугли

В любом случае, это своего рода решение.
Онур Челик

2

Хорошие новости

На сегодняшний день, 11 апреля 2020 года , это легко возможно благодаря backdrop-filterсвойству CSS, которое теперь является стабильной функцией в Chrome, Safari & Edge.

Я хотел это в нашем мобильном приложении Hybrid, которое также доступно в Android / Chrome Webview и Safari WebView.

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

Пример кода:

Просто добавьте свойство CSS:

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

UI Пример 1

Посмотрите, как работает эта ручка, или попробуйте демо:

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

Пример интерфейса 2

Давайте рассмотрим пример приложения McDonald's, потому что оно довольно красочное. Я взял его скриншот и добавил в качестве фона bodyмоего приложения.

Я хотел показать текст поверх него с глянцевым эффектом. Используя backdrop-filter: blur(20px);наложение выше этого, я смог увидеть это: 😍

Главный скриншот введите описание изображения здесь


backdrop-filterвсе еще не работает автоматически в Firefox, хотя. Я сомневаюсь, что пользователи будут включать варианты активации backdrop-filterнамеренно, просто чтобы увидеть этот эффект.
Ричард

0

Я использую фильтры SVG для достижения аналогичных эффектов для спрайтов

<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>
  • Атрибут viewBox выберет ту часть включенного изображения, которую вы хотите.
  • Просто измените фильтр на любой, который вы хотите, например, <feGaussianBlur stdDeviation="10"/>пример Кейта .
  • Используйте <image ...>тег, чтобы применить его к любому изображению или даже использовать несколько изображений.
  • Вы можете создать это с помощью JS и использовать его в качестве изображения или использовать идентификатор в вашем CSS.

У вас где-нибудь есть рабочий пример этого? Возможно, jsFiddle или подобное? Спасибо
Blaker


-1

Вот мой взгляд на это с помощью jQuery. Решение не является универсальным, то есть нужно изменить некоторые позиции и прочее в зависимости от фактического дизайна.

По сути, я сделал следующее: при клонировании триггера / удалите весь фон (что должно быть размытым) в контейнер с не размытым содержимым (которое, по желанию, имеет скрытое переполнение, если оно не имеет полной ширины) и поместите его правильно. Предостережение заключается в том, что при изменении размера окна размытый div будет не соответствовать оригиналу с точки зрения положения, но это может быть решено с помощью некоторой функции изменения размера окна (честно говоря, сейчас меня это не беспокоит).

Буду очень признателен за ваше мнение об этом решении!

Спасибо

Вот скрипка , не проверенная в 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');
    }
});
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.