4

I've been researching dotted borders that support webkit and IE 9+.

I currently have a 'simple' dotted border effect like so:

.bord {
  height: 200px;
  width: 300px;
  background: gray;
  border-radius: 20px;
  position: relative;
}
.bord:before {
  content: "";
  position: absolute;
  height: calc(90% - 10px);
  width: calc(90% - 10px);
  left: 5%;
  top: 5%;
  border: 5px dotted black;
}
<div class="wrapper">
  <div class="bord"></div>
</div>

which renders (in chrome):

enter image description here


But i would like:

enter image description here

Would this be possible using pure css?

(since I can't use border-image as Internet Explorer 10 and earlier versions do not support the border-image property.)

I've looked at the docs but couldn't see any reference, and I've seen stuff like this, but obviously doesn't help me here.


Is there a CSS property I'm missing here? Or an alternative possibility? (IMO, though, these 'dots' should be round anyway) but 'rounded dots' would also be beneficial.


Community
  • 1
  • 1
jbutler483
  • 24,074
  • 9
  • 92
  • 145
  • I found a previous answer to this question here: http://stackoverflow.com/questions/6250394/how-to-increase-space-between-dotted-border-dots – Bitwise Creative Feb 04 '15 at 16:20
  • @mattytommo That is addressed in the question. – James Montagne Feb 04 '15 at 16:26
  • @mattytommo: If you fully read the question, you'd understand why this wasn't an option (**hint**: read the first line) – jbutler483 Feb 04 '15 at 16:26
  • 2
    While @Harry 's answer is impressive, I do think having fixed width and height might be too limiting, and OP should consider going with a border-image for >IE9, and using modernizr or similar to have a fallback. Pixel perfect cross browser design is the road to madness. – fontophilic Feb 04 '15 at 17:42

4 Answers4

8

This is the closest that I could achieve. It uses multiple box-shadows of a single pseudo-element offset to the required positions.

This can easily be converted to a dotted border also by adding the below line to the pseudo-element.

border-radius: 50%;

Box Shadow is supported in IE9+ also.

Note: This approach would work if you have a fixed height and width. Not the ideal approach but I think this is the most you could achieve using CSS having IE9+ support.

.bord {
    height: 185px;
    width: 250px;
    background: gray;
    border-radius: 20px;
    position: relative;
    padding: 25px;
}
.bord:before {
    position: absolute;
    top: 20px;
    left: 20px;
    content:'';
    background: black;
    height: 5px;
    width: 5px;
    box-shadow: 50px 0px 0px black, 100px 0px 0px black, 150px 0px 0px black, 200px 0px 0px black, 250px 0px 0px black, 0px 190px 0px black, 50px 190px 0px black, 100px 190px 0px black, 150px 190px 0px black, 200px 190px 0px black, 250px 190px 0px black, 0px 47.5px 0px black, 0px 95px 0px black, 0px 142.5px 0px black, 0px 47.5px 0px black, 250px 47.5px 0px black, 250px 95px 0px black, 250px 142.5px 0px black;
}
<div class="wrapper">
    <div class="bord">abcd</div>
</div>

The following snippet is strictly not an answer to the current question as IE9+ support is specifically mentioned. This was my original answer (wrong) and is retained as a part of the answer to help future readers who may not need IE9 support. This option uses linear-gradient and background-position (both of which can support percentage values) and hence can be more scale-able than the other.

.bord {
  height: 235px;
  width: 300px;
  background: gray;
  border-radius: 20px;
  position: relative;
}
.bord:before {
  content: "";
  position: absolute;
  height: calc(90% - 10px);
  width: calc(90% - 10px);
  left: 5%;
  top: 5%;
  background: linear-gradient(90deg, black 10%, transparent 10%), linear-gradient(90deg, black 10%, transparent 10%);    
  background-size: 50px 5px;
  background-repeat: repeat-x;
  background-position: 5px 5px, 5px 195px;
}
.bord:after {
  content: "";
  position: absolute;
  height: calc(90% - 10px);
  width: calc(90% - 10px);
  left: 5%;
  top: 5%;
  background: linear-gradient(0deg, black 10%, transparent 10%), linear-gradient(0deg, black 10%, transparent 10%);
  background-size: 5px 50px;
  background-repeat: repeat-y;
  background-position: 5px 0px, 255px 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="wrapper">
  <div class="bord"></div>
</div>
Harry
  • 87,580
  • 25
  • 202
  • 214
  • I think with all of those -webkit prefixes this is probably not working in IE9+? – James Montagne Feb 04 '15 at 16:43
  • @JamesMontagne: Probably yes, but I think linear gradients on the whole might work. Let me check though. Thanks for pointing out :) – Harry Feb 04 '15 at 16:44
  • @JamesMontagne: Once again thanks for pointing out mate. I have added an alternate solution which should work in IE9+ as it is only using box-shadows. – Harry Feb 04 '15 at 17:06
  • 2
    Impressive. I didn't think was possible. – HC_ Feb 04 '15 at 17:16
3

CSS3 Multiple background images (should) work in IE9. So just use a background image and tile it across the four corners of the element. That should be it.


To make things interesting, you can also use SVG images such as these:

svg {
  background-color: #999;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16px" height="16px"><circle cx="4" cy="4" r="4" fill="#000000"></circle></svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16px" height="16px"><circle cx="12" cy="4" r="4" fill="#000000"></circle></svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16px" height="16px"><circle cx="12" cy="12" r="4" fill="#000000"></circle></svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16px" height="16px"><circle cx="4" cy="12" r="4" fill="#000000"></circle></svg>

The SVG images can be embedded inside the CSS using data URI. Putting all this together:

.bord {
  width: 320px;
  height: 224px;
  border-radius: 16px;
  position: relative;
  background: #999;
}
.bord:before {
  content: "";
  position: absolute;
  left: 16px;
  top: 16px;
  right: 16px;
  bottom: 16px;
  background:
    url("data:image/svg+xml,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216px%22%20height%3D%2216px%22%3E%3Ccircle%20cx%3D%224%22%20cy%3D%224%22%20r%3D%224%22%20fill%3D%22%23000000%22%3E%3C%2Fcircle%3E%3C%2Fsvg%3E")
      left top repeat-x,
    url("data:image/svg+xml,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216px%22%20height%3D%2216px%22%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%224%22%20r%3D%224%22%20fill%3D%22%23000000%22%3E%3C%2Fcircle%3E%3C%2Fsvg%3E")
      top right repeat-y,
    url("data:image/svg+xml,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216px%22%20height%3D%2216px%22%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2212%22%20r%3D%224%22%20fill%3D%22%23000000%22%3E%3C%2Fcircle%3E%3C%2Fsvg%3E")
      right bottom repeat-x,
    url("data:image/svg+xml,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216px%22%20height%3D%2216px%22%3E%3Ccircle%20cx%3D%224%22%20cy%3D%2212%22%20r%3D%224%22%20fill%3D%22%23000000%22%3E%3C%2Fcircle%3E%3C%2Fsvg%3E")
      bottom left repeat-y;
}
<div class="bord"></div>
Salman A
  • 262,204
  • 82
  • 430
  • 521
0

There's a CSS trick using gradients to do that.

element {
  background-position: top;
  background-image: linear-gradient(to right, #f8f8f8 20%, rgba(255,255,255,0) 0%);
  background-size: 5px 1px;
  background-repeat: repeat-x;
}

I've made a SCSS mixin to implement this and change colors, sizes, positions and spacing quickly. Check it out at github.com/florbraz/Dotted-Border-w-custom-spacing-SCSS-Mixin.

Flor Braz
  • 71
  • 1
  • 3
0

You can use a single svg inside the css.

.dotted-bloc {
  width: 200px;
  height: 150px;
  margin: 30px auto;
  background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' fill-rule='evenodd' stroke='%23000000' stroke-width='5' stroke-dasharray='3 10'/%3e%3c/svg%3e");
}
<div class="dotted-bloc">
</div>

stroke='%23000000' the last 6 numbers are for your hexadecimal color (000000 for black, FF0000 for red...)

stroke-width='5' the number value is for the width of the border

stroke-dasharray='3 10' The first number is for the width of one dot, and second number is for the interval between each dot.