Take the 2-minute tour ×
Graphic Design Stack Exchange is a question and answer site for Graphic Design professionals, students, and enthusiasts. It's 100% free, no registration required.

I am trying to avoid using a background image (or any image-based solution) to effectively create this:

irregular border

Note: the red arrow is just pointing at the border in question. The arrow should not be included in your answer.

How can I create this irregularly-shaped border with pure CSS (no images)? If images are unavoidable, the most concise and readable answer will get upvoted and accepted.

share|improve this question

4 Answers 4

up vote 10 down vote accepted

You could use CSS3 (keeping in mind this won't work with older versions of IE).

For example, you could combine some shapes like a rectangle and two triangles. See this jsfiddle.

enter image description here

HTML:

<div id="square"></div>
<div class="align">
    <div id="triangle-topleft"></div>
    <div id="triangle-topright"></div>
</div>

And the CSS:

#triangle-topright {
    width: 0;
    height: 0;
    border-top: 40px solid red;
    border-left: 100px solid transparent;
}

#triangle-topleft {
    width: 0;
    height: 0;
    border-top: 40px solid red;
    border-right: 100px solid transparent;
}

#square {
    background-color:red;
    clear:both;
    height:60px;
    width:200px;
}

.align div {
    float: left;
}

You can see a variety of CSS3 shapes here. Most if not all require more than one div, so the challenge would be applying a darker border.

share|improve this answer
    
Is there a way to do this where the polygon uses a percentage-based width? –  Micah - ps I love you Nov 12 '13 at 18:22
    
Using Yisela's approach, you can make the triangle with one div (border-left & border-right with 1/2 the square's width; the border top = desired height; and add a margin-top of (-1 * border-top). You would need to add padding value to the square to prevent text from lapping the triangle. –  horatio Nov 12 '13 at 20:53
    
You could put these additional shapes into pseudo-elements :before and :after to keep your html 'clean'. The :before would be the left triangle, the :after the right one. –  Vincent Jul 25 at 10:01

Yisela's answer is solid, but I figured I'd offer up this alternative: using polygon or an image URI with CSS shapes and clip-path. Here's a quick tutorial.

Note that this method will work with even fewer browsers than the triangle border trick at the moment. However, if you want to use a more complex shape or wrap your text to the shape this will be the way to go.

demo-screenshot

share|improve this answer
    
It appears this solution would even work if I needed the polygon to use a percentage-based width. Perhaps, by means of the CSS vw unit. Does that sound possible? –  Micah - ps I love you Nov 12 '13 at 18:25

Another method for this which may also have limited support is "embedded SVG in CSS". I have not tried this myself but the idea is that you provide an image resource as a url within the css declaration for the object and you pass it a properly escaped url which contains the data.

SVG is a plain text/xml format. An example polygon (from w3schools):

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <polygon points="200,10 250,190 160,210"
  style="fill:lime;stroke:purple;stroke-width:1"/>
</svg> 

An example inline (embedded) SVG (simplified) (from stackoverflow):

url("data:image/svg+xml;utf8, <svg></svg>");

Note that the SVG data must be "escaped" properly for inline use, which makes it slightly less attractive than merely linking a SVG file.

There is some discussion regarding viability of the method in the above linked thread. I think that embedding something as simple as a white-filled triangle is an easy decision provided support is there. Complex SVG format data should be stored as an SVG file rather than inline.

SVG files are vector and can be scaled by percentage, unlike the "borders" method. They also (currently) have better (non-inline at least) support than the clipping path method listed. SVG, being plain text, can even be emitted on-the-fly using e.g. PHP or other server-side scripting.

share|improve this answer

If your blue area on the image is a transparent png and the white area is transparent, then you need to include this html to make it drop shadows :

<svg height="0" xmlns="http://www.w3.org/2000/svg">
    <filter id="drop-shadow">
        <feGaussianBlur in="SourceAlpha" stdDeviation="4"/>
        <feOffset dx="12" dy="12" result="offsetblur"/>
        <feFlood flood-color="rgba(0,0,0,0.5)"/>
        <feComposite in2="offsetblur" operator="in"/>
        <feMerge>
            <feMergeNode/>
            <feMergeNode in="SourceGraphic"/>
        </feMerge>
    </filter>
</svg>

And use this css on the image :

.shadowed {
    -webkit-filter: drop-shadow(12px 12px 25px rgba(0,0,0,0.5));
    filter: url(#drop-shadow);
    -ms-filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12, Color='#444')";
    filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12, Color='#444')";
}

This is perfectly cross-browser solution.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.