Nathan
Nathan

Reputation: 319

css only textured and 'stitched' ribbon

This is driving me nuts, I've seen it before but can't replicate it or find it or any resources for it. What I am doing is a vertical ribbon with a leather texture and a "stitched pattern". The way the stitches work is simple enough, inner divs with dashed borders, and even the ribbon shape is easy enough using the pseudo :after class, but combining the two is just not going to plan.

This is what I have for css that is working so far (it is all done with css minus the leather texture):

.wrapleather {
        width:100px;
        height:120px;
	    float: right;
	    margin-right:20px;
        background-image : url("leather.png");
        border-radius: 5px;
        -webkit-box-shadow: 0px 1px 10px rgba(0,0,0,0.5);
        -moz-box-shadow: 0px 1px 10px rgba(0,0,0,0.5);
        box-shadow: 0px 1px 10px rgba(0,0,0,0.5);
	    position:relative;
    }
    .wrapleather:after {
    	content: '';
        display: block;
        width: 0;
        height: 105px;
        position: absolute;
        top: 0;
        left: 0;
        border-width: 0 50px 15px 50px;
        border-style: solid;
        border-color: transparent transparent #cdc0a8;
	    position:absolute;
    	top:0;
    	left:0;
    }
    .wrapleather .outside {
    	width:90px;
    	height:110px;
        margin: 4px;
        border-radius: 5px;
        border: 1px dashed #aaa;
        box-shadow: 0 0 0 1px #f5f5f5;
    	}
    .wrapleather .inside {
        width:90px;
        height:110px;
        border-radius: 5px;
     }
<div class="wrapleather">
     <div class="outside">
       <div class="inside">
        <p class="font">Leather</p>
       </div>
     </div>    
  </div>

Additionally the shadow is remaining in a "square" format and not taking the shape of everything. To clarify I am not asking anyone to debug or anything like that, I am simply asking for alternative or further methods to be shared that could achieve the desired results, css is still something I am in the process of learning so any advice or anything of that nature that you could give would be appreciated, and if you need any additional info please let me know. Thanks!

Upvotes: 2

Views: 3002

Answers (2)

Josh Burgess
Josh Burgess

Reputation: 9567

So, I wanted to make sure that I wasn't losing my mind and that this ribbon effect is actually possible on modern browsers without relying on webkit specific filters. So here it is for all those who come across this later.

You just need to be more diligent with how you model your box-shadows.

Note that when increasing the width, you'll need to subsequently decrease the angle at which you're rotating and skewing the :before and :after elements.

Example:

.ribbon {
    background: #eee;
    border-left: 1px dashed #aaa;
    border-right: 1px dashed #aaa;
    border-top: 1px dashed #aaa;
    box-shadow: 5px 0 0 #eee,
                -5px 0 0 #eee,
                0 -5px 0 #eee,
                5px -5px 0 #eee,
                -5px -5px 0 #eee,
                5px 1px 5px 5px #888;
    height: 120px;
    margin: 10px 5px 0 5px;
    position: relative;
    width: 90px;
    z-index: 3;
}
.ribbon:after,
.ribbon:before {
    content: '';
    position: absolute;
    top: calc(100% - 1px);
    width: calc(50% + 1px);
    border-bottom: 1px dashed #aaa;
}
.ribbon:after {
    transform: rotateZ(20deg) skewX(20deg) translateY(-2px);
    transform-origin: top right;
    right: -1px;
    height: 40px;
    background-color: #eee;
    border-right: 1px dashed #aaa;
    box-shadow: 5px 0 0 #eee,
                0 5px 0 #eee,
                5px 5px 0 #eee,
                15px 15px 5px -5px #888,
                0 15px 5px -5px #888,
                15px 0 5px -5px #888;
}
.ribbon:before {
    transform: rotateZ(-20deg) skewX(-20deg);
    transform-origin: top left;
    left: -1px;
    height: 40px;
    background-color: #eee;
    border-left: 1px dashed #aaa;
    box-shadow: -5px 0 0 #eee,
                0 5px 0 #eee,
                5px 5px 0 #eee,
                15px 15px 5px -5px #888,
                0 15px 5px -5px #888;
}
<div class="ribbon"></div>

Upvotes: 0

joshnh
joshnh

Reputation: 8704

There is a way to do what you want with CSS only, but it won't work on all browsers. If you want the best browser support, you should probably use an image.

Here is a demo (you may have noticed I only use a single element, as you shouldn't introduce extra markup just for styling): http://jsfiddle.net/joshnh/eUje5/

HTML

<div class="ribbon"></div>

CSS

.ribbon {
    background: #eee;
    border-left: 1px dashed #aaa;
    border-right: 1px dashed #aaa;
    border-radius: 5px 5px 0 0;
    box-shadow: 5px 0 0 #eee,
                -5px 0 0 #eee;
    height: 120px;
    margin: 0 5px;
    position: relative;
    width: 90px;
    -webkit-filter: drop-shadow(0 2px 5px hsla(0,0%,0%,.5));
}
.ribbon:after,
.ribbon:before {
    border-top: 15px solid #eee;
    content: '';
    height: 0;
    position: absolute;
    top: 100%;
    width: 0;
}
.ribbon:after {
    border-left: 50px solid transparent;
    right: -6px;
}
.ribbon:before {
    border-right: 50px solid transparent;
    left: -6px;
}

Upvotes: 7

Related Questions