1

I need to make a dashed border inside a vertical banner, and somehow for some reasons I'm failing to make it, every time I mess whith border the banner just falls apart. Can you help me work this out.

Here is my banner:

div {
    background: #1589A1;
    padding: 20px;
    position: relative;
    color: #fff;
    width: 100px;    
    min-height: 70px;
    font: 600 16px sans-serif;
    color: #fff;    
}
div:after {
    content:'';
    position: absolute;
    left: 50%;
    bottom: -100px;
    border: 50px solid transparent;
    border-top: 50px solid #1589A1;
    -webkit-transform: translate(-50%, 0);
    -ms-transform: translate(-50%, 0);
    transform: translate(-50%, 0);
}
div span{
    padding: 30px 0 30px;
    position: relative;
    display: block;
    z-index: 1;
    -webkit-transform: rotate(-90deg);
    -moz-transform: rotate(-90deg);
    -o-transform: rotate(-90deg);
    transform: rotate(-90deg);
}

Fiddle example. Picture of the banner.

Felix A J
  • 6,300
  • 2
  • 27
  • 46
copser
  • 2,523
  • 5
  • 38
  • 73
  • Can you include an example that shows how the banner falls apart when you try to add a dashed border? – Antonio Dangond Jun 20 '15 at 04:19
  • After testing, it falls apart in the `div:after`, removing the border lines causes it to become a square. If it helps, you can get the top border dashed by adding `border: #fff 1px dashed;` inside the css for the `div` segment. – Kraang Prime Jun 20 '15 at 04:22
  • Ok I did that, the dashed border in the div part is ok now, but what to do whit the :after part when I remove border? @SanuelJackson – copser Jun 20 '15 at 04:31
  • That's the part that is kind of funky for me. I am not sure what to do with that part since the `border` portion seems to be important to the drawing of the upside down triangle. – Kraang Prime Jun 20 '15 at 04:32
  • Can you add an image of what exactly you want to achieve? – Yandy_Viera Jun 20 '15 at 04:43
  • 1
    possible duplicate of [CSS triangle custom border color](http://stackoverflow.com/questions/9450733/css-triangle-custom-border-color) –  Jun 20 '15 at 04:50
  • 1
    You're using the css border property to make the triangle on the bottom, unfortunately you need to make a second triangle just to make a solid border, I don't think you'll be able to achieve a dashed border. Maybe it would be better to make an image background for a div instead. –  Jun 20 '15 at 04:51
  • I will need to re code this, thank @TinyGiant – copser Jun 20 '15 at 05:20

2 Answers2

2

This is a fun one. Sometimes it can helpful to look at the simplest approach, which in this case might be to use SVG. ;-)

That said, assuming you must do this in CSS and have a reasonable progressive enhancement strategy (i.e. what are you starting with that people will see when their user agent doesn't support all the effects you add), it seem to me that the simplest approach would be to use two boxes: one main box and one rotated to create the diamond shape at the bottom.

We start with the main box that will contain the text. We set the background color, border, a gradient effect. A hard box shadow adds the extra "fabric" around the dashed border. The border width is unset on the right side, the gradient is adjusted to be the right size and placement. We also rotate the whole thing.

div {
    position: absolute;
    top: 46px; /* height minus box-shadow */
    left: 0;
    width: 200px;
    height: 50px;
    background: steelblue;
    background-image: linear-gradient(to left, steelblue, rgba(255,255,255,0.5), steelblue);
    background-size: 20px 100%;
    background-repeat: no-repeat;
    background-position: 125px;
    transform: rotate(-90deg);
    border: 1px dashed black;
    border-width: 1px 0 1px 1px;
    box-shadow: 0 0 0 4px steelblue;
}

Next, we add a pseudo-element for the diamond shape. To do it perfectly, you'd need a height for the first box that matches the hypotenuse of the isosceles right triangles that you'd get if you split this second box from corner to corner, so that the corners of both boxes align perfectly. I just eyeballed it:

div:before {
    position: absolute;
    top: 8px;
    left: -21px;
    display: block;
    content: ' ';
    width: 33px;
    height: 33px;
    background: steelblue;
    transform: rotate(45deg);
    border: 1px dashed black;
    box-shadow: 0 0 0 4px steelblue;
    border-width: 0 0 1px 1px;
}

Just a box, same treatments as the first (though no gradient and we unset different borders, plus rotated only 45 degrees). We're absolutely positioning this.

And finally, we add some text. By default this would display under the pseudo element, but absolutely positioning solves this.

p {
    position: absolute;
    color: rgba(255,255,255,0.9);
    font: 1.5em Pacifico;
    line-height: 0.3em;
}

So, it's not perfect, but

here's a working example.

Please note that I did not use any vendor prefixes, so viewers might need to adjust for specific browsers. And, it won't work everywhere, so perhaps SVG is still an option for you.

stephenhay
  • 2,824
  • 24
  • 25
0

This is an example that could guide you, right now is pretty static but could be improved by making it more dynamic.

* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}
body {
    padding: 50px;
}
.wrapper {
    position: relative;
    width: 70px;
    height: 170px;
    padding: 0 4px;
    background: #1589A1;
}
.content {
    padding: 15px 15px 0;
    width: 100%;
    height: 100%;
    font: 600 16px sans-serif;
    color: #fff;
    border: dashed #000;
    border-width: 0 2px;
}
.wrapper:after {
    content:'';
    position: absolute;
    left: 50%;
    bottom: -70px;
    border: 35px solid transparent;
    border-top: 35px solid #1589A1;
    -webkit-transform: translate(-50%, 0);
    transform: translate(-50%, 0);
}
.content:after {
    content:'';
    position: absolute;
    z-index: 1;
    -webkit-transform: rotate(-45deg);
    transform: rotate(-90deg);
    width: 35px;
    height: 35px;
    border: dashed #000;
    border-width: 0 0 2px 2px;
    bottom: -22px;
    left: 17px;
}
.text {
    position: absolute;
    font-size: 18px;
    width: 150px;
    text-transform: uppercase;
    z-index: 5;
    top: 90px;
    left: -40px;
    -webkit-transform: rotate(-90deg);
}
<div class="wrapper">
    <div class="content">
        <p class="text">my css banner</p>
    </div>    
</div>

Improved the above example to do dynamic

In the above snippet example I rotate the text then I gave the styles setting fixed height to its container, making the border were to the bottom and I set position: absolute to the p.text to position it in the right place, to summarize I gave styles vertically but because p.text has position: absolute when you change the text you also have to change the height of wrapper which it is a bit annoying.

So in the following solution I first set display: inline-block to wrapper to make it fit the contents, so when you change the text it will change too, then I gave the styles in the normal position in which it is

enter image description here

and finally rotate the wrapper.

enter image description here

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
body {
  padding: 120px 50px;
}
.wrapper {
  position: relative;
  padding: 4px 0;
  background: #1589A1;
  display: inline-block;
  -webkit-transform: translate(-38%, 100%) rotate(-90deg);
  transform: translate(-38%, 100%) rotate(-90deg);
}

.content {
  padding: 17px 33px 17px 0;
  width: 100%;
  color: #fff;
  border: dashed #000;
  border-width: 2px 0;
  height: 62px;
}
.wrapper:after {
  content:'';
  position: absolute;
  top: 0;
  left: 0;
  border: solid transparent;
  border-width: 35px 35px 35px 0;
  border-right: 35px solid #1589A1;
  -webkit-transform: translateX(-100%);
  transform: translateX(-100%);
}
.content:after {
  content: '';
  position: absolute;
  display: block;
  z-index: 1;
  left: -22px;
  top: 15px;
  -webkit-transform: rotate(45deg);
  transform: rotate(45deg);
  width: 38px;
  height: 38px;
  border: dashed #000;
  border-width: 0 0 2px 2px;
}
.text {
  font-size: 20px;
  text-transform: uppercase;
  z-index: 5;
  margin-bottom: 0;
  white-space: nowrap;
  font-family: Arial;
}
<div class="wrapper">
    <div class="content">
        <p class="text">my css dynamic banner</p>
    </div>
</div>

So you can now change the text without worrying about the height of the containers.

Here the jsfiddle to play with

Yandy_Viera
  • 4,320
  • 4
  • 21
  • 42