Clipping or chamfering corners of image to see background

前端 未结 2 533
借酒劲吻你
借酒劲吻你 2020-12-17 04:13

I have a design where corners of images are cut in a 45° angle. For the time being, it’s achieved by masking it with an absolutely positioned span, which has a transparent b

相关标签:
2条回答
  • 2020-12-17 04:23

    Using Transforms (so CSS3 solution only)

    There is a small amount of imprecision in the following method, and it has two "coding" drawbacks:

    1. Two wrappers needed on the img
    2. Need to know the size of the image (which may not always be a drawback if images are set sizes or if javascript is used to give width/height info).

    It does, however, degrade nicely back to square corners for IE8 and lower.

    The core idea is to size the outer wrapper and hide its overflow, properly size, rotate, and scale down the inner wrapper to create the chamfered corners (which also has overflow hidden), then reverse the rotation and scale back up, and reposition if needed the img nested inside. The method is robust enough to get some fairly decent borders set up if desired, though the rendering of such borders on browsers varies as to quality.

    Here's the fiddle.

    HTML (basic form)

    The span could be a div.

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

    CSS (basic form)

    .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 (smaller chamfer with 2px border)

    See the above fiddle for a "larger" chamfer with 10px border version as well.

    Of course, if all your images were getting a set sized border, you would just make this just like your base html above, and not do override classes as I have here.

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

    CSS (overrides the basic css above)

    See the above fiddle for a "larger" chamfer with 10px border version as well.

    Of course, if all your images were getting a set sized border, you would just make these the values of your base css, and not do it in separate classes as defined here.

    .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);    
    }
    
    0 讨论(0)
  • 2020-12-17 04:46

    Check out this blog post (and its corresponding jsFiddle) where the author uses multiple background gradients to achieve what I think you're wanting to do:

    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;
    }
    
    0 讨论(0)
提交回复
热议问题