0
votes

I'm trying to use SVG to create a dotted border around an HTML block with a fixed width but flexible height. I'm tantalisingly close but can't get the bottom to display.

Here is a fiddle (the fiddle has the SVG image included, so it can be inline there URL encoded elements, specifically # is %23)

The SVG code looks like this:

<svg width="300px" height="100%" xmlns="http://www.w3.org/2000/svg">
  <rect x="5" y="5" width="290" height="100%" 
    style="fill: yellow; fill-opacity: 0.5; stroke: #009fe3; stroke-width: 3; stroke-linecap: round; stroke-dasharray: 1 7"/>
</svg>

The CSS like this:

div.block {
  box-sizing: border-box;
  padding: 10px;
  width: 300px;
  background-image: url("dotted-border.svg");
}

I guess what I want is to offset the rectangle from the bottom, but it needs to be a pixel value (5px). It looks like what I want will be trivial with wider SVG 2 adoption (http://www.w3.org/Graphics/SVG/WG/wiki/Proposals/Stroke_position) as then the stroke could be positioned inside the shape.

I know I could just add another image and use CSS :after, but I'm curious!

2
you could use the preserveAspectRatio attribute but the dotted lines will look stretched or squeezed according to the content height : jsfiddle.net/eoLppgty/1web-tiki

2 Answers

1
votes

it is not possible to calculate the right height in svg. instead of using background image, wrap the svg with absolutely positioned div:

HTML

<div class="block">
    <article>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloremque quasi officia vero aut. Velit ratione sapiente fugiat rerum eos ipsa praesentium autem similique vitae reprehenderit et tempora optio eveniet facilis.</article>
    <div class="back-svg">
        <svg width="100%" height="100%" xmlns='http://www.w3.org/2000/svg'><rect width="100%" height="100%" style='fill: yellow; fill-opacity: 0.5; stroke: #009fe3; stroke-width: 5; stroke-linecap: round; stroke-dasharray: 1 7'/></svg>
    </div>
</div>

CSS

html,body {
  height:100%;
}
div.block {
  position: relative;
  box-sizing: border-box;
  padding: 10px;
  width: 300px;
  border: 1px solid green;
}
div.back-svg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
}

fiddle: http://jsfiddle.net/k3v4by34/

1
votes

Why not use a straightforward CSS border instead?

div.block {
    box-sizing: border-box;
    padding: 10px;
    width: 300px;
    background-image: url("data:image/svg+xml;utf8,<svg width='300px' height='100%' xmlns='http://www.w3.org/2000/svg'><rect x='5' y='5' width='290' height='100%' style='fill: yellow; fill-opacity: 0.5; stroke: %23009fe3; stroke-width: 3; stroke-linecap: round; stroke-dasharray: 1 7'/></svg>");
}

div.block2 {
    box-sizing: border-box;
    padding: 4px;
    margin:3px;
    width: 294px;
    background-color:rgba(255,255,0,0.5);
    border:3px dotted #009fe3;
}

/* Alternative method using CSS3 border-image: */
div.block3 {
    box-sizing: border-box;
    padding: 4px;
    margin:3px;
    width: 294px;
    background-color:rgba(255,255,0,0.5);
    border:8px solid transparent;
    -webkit-border-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAbklEQVR4nGL4W8zBMJAYmbMCiJ9C8Qosimkijyz5Hw2vQNNME3mYgqdYFDxFMoBm8oPGAQMeBQOeCAdFNhxwB4yWA6PlwGg5MODZcMAdMFoOjJYDo+XAgGfDAXfAaDkwWg6MlgMDggEAAAD//wMAIRKl6nQ6gLIAAAAASUVORK5CYII=) round;
    -o-border-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAbklEQVR4nGL4W8zBMJAYmbMCiJ9C8Qosimkijyz5Hw2vQNNME3mYgqdYFDxFMoBm8oPGAQMeBQOeCAdFNhxwB4yWA6PlwGg5MODZcMAdMFoOjJYDo+XAgGfDAXfAaDkwWg6MlgMDggEAAAD//wMAIRKl6nQ6gLIAAAAASUVORK5CYII=) round;
    border-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAbklEQVR4nGL4W8zBMJAYmbMCiJ9C8Qosimkijyz5Hw2vQNNME3mYgqdYFDxFMoBm8oPGAQMeBQOeCAdFNhxwB4yWA6PlwGg5MODZcMAdMFoOjJYDo+XAgGfDAXfAaDkwWg6MlgMDggEAAAD//wMAIRKl6nQ6gLIAAAAASUVORK5CYII=) round;
    border-image-slice: 25%;
}
<div class="block">
    <article>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloremque quasi officia vero aut. Velit ratione sapiente fugiat rerum eos ipsa praesentium autem similique vitae reprehenderit et tempora optio eveniet facilis. (SVG)</article>
</div>
<p></p>
<div class="block2">
    <article>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloremque quasi officia vero aut. Velit ratione sapiente fugiat rerum eos ipsa praesentium autem similique vitae reprehenderit et tempora optio eveniet facilis. (CSS)</article>
</div>
<p></p>
<div class="block3">
    <article>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloremque quasi officia vero aut. Velit ratione sapiente fugiat rerum eos ipsa praesentium autem similique vitae reprehenderit et tempora optio eveniet facilis. (CSS3)</article>
</div>