Cropping or chamfering corners of an image to see the background

I have a design where the corners of the images are cut at an angle of 45 °. So far this has been achieved by masking it with an absolutely positioned span, which has a transparent background image with an angular “cut” in opaque white. This is far from ideal, first because of the additional interval, and secondly, because the background of the image is not uniform white.

I intend to create transparent PNGs later, but it would be more elegant and, given that images are photographs, they use JPEG and CSS less heavily. The new CSS mask property looked promising, but as I understand it, it does not provide the ability to "mask" against the background of the element, right?

So my question is: are there any new CSS properties that Im did not know and allowed me to do this?

+4
source share
2 answers

Using Transforms (CSS3 Only)

There is a small amount of inaccuracy in the following method and has two drawbacks to “coding”:

  • Two shells needed for img
  • You need to know the size of the image (which may not always be a drawback if the images are set in size or if javascript is used to indicate width / height information).

However, it decomposes beautifully back into square corners for IE8 and below.

The main idea is to size the outer shell and its overflow, correct size, rotate and scale the inner shell to create beveled corners (which also have overflow hidden), and then reverse rotation and scaling, and if necessary, insert img inside. This method is strong enough to get pretty decent borders if you want, although the rendering of such borders in browsers depends on the quality.

Here is the violin.

HTML (main form)

span can 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 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 bevel with 2px border)

See the above fiddle for a “larger” chamfer with a 10x version of the frame.

Of course, if all your images got a border with a fixed size, you would just do it the same as your base html above, and don't do class redefinition like I do here.

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

CSS (overrides basic css above)

See the above fiddle for a “larger” chamfer with a 10x version of the frame.

Of course, if all your images got a border with a fixed size, you would just do these 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); } 
+6
source

Check out this blog post (and its corresponding jsFiddle), where the author uses several background gradients to achieve what I think you want 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; } 
+1
source

All Articles