In the previous tutorial, we learned how to make an 1800s-style CSS border with a single-motif repeating element:
Now, you will learn 3 ways to create horizontal lines with repeating Victorian motifs, where the repeating elements are not identical. See the example below, be sure to drag the “resize handle” to see how these lines adapt to different widths:
Method B:
Method C:
Like in the previous post, we will be using the free Inkscape for vector editing.
Table of contents:
- Get the images and vectorize them
- Approach A: simple repetition. Alternating wide/narrow in the centre.
- Approach B: double repetition. Always a narrow element in the centre.
- Approach C: one-and-two-halves repetition. Always a wide element in the centre.
Get the image
We’ll be working with the Recueil des divers caractères, vignettes et ornements de la fonderie et imprimerie de J. G. Gillé from 1808.
Let’s choose an asymmetrical (or, dual-motif) pattern. In the below screenshot, the central motifs in specimens 98, 100 and 101 are suitable.

We will use number 100 for this tutorial:

First, we turn it into a vector (SVG) and group the wide elements and narrow elements separately.
Approach A: simple repetition
The following method is the simplest way to fill in a horizontal line. We will use the background-image property with a horizontal repetition.
The line will be symmetrical, but sometimes the central element will be “wide” and sometimes “narrow”. This is a weakness – if you ever want to put a special one-of-a-kind element in the middle of the line, you wouldn’t know whether to make it wide or narrow.
Initially, we will repeat this image horizontally:
Here is the CSS for a basic repetition:
hr.ayh{
background-image: url( 'four-repeat-both.svg' ); /* our image */
background-repeat: repeat-x; /* repeat it horizontally, in the x-dimension */
background-position: left top;
height: 21px;
border: 0;
}
This approach often cuts off the pattern, depending on the width of the element:

Our goal is to restrict the width of this element to a value that prevents cutoff and where the pattern is symmetrical. We want the width of our element to “land in between” the patterns.
To do that we will use the CSS functions calc(), which performs basic math functions, and round() which lets us round-down to the nearest multiple of a value.
My goal is to have the line be at least as wide as 1 of the wider segments of our repeating element (39px). With the width increasing from there only by full multiples of 59px.

That setup will ensure that there will always be a wide element at the far-left of our line, a wide element at the far-right, and one of the narrow 20px elements in the centre.
We add the extra property in bold:
hr.ayh{
width: calc(39px + round(down,calc( 100% - 39px),59px));
background-image: url( 'four-repeat-both.svg' ); /* our image */
background-repeat: repeat-x; /* repeat it horizontally, in the x-dimension */
background-position: left top;
height: 21px;
border: 0;
}
Here is a detailed explanation of what we’re doing:

And here is the result:
Approach B: narrow element in the center, double repetition
Now we will set up the line so that there is always a narrow element in the centre.
For this approach, we will use the powerful Border-Image property. This property lets us slice an image into 9 pieces, to use 4 of those pieces are the top & bottom edges and the rest as repeating vertical and horizontal elements.

Read more about the Border-Image property at Smashing Magazine.
Below is the source image we will slice up for use as a border:

Here are the important parts of this image:
- The far left portion of the border. It does not repeat.
- The middle – made up of 2 repetitions of our asymmetrical repeating motif.
- The far right portion – also does not repeat.
- … there are no other slices. Because we’re creating a horizontal line and not a full surround border, we will slice the image into 3 pieces instead of 9.
The setup above will always result in the line starting and ending with the wide 39px elements for a symmetrical look.
Why do we need 2 repetitions for the middle part?
Border-Image has a counter-intuitive behaviour with the middle repeating portion: as your element gets wider, the middle part of the pattern stays centred. More of the pattern is gradually revealed to the left and to the right of the middle portion as the width grows.
Let me illustrate.
The top image shows what happens when the width fits the image above neatly: 59px + 118px + 39px = 216px.
As the width grows, the red and blue middle portion remains centred, and additional portions are added on both sides.

Here is the commented CSS code that lets us slice the image and restrict the line width to “neat looking” values:
hr.bee {
border-image-source: url( 'multi-size-centered2.svg' );
/* the image we will chop into "left side", "right side" and "repeating middle" */
border-image-slice: 21 39 0 59;
/* from the top: 21px - that's how tall the image is
from the right: inset 39px for the "right side" border image
from the bottom: 0px - we are not creating a bottom border for this example
from the left: chop 59px for the "left side" of the pattern
*/
border-image-width: 21px 39px 0 59px;
/* the width for our "image border" will have the same dimensions as the slices we took from the original
.svg file. We are not stretching or compressing the slices.
*/
box-sizing: content-box;
/* our "width" will not include the padding/margin/border in it */
padding: 0px 39px 0px 59px;
/* add padding on the left and right, to make space for (and match the size of) the left & right portions of the border */
border-image-repeat: repeat;
/* we will repeat the middle portion of our pattern, without compressing it to fit */
width: round(down,calc(100% - 98px),118px);
/*
We allow the wdth to only have values that prevent pattern cut-off.
Because we set box-sizing to "content-box" we are only dealing with the width of the middle repeating portion.
So, the width of it will be 100% of the parent, minus the width of the right & left static portions (39px + 59px = 98px).
Then, beyond that, we will round to sizes that include 2 full repetitions of our middle portion, which is
59px+59px = 118px. We will only reveal widths in increments of 2 full asymmetrical elements
*/
border-image-outset: 0;
/* no outset - our border image will appear where the border would usually appear */
height: 21px;
/* the height of our border .svg */
}
Once again, here is the final result:
Approach C: wide element in the center, element & 2 halves
In this method, we will use the border-image attribute while always keeping a wide element at the centre.
Here is the image that we will slice up for use as border-image:
As we saw above, as the “middle” of your line grows the pattern is repeated on both sides of the centre line. So, in order to turn the image above into a neatly-repeating border, we have to set the width according to this graphic:

We want the middle (red) portion just wide enough that the narrow elements get fully fleshed out to the sides.
Here is the commented CSS code that helps us set this up:
hr.cee {
border-image-source: url( 'five-border-image.svg?sdfsdf' );
/* the image we will chop into "left side", "right side" and "repeating middle" */
border-image-slice: 21 39 0 39;
/* from the top: 21px - that's how tall the image is
from the right: inset 39px for the "right side" border image - 1 "wide" element
from the bottom: 0px - we are not creating a bottom border for this example
from the left: chop 39px for the "left side" of the pattern
*/
border-image-width: 21px 39px 0 39px;
/* the width for our "image border" will have the same dimensions as the slices we took from the original
.svg file. We are not stretching or compressing the slices.
*/
box-sizing: border-box;
/* border-box sizing: when we set the "width", it'll encompass padding and borders too */
padding: 0px 39px 0px 39px;
/* leave space for the "left" and "right" bumper elements */
border-image-repeat: repeat;
/* we will repeat the middle portion of our pattern, without compressing it to fit */
width: calc(79px + 78px + round(down,calc(100% - 78px - 79px),118px));
/*
The goal is to permit only widths that prevent pattern cutoff.
Because box-sizing is "border-box", we have to factor in the width of the padding into our final width.
We start with a minimum width of 79px (one whole middle section with the 10+39+10=59 elements PLUS
and extra 10+10 to complete the "small" elements in the middle = 59+10+10 = 79.
Then we add another minimum +78px which represents the left and right non-repeating bumpers: 39+39.
Then, we take the full with of the entire parent = 100%, and subtract this amount from it.
Whatever is left over, represents the width of the middle portion's width above what it takes
to render the 2 wide bumpers on the sides, 1 wide element in the middle, with 2 small elements on its sides.
Next, we take that middle portion and round it down to the smallest multiple of 118px, which is 2
full repetitions of the middle portion: 79px + 79px. This repeats the middle portion symmetrically
on both sides of the centre line without cutoff.
*/
border-image-outset: 0;
/* no outset - our border image will appear where the border would usually appear */
height: 21px;
/* the height of our border .svg */
border-width: 0;
/* needed to ensure our width is correct to the pixel */
}
And the final result from this code:










































































































































