【问题标题】:Clipping or chamfering corners of image to see background剪裁或倒角图像以查看背景
【发布时间】:2013-01-03 07:23:04
【问题描述】:

我有一个设计,其中图像的角被切割成 45° 角。目前,它是通过使用绝对定位的跨度对其进行遮罩来实现的,该跨度具有透明的背景图像,其中角落“切割”为不透明的白色。这远非理想,首先是因为额外的跨度,其次是因为图像的背景不是均匀的白色。

我打算稍后生成透明的 PNG,但它会更优雅——考虑到图像是照片——使用 JPEG 和 CSS 的带宽更小。新的 CSS 掩码属性看起来很有希望,但据我了解,它不提供“屏蔽”元素背景的能力,是吗?

所以我的问题是,是否有任何我不知道的新 CSS 属性允许我这样做?

【问题讨论】:

    标签: css transparency mask clip


    【解决方案1】:

    使用变换(仅限 CSS3 解决方案)

    下面的方法有少量的不精确,它有两个“编码”的缺点:

    1. img 需要两个包装器
    2. 需要知道图像的大小(如果图像设置了大小或使用 javascript 提供宽度/高度信息,这可能并不总是一个缺点)。

    不过,对于 IE8 及更低版本,它确实可以很好地降级为方角。

    核心思想是调整外包装的大小并隐藏其溢出,适当调整大小、旋转和缩小内包装以创建倒角(也隐藏了溢出),然后反转旋转并放大,并在需要时重新定位嵌套在里面的img。该方法足够健壮,可以根据需要设置一些相当不错的边框,尽管在浏览器上呈现此类边框的质量会有所不同。

    Here's the fiddle.

    HTML(基本形式)

    span 可以是 div

    <span class="chamfer">
        <span>
            <img src="http://placehold.it/351x151" />
        </span>
    </span>
    

    CSS(基本形式)

    .chamfer {
        overflow: hidden;
        display: inline-block; /* could be "block" */
        margin: 25px; /* for demo only */
        /* Because of the rotations following, it seems like an odd
           number in width and height worked more consistently, as
           it gives a "middle" pixel by which to transform the rotation
           off of
        */
        width: 351px; /* width of image */
        height: 151px; /* height of image */
    }
    
    .chamfer > span {
        overflow: hidden;
        display: inline-block; /* could be "block" */
        -moz-transform-origin: 50% 50%;
        -webkit-transform-origin: 50% 50%;
        -o-transform-origin: 50% 50%;
        -ms-transform-origin: 50% 50%;
        transform-origin: 50% 50%;
        /* The rotation gets the chamfer angle
           the scale sets the "size" of the cut
           though not very precisely (exact px height
           is not possible to set explicitly.
        */
        -moz-transform: rotate(45deg) scale(.9);
        -webkit-transform: rotate(45deg) scale(.9);
        -o-transform: rotate(45deg) scale(.9);
        -ms-transform: rotate(45deg) scale(.9);
        transform: rotate(45deg) scale(.9);
        /* top/bottom padding is image width (351px)
           minus the image height (151px) = 200px divided by 2;
           if the image were taller than wide, then this
           would become (iH - iW) / 2 for the left/right padding 
        */
        padding: 100px 0; 
        margin-top: -100px; /* adjust for the padding */
        /* the following helped "square" the item better */
        width: 100%;
        height: 100%;
    }
    
    .chamfer img {
        display: inline-block; /* could be "block" */
        -moz-transform-origin: 50% 50%;
        -webkit-transform-origin: 50% 50%;
        -o-transform-origin: 50% 50%;
        -ms-transform-origin: 50% 50%;
        transform-origin: 50% 50%;
        /* The rotation is reversing the wrapper rotation
           to put the image horizontal again, while the scale
           is the inverse of the wrapper's scale, so here
           it is ( 1 / 0.9 ) = 1.11, to scale the image back
           up to correct size
        */
        -moz-transform: rotate(-45deg) scale(1.11);
        -webkit-transform: rotate(-45deg) scale(1.11);
        -o-transform: rotate(-45deg) scale(1.11);
        -ms-transform: rotate(-45deg) scale(1.11);
        transform: rotate(-45deg) scale(1.11);  
    }
    

    HTML(带有 2px 边框的小倒角)

    请参阅上面的小提琴,了解带有 10px 边框版本的“更大”倒角。

    当然,如果您的所有图像都获得了一个固定大小的边框,您只需像上面的基本 html 一样制作它,而不是像我在这里那样覆盖类。

    <span class="chamfer small b2">
        <span>
            <img src="http://placehold.it/351x151" />
        </span>
    </span>
    

    CSS(覆盖上面的基本 CSS)

    请参阅上面的小提琴,了解带有 10px 边框版本的“更大”倒角。

    当然,如果您的所有图像都获得了固定大小的边框,您只需将这些设置为基本 css 的值,而不是在此处定义的单独类中进行。

    .b2 * { 
        border: 2px solid black;
    }
    
    .chamfer.b2 { /* 2px border */
        width: 355px; /* 4px added for the 2px border */
        height: 155px; /* 4px added for the 2px border */
    }
    
    .chamfer.b2 > span {
        margin-top: -102px; /* the extra 2px is to accomodate top border of 2px */
        margin-left: -2px; /* this is for the 2px left border */
    }
    
    .chamfer.small > span {
        /* changed the scale for a smaller cut */
        -moz-transform: rotate(45deg) scale(.96);
        -webkit-transform: rotate(45deg) scale(.96);
        -o-transform: rotate(45deg) scale(.96);
        -ms-transform: rotate(45deg) scale(.96);
        transform: rotate(45deg) scale(.96);
    }
    
    .chamfer.small img {
        /* scale changed on wrapper to .96 so scale changes on 
           image to ( 1 / 0.96 ) = 1.042. 
        */
        -moz-transform: rotate(-45deg) scale(1.042);
        -webkit-transform: rotate(-45deg) scale(1.042);
        -o-transform: rotate(-45deg) scale(1.042);
        -ms-transform: rotate(-45deg) scale(1.042);
        transform: rotate(-45deg) scale(1.042);    
    }
    

    【讨论】:

    【解决方案2】:

    查看这篇博文(及其相应的 jsFiddle),作者使用多个背景渐变来实现我认为您想要做的事情:

    http://lea.verou.me/2011/03/beveled-corners-negative-border-radius-with-css3-gradients/

    div {
        background: #c00; /* fallback */
        background:
            -moz-linear-gradient(45deg,  transparent 10px, #c00 10px),
            -moz-linear-gradient(135deg, transparent 10px, #c00 10px),
            -moz-linear-gradient(225deg, transparent 10px, #c00 10px),
            -moz-linear-gradient(315deg, transparent 10px, #c00 10px);
        background:
            -o-linear-gradient(45deg,  transparent 10px, #c00 10px),
            -o-linear-gradient(135deg, transparent 10px, #c00 10px),
            -o-linear-gradient(225deg, transparent 10px, #c00 10px),
            -o-linear-gradient(315deg, transparent 10px, #c00 10px);
        background:
            -webkit-linear-gradient(45deg,  transparent 10px, #c00 10px),
            -webkit-linear-gradient(135deg, transparent 10px, #c00 10px),
            -webkit-linear-gradient(225deg, transparent 10px, #c00 10px),
            -webkit-linear-gradient(315deg, transparent 10px, #c00 10px);
    }
    
    div, div.round {
        background-position: bottom left, bottom right, top right, top left;
        -moz-background-size: 50% 50%;
        -webkit-background-size: 50% 50%;
        background-size: 50% 50%;
        background-repeat: no-repeat;
    }
    

    【讨论】:

    • 有点不清楚这如何在img 元素上起作用,因为背景将被图像本身覆盖。
    • 正确,这不是端到端的解决方案。您可能仍然需要绝对定位每个图像的跨度并使用纯色而不是透明(这类似于我认为已经完成的)。它只会使您不必使用实际图像,并且可以更可定制/更快地加载。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    相关资源
    最近更新 更多