【问题标题】:How to have an image with css filter:blur and sharp edges?如何使用 css 过滤器获得图像:模糊和锐利边缘?
【发布时间】:2013-06-20 11:54:35
【问题描述】:

我想在悬停时模糊图像。

问题在于图像的边缘也会模糊得令人不快。 在 Fiddle 中,您可以清楚地看到它的绿色背景。

如果我将图像缩放,即 1.2,它最终会解决问题,但在过渡期间仍然会出现模糊的边缘。

任何想法如何使这种效果具有锋利的边缘?

http://jsfiddle.net/d8Njs/

html:

<div class="item">
   <img src="http://placekitten.com/300"/>
</div>

css:

.item {
overflow: hidden;
width:300px;
height: 300px;
background: green;
}

.item img{
transition:all .5s ;
}

.item img:hover{
-webkit-filter: blur(5px);
/*skaling the image would help, but it still looks bad during the transition
-webkit-transform:scale(1.2); */
}

【问题讨论】:

  • 有趣的问题 - Webkit methinks 中的错误。
  • stackoverflow.com/questions/12224320/… 的相同问题供参考。
  • 使用-webkit-transform:scale(1.0) 进行缩放似乎应该比 1.2 更有效......但虽然它确实保持边缘清晰,但它对周围形成的令人不快的绿色效果没有任何作用过渡期间的图像。

标签: css


【解决方案1】:

我所知道的技术,在http://demosthenes.info/blog/534/Crossbrowser-Image-Blur得到了很好的解释:

1..如果您的图像的所有外边缘都具有相同的颜色,如上例所示,您可以将主体或容器元素的背景颜色设置为相同的颜色。 (仅供参考;并不真正适用于你,至少在你的小提琴中不适用)。

2..使用剪辑属性修剪图像的边缘。剪辑总是按以下顺序说明:

clip: rect( top, offset of right clip from left side, offset of bottom from top, left)

对于上面的示例,图像为 367px 宽 × 459 像素高,模糊为 2 个像素,因此剪辑应为:

clip: rect(2px,365px,457px,2px);

(请注意,clip 仅应用于具有 position: absolute 应用于它们的元素。如果您想在 IE8 和更早版本中获得支持,请记住将 px 放在值的末尾)。 (不知道您是在堆叠、网格还是只是标注等中布置照片。如果您可以接受绝对定位,可能是合适的。)

3..将图像包裹在比图像略小的包含元素(例如 a )中,对外部元素应用溢出:隐藏并将图像稍微向左和向上移动以消除可见模糊在那些边缘。

--

此外,在图像周围添加边框似乎至少在 Webkit 中有所帮助,但我尚未对其进行广泛测试。

.item img{
    transition:all .5s ;
    border:1px solid #000;
}

【讨论】:

  • 谢谢!不幸的是,在过渡过程中会出现模糊的边缘,即使它们最终由于剪辑或小于图像的容器等而消失。
  • 添加边框确实消除了模糊的边缘。
  • +1 用于添加边框。请注意,可以将边框设置为 transparent 并且仍然可以正常工作。
【解决方案2】:

一点 SVG:

<svg width="200" height="200" viewBox="10 10 280 280">
<filter id="blur">
 <feGaussianBlur stdDeviation="10"/>
</filter>
<image id="kitten" x="0" y="0" width="300" height="300" xlink:href="http://placekitten.com/300"/>
</svg>

还有一些 CSS:

 #kitten:hover { filter:url(#blur); }  

应该会产生预期的效果。 http://jsfiddle.net/5Jk6p/

#kitten:hover {
  filter:url(#blur);
}
<svg width="200" height="200" viewBox="10 10 280 280">
  <filter id="blur">
    <feGaussianBlur stdDeviation="10" />
  </filter>
  <image id="kitten" x="0" y="0" width="300" height="300" xlink:href="http://placekitten.com/300" />
</svg>

【讨论】:

    【解决方案3】:

    似乎设置剪辑或多或少地解决了这个问题。但是,过渡结束时有一个奇怪的效果。强制使用 GPU(通过 translateZ hack)似乎可以解决问题。

    CSS

    div {
        width:300px;
        height:300px;
        position: absolute;
    }
    .no {
        left: 400px;
        top: 10px;
    }
    
    .box img {
       transition: 2s -webkit-filter;
       position:absolute;
       left: -3px;
       top:-3px;
        clip: rect(5px 295px 295px 5px);
        -webkit-transform: translateZ(0px);
    }
    div img {
       transition: 2s -webkit-filter;
       position:absolute;
       left: -3px;
       top:-3px;
        clip: rect(5px 295px 295px 5px);
    }
    
    div img:hover{
        -webkit-filter: blur(8px);
    }
    

    demo with a comparative with and without the transform

    【讨论】:

      【解决方案4】:

      在花了一天的时间后,我能够创建一个蹩脚、丑陋、hacky 的解决方案。 可能不会在实际项目中使用它,但也许它可以激励其他人在我的解决方案中使用某些东西,但让它不那么难看。 至少最终结果看起来像我想要的那样!

      使用白色边框和 box-sizing:border-box,然后一些边距我能够得到最终结果有锐利的边缘,3/4 的边缘在过渡期间不显示绿色背景。如果有人能找出为什么在过渡期间某些边缘会随着背景褪色,那可能会有所帮助。

      http://jsfiddle.net/fVNqm/2/

      html:

      <div class="box">
          <img src="http://placekitten.com/300" />
         <div class="tophack"></div>
      </div>
      

      CSS:

      .box{
      box-sizing: border-box;
      position:relative;
      border:3px solid white;
      overflow: hidden;
      background:green;
      width:300px;
      height:300px;
      }
      
      div img {
      transition:.2s all;
      position:absolute;
      left: -3px;
      top:-3px;
      }
      
      div img:hover{
      filter: blur(2px);
      -webkit-filter: blur(2px);
      -moz-filter: blur(5px);
      -o-filter: blur(5px);
      -ms-filter: blur(5px);
      }
      
      .tophack{ 
      background:white;
      width:300px;
      height:3px;
      z-index:10;
      position:absolute;
      top: 0px;
      }
      

      仍然希望有更好的东西!

      【讨论】:

        【解决方案5】:

        将此添加到您的 CSS

        .item img{margin:0px 0px 0px -1px;} 
        

        【讨论】:

          猜你喜欢
          • 2023-03-17
          • 2016-10-07
          • 2015-03-26
          • 2014-09-02
          • 1970-01-01
          • 2015-07-16
          • 2019-07-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多