11

Is there any way to create a sharp flat corner with CSS and HTML?

Something like this:

  ____
 /    \
 |    |
 \____/
web-tiki
  • 99,765
  • 32
  • 217
  • 249
AturSams
  • 7,568
  • 18
  • 64
  • 98

6 Answers6

26

Look here. There you find all you need:

http://css-tricks.com/examples/ShapesOfCSS/

Edit In case the link goes lost:

CSS

#octagon { 
  width: 100px; 
  height: 100px; 
  background: red;  
  position: relative; 
} 

#octagon:before { 
  content: ""; 
  position: absolute;  
  top: 0; left: 0; 
  border-bottom: 29px solid red; 
  border-left: 29px solid #eee; 
  border-right: 29px solid #eee; 
  width: 42px; height: 0; 
} 

#octagon:after { 
  content: ""; 
  position: absolute; 
  bottom: 0; 
  left: 0; 
  border-top: 29px solid red; 
  border-left: 29px solid #eee; 
  border-right: 29px solid #eee; 
  width: 42px; 
  height: 0; 
} 
Sven Bieder
  • 5,515
  • 2
  • 21
  • 27
  • But you didn't get the accepted answer now. Shame. Yours is better. – Mr Lister Jun 04 '12 at 18:05
  • 1
    Not a problem. When the other answer works better for him, then it's ok. In the end it's about helping people and not about who gets accepted. – Sven Bieder Jun 04 '12 at 18:07
  • Yeah, but it's also for helping people who search this site in the future. If they see the other answers accepted, they may think that's the better one, with the 4 extra divs. Oh well. – Mr Lister Jun 04 '12 at 18:10
  • @SvenBieder, I hope you are not mad that I "stole" your accepted answer, that wasn't my intention. I took your idea and was just curios if I can do it the way I see fit – Dejan Jun 05 '12 at 09:39
  • @MrLister, care to share why this is better? I'm not saying you're wrong, I'm just hoping to learn something. So far I see that the solution here works, but only for divs that are with fixed size of 100x100, whereas mine works for all widths and heights. And of course I could reduce the number of extra divs using content and pseudo selectors, but then I lose IE7 support and below – Dejan Jun 05 '12 at 09:40
  • 1
    @dDejan No, I have no reason to be mad. Different ways lead to the aim. What is the best way for the asking person is his decision. As I said, may aim is not to get the "accepted" answer. I'm here to help by showing a way I would choose. – Sven Bieder Jun 05 '12 at 11:34
  • @dDejan This is better in that it doesn't use extra markup. Markup is for content, CSS is for how it looks. And you're right about the fixed sizes, but if you're going to use Javascript anyway, you can change the sizes as well with that. – Mr Lister Jun 05 '12 at 13:11
  • 1
    @dDejan [Here is a jsFiddle](http://jsfiddle.net/XSs9L/1/) that doesn't rely on the sizes being 100x100, and without Javascript. It doesn't work in IE7 though... – Mr Lister Jun 05 '12 at 13:49
9

Here is my solution, using the CSS shapes from Chris Coyier.

http://jsfiddle.net/dDejan/XSs9L/

4 extra divs are inserted via JavaScript (well, jQuery actually) for each of your containers that you want shaped this way. These divs are positioned absolutely in the corners of it's parent, and they are styled accordingly as described in the link posted by Sven Bieder

Dejan
  • 501
  • 5
  • 13
4

You can compose this using absolutely-positioned :before and :after elements using the CSS triangles technique.

<div class="box"></div>

css:

.box {
   background-color:#2020ff;
   height:50px;
   width:50px;
   position:relative   
}

.box:after {
    content:" ";
    width: 0;
    height: 0;
    border-top: 10px solid #ffffff;
    border-bottom: 10px solid transparent;
    border-right:10px solid #ffffff;  
    position:absolute;
    top:-9px;
    right:0px;

}
Diodeus - James MacFarlane
  • 112,730
  • 33
  • 157
  • 176
  • This looks good but could you explain the code? I don't fully understand how it works? – AturSams Jun 04 '12 at 16:01
  • 1
    It's a old trick of making a triangle out of the corner piece of a border. In this case it's a white triangle that covers up a portion of the blue box. You can edit the settings in :after to see how it works. Use another one with :before to cover up the upper-left corner. Here's how it works: http://stackoverflow.com/questions/7073484/how-does-this-css-triangle-shape-work – Diodeus - James MacFarlane Jun 04 '12 at 16:17
1

box {
  background-color: transparent;
  position: fixed;
  width: 300px;
  height: 300px;
}
svg {
  width: 300px;
  height: 300px;
}
polygon {
  visibility: visible;
  background: black;
  stroke: white;
}
<box>
  <svg>
    <polygon points="0 250, 50 300, 300 300, 300 50, 250 0, 0 0" />
  </svg>
</box>
1

Here is a complete solution for the whole box. It scales based on the content size like you would expect from a regular div. And you can easily resize it with the height and width property without having to tinker with anything else. It is a modified version of this codepen.

div {
  padding: 5px;
  margin: 40px auto;
  width: 230px;
  background: rgba(47,51,54,1); /* fallback */
  background:
        -moz-linear-gradient(45deg,  transparent 7px, rgba(47,51,54,1) 7px),
        -moz-linear-gradient(135deg, transparent 7px, rgba(47,51,54,1) 7px),
        -moz-linear-gradient(225deg, transparent 7px, rgba(47,51,54,1) 7px),
        -moz-linear-gradient(315deg, transparent 7px, rgba(47,51,54,1) 7px);
  background:
        -o-linear-gradient(45deg,  transparent 7px, rgba(47,51,54,1) 7px),
        -o-linear-gradient(135deg, transparent 7px, rgba(47,51,54,1) 7px),
        -o-linear-gradient(225deg, transparent 7px, rgba(47,51,54,1) 7px),
        -o-linear-gradient(315deg, transparent 7px, rgba(47,51,54,1) 7px);
  background:
        -webkit-linear-gradient(45deg,  transparent 7px, rgba(47,51,54,1) 7px),
        -webkit-linear-gradient(135deg, transparent 7px, rgba(47,51,54,1) 7px),
        -webkit-linear-gradient(225deg, transparent 7px, rgba(47,51,54,1) 7px),
        -webkit-linear-gradient(315deg, transparent 7px, rgba(47,51,54,1) 7px);
  xbackground:
        linear-gradient(45deg,  transparent 7px, rgba(47,51,54,1) 7px),
        linear-gradient(135deg, transparent 7px, rgba(47,51,54,1) 7px),
        linear-gradient(225deg, transparent 7px, rgba(47,51,54,1) 7px),
        linear-gradient(315deg, transparent 7px, rgba(47,51,54,1) 7px);
}

div {
    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;
}

p {
  border-left: none;
  border-right: none;
  color: #ccc;
  margin: 0;
  min-height: 40px;
  padding: 10px;
  position: relative;
}
<div>
  <p>Here is some content.</p>
</div>

https://codepen.io/c0n5/pen/vYyRPVZ

Constantin
  • 109
  • 1
  • 4
0

.rotate {
    margin: 100px;
    background-color: olivedrab;
    width: 100px;
    height: 100px;
    transform: rotate(45deg);
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <div class="rotate"></div>
</body>

</html>
  • I needed a method that would allow a user to click through the corners of a div to material behind. This isn't perfect but so far it's the best simple solution I can find. I don't think this exactly answers the question but it was what I was looking for. Thanks! – Andy Jun 30 '22 at 20:44