Clipping or chamfering corners of image to see background
Using Transforms (so CSS3 solution only)
There is a small amount of imprecision in the following method, and it has two "coding" drawbacks:
- Two wrappers needed on the
img
- 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);
}
Chamfered border different container color CSS
You may use the pseudo element and rotate them on top(over) of the container with a little difference from your method.
Draw an inset shadow instead a border to your container.
Draw squares with a white background (as container) with borders.
Rotate the square and hide part of them overflowing from container.
DEMO
.chamfered-box{
margin:1em auto;
width: 440px;
padding:5px;
position: relative;
overflow:hidden;
background: white;
box-shadow: inset 0 0 0 1px #149E4B;
}
.chamfered-box::before, .chamfered-box::after{
width: 20px;
height: 20px;
background: #fff;
content: '';
position: absolute;
bottom: 0;
border: 1px solid #149E4B;
transform:rotate(45deg);
}
.chamfered-box::after{
right: -11px;
bottom: -11px;
}
.chamfered-box::before{
left: -11px;
top: -11px;
}
Div Backgrounds That Overlap At The Corner
Yes, this is very possible with CSS.
Here is a technique using a rotated div and :before
pseudo element. This looks like a long explanation, but the basic principal is pretty straight forward once you start poking around.
Compatibility: IE9 + and all modern browsers — The transform
property in IE9 requires the -ms-
prefix and Safari requires the -webkit-
prefix. They should be placed before the unprefixed property.
The wrapper
The wrapper is used to clip the slanted corners of each div.
- Provide a suitable max and min width
- Clip its children with
overflow: hidden
The div
The div is used to create the slant by clipping its childrens bottom right corner.
- Rotate with
transform: rotate()
- Clip its children with
overflow: hidden
- Blow the width out with
width: 200%
so that the corners are clipped by the wrapper - Move every div (except the first div) up with a negative margin
- Change the z-order with
z-index
so that each div is overlapped by the div before it
The :before
pseudo element
The :before
provides the actual background image without any extra markup.
- Counter the div parents rotation by the same number of degrees
- Provide the background image
- Shift as needed with
transform-origin
The straight edge is provided by the bottom edge of the image and the corner is cut off by the parent. The image must be quite large to overlap the width of its parent.
Full Example
Example with prefixes.
.wrap {
margin: 0 auto;
max-width: 1000px;
min-width: 660px;
overflow: hidden;
background: #EEE;
}
.wrap > div {
transform: rotate(-15deg);
height: 700px;
width: 200%;
overflow: hidden;
transform-origin: 0 90%;
position: relative;
z-index: 10;
}
.wrap > div:before {
content: '';
display: block;
width: 100%;
height: 100%;
background: url(http://lorempixel.com/output/food-q-c-1500-1000-2.jpg) no-repeat;
transform: rotate(15deg);
position: absolute;
transform-origin: 30% 0;
}
.wrap > div:nth-child(n+2) {
margin-top: -140px;
}
.wrap > div:nth-child(2):before {
background-image: url(http://lorempixel.com/output/people-q-c-1500-1000-10.jpg);
}
.wrap > div:nth-child(3):before {
background-image: url(http://lorempixel.com/output/technics-q-c-1500-1000-3.jpg);
}
.wrap > div:nth-child(2) {
z-index: 9;
}
.wrap > div:nth-child(3) {
z-index: 8;
}
<div class="wrap">
<div></div>
<div></div>
<div></div>
</div>
How to draw a shape using a piece of image in php
Preprocessing the image is vital
Whether done manually by you, or on the fly somehow through a GD library, you absolutely at the least need to take the image you state you are receiving...
...and crop and tighten it to make it clean like this (with no white space around the edges and the notch/cut removed):
Then you have an image you can actually work with.
Otherwise, PURE CSS / JAVASCRIPT
NOTE: I am not doing the javascript here. It would be used to dynamically set the element sizing as seen in the html.
Normally I would use a judicious amount of :before
and ':after' pseudo elements to keep the html less cluttered, but since you need dynamic sizing of the frame, then we need to use a number of nested div elements to set dynamic styles for widths and heights that are critical to some of the div
elements (some of which would still be pseudo elements if javascript could access those or if dynamic sizing was not needed).
NOTE: So far I have only tested this in Chrome and Firefox. Really old browsers are for sure going to fail miserably.
/* implementation of framing */
.frameit {
/* width and height must be set dynamically by javascript see html */
position: relative;
box-sizing: border-box;
overflow: hidden;
padding: 20px; /* at least border size */
}
.frameit:before,
.frameit:after,
.frameit .sides > div,
.frameit .corner > div {
position: absolute;
background-image: url(http://i.stack.imgur.com/vAgqj.jpg);
background-size: 100% 20px; /* 100% and border size */
height: 20px; /* equal to border width of frameit div */
}
.frameit:before {
content: '';
top: 0;
left: 0;
right: 0;
}
.frameit:after {
content: '';
bottom: 0;
left: 0;
right: 0;
}
.frameit .sides {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
}
.frameit .sides > div {
/* width must be set dynamically by javascript see html */
height: 20px;
}
.frameit .sides > div:first-child {
top: 0;
left: 20px; /* border width */
transform-origin: 0 0;
transform: rotate(90deg);
}
.frameit .sides > div:last-child {
bottom: 0;
right: 20px; /* border width */
transform-origin: 100% 100%;
transform: rotate(90deg);
}
.frameit .sides ~ .corner { /* all corners */
position: absolute;
z-index: 2;
width: 29px; /* square root of ((border-width squared) x 2) round up */
height: 29px; /* match width */
overflow: hidden;
}
.frameit .TL {
top: 0;
left: 0;
transform-origin: 0 0;
transform: rotate(-45deg);
}
.frameit .TL > div {
top: inherit;
left: inherit;
transform-origin: inherit;
transform: rotate(45deg);
}
.frameit .TR {
top: 0;
right: 0;
transform-origin: 100% 0;
transform: rotate(45deg);
}
.frameit .TR > div {
top: 0;
right: 0;
transform-origin: 100% 0;
transform: rotate(-45deg);
}
.frameit .BR {
bottom: 0;
right: 0;
transform-origin: 100% 100%;
transform: rotate(-45deg);
}
.frameit .BR > div {
bottom: inherit;
right: inherit;
transform-origin: inherit;
transform: rotate(45deg);
}
.frameit .BL {
bottom: 0;
left: 0;
transform-origin: 0 100%;
transform: rotate(45deg);
}
.frameit .BL > div {
bottom: inherit;
left: inherit;
transform-origin: inherit;
transform: rotate(-45deg);
}
/* Optional shading to help define the joint */
.frameit .sides > div:first-child:before,
.frameit .sides > div:last-child:before {
content: '';
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
background-color: rgba(0,0,0,.07);
}
<div class="frameit" style="width: 200px; height: 300px;">
<!-- top and bottom and overall container
width and height assumed to be set by javacript by user
-->
<div class="sides">
<!-- left and right sides
widths of the children are equal to HEIGHT of container and are
assumed to be set by javacript by user
-->
<div style="width: 300px;"></div>
<div style="width: 300px;"></div>
</div>
<div class="TL corner"><!-- top left bevel --><div style="width: 200px;"></div></div>
<div class="TR corner"><!-- top right bevel --><div style="width: 200px;"></div></div>
<div class="BR corner"><!-- bottom right bevel --><div style="width: 200px;"></div></div>
<div class="BL corner"><!-- bottom left bevel --><div style="width: 200px;"></div></div>
</div>
How can I make angled corners on a UIView?
First you need a path with the angled corners:
- (CGPathRef) makeAnglePathWithRect: (CGRect)rect withSize:(float) s {
CGPoint one = CGPointMake( rect.origin.x +s, rect.origin.y);
CGPoint two = CGPointMake( rect.origin.x + rect.size.width - s, rect.origin.y);
CGPoint three = CGPointMake( rect.origin.x + rect.size.width, rect.origin.y +s);
CGPoint four = CGPointMake( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height -s);
CGPoint five = CGPointMake( rect.origin.x + rect.size.width-s, rect.origin.y + rect.size.height);
CGPoint six = CGPointMake(rect.origin.x+s, rect.origin.y + rect.size.height);
CGPoint seven = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height-s);
CGPoint eight = CGPointMake(rect.origin.x, rect.origin.y + s);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path,NULL,one.x, one.y);
CGPathAddLineToPoint(path,NULL,two.x, two.y);
CGPathAddLineToPoint(path,NULL,three.x, three.y);
CGPathAddLineToPoint(path,NULL,four.x, four.y);
CGPathAddLineToPoint(path,NULL,five.x, five.y);
CGPathAddLineToPoint(path,NULL,six.x, six.y);
CGPathAddLineToPoint(path,NULL,seven.x, seven.y);
CGPathAddLineToPoint(path,NULL,eight.x, eight.y);
CGPathAddLineToPoint(path,NULL,one.x, one.y);
return path;
}
Then you need to use the path to specify a mask:
CAShapeLayer *maskLayer = [CAShapeLayer layer];
CGRect bounds = CGRectMake(0.0f, 0.0f, 100, 100); //figure out your bounds
[maskLayer setFrame:bounds];
CGPathRef p = [self makeAnglePathWithRect:bounds withSize:20.0];
maskLayer.path = p;
_myview.layer.mask = maskLayer;
If you want to remove the angles from any corner, fiddle with points one-eight, removing the "s" value. You can change the size of the triangles cut out of the corners with the size parameter.
Is it possible to create an angled corner in CSS?
It's a little difficult keeping the border, but I managed to achieve a close effect using :before and :after elements with a parent container (:before and :after don't work on an img tag)
Add a border to the container
Add a before to block out a corner and offset by -1 to cover the border
Add an after that's slightly offset from the before to create the line inside the cut off
As you can see, the thickness of the 45deg line is a bit of an issue:
.cutCorner {
position:relative; background-color:blue;
border:1px solid silver; display: inline-block;
}
.cutCorner img {
display:block;
}
.cutCorner:before {
position:absolute; left:-1px; top:-1px; content:'';
border-top: 70px solid silver;
border-right: 70px solid transparent;
}
.cutCorner:after {
position:absolute; left:-2px; top:-2px; content:'';
border-top: 70px solid white;
border-right: 70px solid transparent;
}
<div class="cutCorner">
<img class="" src="https://www.google.co.uk/logos/doodles/2013/william-john-swainsons-224th-birthday-5655612935372800-hp.jpg" />
</div>
Related Topics
Css-Less Class Extend Class with Pseudo Class
Is There a Version of Yui Compressor That Deals Correctly with Media Queries
Display:None Doesn't Work on Outlook 2007
CSS Change List Item Background Color with Class
Selector for One Tag Directly Followed by Another Tag
Combine Calc() with Attr() in CSS
Why Do Flexbox Item Images Resize Differently According to Their Initial Size
How to Turn Off SASS Rgb -> Color Name
Jsf2 Add Custom Font to CSS Stylesheet
Css3 Appearance Property for Ie
Css: Fixed with Horizontal Menu, with Variable Width Tabs, Using Ul
Oocss Separation of Container and Content
Android Webview Border-Radius Aliasing
How to See the Print Media CSS in Firebug
Why Do 'Foo Bar' and 'Foo > Bar' Have the Same Specificity in CSS
Font Smoothing Techniques? Text-Shadow Rendering Differently in Chrome 14.0.833.0 or Higher
How to Prevent Division When Using Variables Separated by a Slash in CSS Property Values