Zdefiniowane krawędzie z rozmyciem filtra CSS3

79

Ten kod zamazuje niektóre obrazy

img {
  filter: blur(5px);
  -webkit-filter: blur(5px);
  -moz-filter: blur(5px);
  -o-filter: blur(5px);
  -ms-filter: blur(5px);
}

Jednak krawędzie obrazu również ulegają rozmyciu. Czy można rozmazać obraz, zachowując zdefiniowane krawędzie? Jak wstawka, czy coś?

colmtuite
źródło

Odpowiedzi:

103

Można umieścić go w <div>z overflow: hidden;i ustawić <img>się margin: -5px -10px -10px -5px;.

Próbny: jsFiddle

Wynik

CSS

img {
    filter: blur(5px);
        -webkit-filter: blur(5px);
        -moz-filter: blur(5px);
        -o-filter: blur(5px);
        -ms-filter: blur(5px);
    margin: -5px -10px -10px -5px;
}

div {
    overflow: hidden;
}
​

HTML

<div><img src="http://placekitten.com/300" />​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​</div>​​​​​​​​​​​​
Myślenie Sztywne
źródło
1
@Moppy To nie działa w Chrome 23 / OS X dla mnie. Myślę, że marginjest to wymagane.
ThinkingStiff
1
@Moppy Ponieważ imgznajduje się wewnątrz divi blurprzekracza granice div. overflow: hidden;Odcina go.
ThinkingStiff
10
O co chodzi ze śmieciami na dole JSFiddle? Nie rozumiem, dlaczego GA śledzenie JSFiddle jest konieczne ...
Bojangles
1
@Bojangles, „śmieci” na dole obrazu w pliku jsfiddle znajdują się w samym obrazie .
uberdog
3
Czy istnieje sposób na zrobienie tego w przypadku obrazu tła? Chodzi o to, aby stworzyć rozmyty obraz tła z tekstem
Guy,
58

Udało mi się to zrobić z

transform: scale(1.03);

Właściwość zastosowana na obrazie. Z jakiegoś powodu w Chrome inne dostarczone rozwiązania nie działałyby, gdyby istniał jakiś względnie ustawiony element nadrzędny.

Sprawdź http://jsfiddle.net/ud5ya7jt/

W ten sposób obraz zostanie nieco powiększony o 3%, a krawędzie zostaną obcięte, co i tak nie powinno stanowić problemu na rozmytym obrazie. W moim przypadku zadziałało dobrze, ponieważ jako tło używałem obrazu o wysokiej rozdzielczości. Powodzenia!

João Josézinho
źródło
to jest ładne, proste i regulowane. działa idealnie w mojej sytuacji jsfiddle.net/ud5ya7jt/28, podczas gdy niektóre inne rozwiązania wydają się teraz zawodzić.
Jeannie
Dziękuję bardzo za to, właśnie tego szukałem :)
jeerbl
1
ustawienie rodzica na overflow: hiddenusunie paski przewijania! dzięki!
dimmg
1
Takie proste rozwiązanie!
Dotl
skala (1) działa, ale 1.03 jest tak, że przycinamy obraz o 3%, aby rozmazane krawędzie nie były tak łatwo zauważalne
João Josézinho
17

Używałem -webkit-transform: translate3d(0, 0, 0);z overflow:hidden;.

DOM:

<div class="parent">
    <img class="child" src="http://placekitten.com/100" />
</div>

CSS:

.parent {
    width: 100px;
    height: 100px;
    overflow: hidden;
    -webkit-transform: translate3d(0, 0, 0);
}
.child {
    -webkit-filter: blur(10px);
}

DEMO: http://jsfiddle.net/DA5L4/18/

Ta technika działa w Chrome34 i iOS7.1

Aktualizacja

http://jsfiddle.net/DA5L4/50/

jeśli używasz najnowszej wersji Chrome, nie musisz używać -webkit-transform: translate3d(0, 0, 0);hackowania. Ale to nie działa w Safari (webkit).

GeckoTang
źródło
@Razvan Cercelaru naprawdę? jaką wersję safari sprawdziłeś w moim demo? Działa w Mac Safari 7.
GeckoTang
Pracował dla mnie! Dzięki! (Chromium 50.0.2661.86 (64-bitowy) OSX)
iperdiscount
12

Możesz też zachować cały film, nie musisz niczego odcinać.
Możesz nakładać cienie wstawkowe na rozmyte na biało krawędzie.

To też wygląda naprawdę ładnie :)

Po prostu wklej ten kod do rodzica swoich filmów:

.parent {
    -webkit-box-shadow: inset 0 0 200px #000000;
       -moz-box-shadow: inset 0 0 200px #000000;
            box-shadow: inset 0 0 200px #000000;
}
GlabbichRulz
źródło
1
Działa wspaniale, żadna inna sugestia nie pomogła.
DGibbs,
2
W moim przypadku pomogło, ale nadal pozostawiało niepożądane rozmycie, więc dodałem dodatkową warstwę cienia w pudełku:box-shadow: inset 0 0 200px #000000, inset 0 0 200px #000000;
falsarella
6

W wielu sytuacjach, w których IMG można ustawić w pozycji: absolutnej , możesz użyć klipu, aby ukryć rozmyte krawędzie - a zewnętrzny DIV jest niepotrzebny.

img {
    filter: blur(5px);
        -webkit-filter: blur(5px);
        -moz-filter: blur(5px);
        -o-filter: blur(5px);
        -ms-filter: blur(5px);
    position: absolute;
    clip: rect(5px,295px,295px;5px);
}
genedronek
źródło
1
caniuse.com/#feat=css-clip-path tutaj przeglądarka obsługuje obcinanie. IE jest najlepszy 😆
Philip Giuliani
6

Po rozwiązaniu tego samego problemu dzisiaj, chciałbym przedstawić rozwiązanie, które (obecnie) działa w głównych przeglądarkach. Niektóre inne odpowiedzi na tej stronie działały kiedyś, ale ostatnie aktualizacje, niezależnie od tego, czy chodzi o przeglądarkę, czy system operacyjny, unieważniły większość / wszystkie z nich.

Kluczem jest umieszczenie obrazu w kontenerze i przekształcenie: przeskalowanie tego kontenera z jego przepełnienia: ukryty rodzic. Następnie rozmycie zostanie zastosowane na obrazie wewnątrz pojemnika, zamiast na samym pojemniku.

Działające skrzypce: https://jsfiddle.net/x2c6txk2/

HTML

<div class="container">
    <div class="img-holder">
        <img src="https://unsplash.it/500/300/?random">
    </div>
</div>

CSS

.container {
    width    : 90%;
    height   : 400px;
    margin   : 50px 5%;
    overflow : hidden;
    position : relative;
}

.img-holder {
    position  : absolute;
    left      : 0;
    top       : 0;
    bottom    : 0;
    right     : 0;
    transform : scale(1.2, 1.2);
}

.img-holder img {
    width          : 100%;
    height         : 100%;
    -webkit-filter : blur(15px);
    -moz-filter    : blur(15px);
    filter         : blur(15px);
}
rorymorris89
źródło
3

Tylko niewielka wskazówka do zaakceptowanej odpowiedzi, jeśli używasz pozycji bezwzględnej, ujemne marginesy nie będą działać, ale nadal możesz ustawić wartość ujemną górną, dolną, lewą i prawą na wartość ujemną i ukryć przepełnienie elementu nadrzędnego.

Odpowiedź o dodaniu klipu do pozycji obrazu bezwzględnego ma problem, jeśli nie znasz rozmiaru obrazu.

cn123h
źródło
2

Wstaw obraz wewnątrz za pomocą position: relative;ioverflow: hidden;

HTML

<div><img src="#"></div>

CSS

div {
    position: relative;
    overflow: hidden;
}
img {
    filter: blur(5px);
        -webkit-filter: blur(5px);
        -moz-filter: blur(5px);
        -o-filter: blur(5px);
        -ms-filter: blur(5px);
}

Działa to również w przypadku elementów o różnych rozmiarach, takich jak dynamiczne elementy DIV.

bpanatta
źródło
1

Możesz zapobiec nakładaniu się obrazu na jego krawędzie, przycinając obraz i stosując element wrapper, który ustawia efekt rozmycia na 0 pikseli. Tak to wygląda:

HTML

<div id="wrapper">
  <div id="image"></div>
</div>

CSS

#wrapper {
  width: 1024px;
  height: 768px;

  border: 1px solid black;

  // 'blur(0px)' will prevent the wrapped image
  // from overlapping the border
  -webkit-filter: blur(0px);
  -moz-filter: blur(0px);
  -ms-filter: blur(0px);
  filter: blur(0px);
}

#wrapper #image {
  width: 1024px;
  height: 768px;

  background-image: url("../images/cats.jpg");
  background-size: cover;

  -webkit-filter: blur(10px);
  -moz-filter: blur(10px);
  -ms-filter: blur(10px);
  filter: blur(10px);

  // Position 'absolute' is needed for clipping
  position: absolute;
  clip: rect(0px, 1024px, 768px, 0px);
}
Benny Neugebauer
źródło
1

Najprostszym sposobem jest dodanie przezroczystego obramowania do elementu div zawierającego obraz i ustawienie jego właściwości display na inline-block, tak jak to:

CSS:

div{
margin: 2rem;
height: 100vh;
overflow: hidden;
display: inline-block;
border: 1px solid #00000000;
}

img {
-webkit-filter: blur(2rem);
filter: blur(2rem);
}

HTML

<div><img src='https://images.unsplash.com/photo-1557853197-aefb550b6fdc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=375&q=80' /></div>

Oto kodepen przedstawiający to samo: https://codepen.io/arnavozil/pen/ExPYKNZ

arnavpanwar99
źródło
0

Możesz spróbować dodać obramowanie do innego elementu:

DOM:

<div><img src="#" /></div>

CSS:

div {
   border: 1px solid black;
}
img {
    filter: blur(5px);
}
Krycke
źródło
0

Okazało się, że w moim przypadku nie muszę dodawać owijki.

Właśnie dodałem -

margin: -1px;

lub

margin: 1px; // any non-zero margin
overflow: hidden;

Mój rozmyty element był absolutnie ustawiony.

brendangibson
źródło
volkerotto.net/2014/07/03/…
Mary Pieroszkiewicz
0

Oto rozwiązanie, które wymyśliłem, utrzymuje 100% obrazu i nie jest potrzebne żadne przycinanie:

Zasadniczo odwracam obraz w siatce 3x3, a następnie rozmywam wszystko, a następnie powiększam obraz środkowy, skutecznie tworząc jak powtarzające się krawędzie podczas rozmywania po efektach, to trochę dziwne, że css3 nie ma wbudowanych powtarzających się krawędzi.

Link do metody / kodu: Jak rozmyć obraz za pomocą CSS3 bez przycinania lub blaknięcia krawędzi?

Patrik Fröhler
źródło
1
Chociaż ten link może odpowiedzieć na pytanie, lepiej jest zawrzeć tutaj zasadnicze części odpowiedzi i podać link do odniesienia. Odpowiedzi zawierające tylko łącze mogą stać się nieprawidłowe, jeśli połączona strona ulegnie zmianie.
Arnon Zilca
Cóż, tak zabawne, że tak mówisz, bo właśnie zaktualizowałem ten post i tytuł, a to całkowicie zepsuło link tutaj x)
Patrik Fröhler
0

Jeśli używasz obrazu tła, najlepszy sposób, jaki znalazłem, to:

filter: blur(5px);
margin-top: -5px;
padding-bottom: 10px;
margin-left: -5px;
padding-right: 10px;
Elad Swissa
źródło