I want to create fancy borders for an element but the vertical lines are giving me trouble
- the right side looks correct in this example but only works for this specific size (which i don't want) and AFAIK there is no way to calc() the width based on the height.
- I don't want to use another image for verical lines, but if there is no other solution, I would.
- I am not married to this approach but it's the only one I've been able to figure out.
Can anyone tell me how I can fix this?
.block
{
position: relative;
width: 400px;
height: 200px;
margin: auto;
background-color: silver;
}
.border
{
position: absolute;
width: 100%;
height: 100%;
}
.corner
{
width: 16px;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCA1LjEuN4vW9zkAAAC2ZVhJZklJKgAIAAAABQAaAQUAAQAAAEoAAAAbAQUAAQAAAFIAAAAoAQMAAQAAAAIAAAAxAQIAEAAAAFoAAABphwQAAQAAAGoAAAAAAAAAYAAAAAEAAABgAAAAAQAAAFBhaW50Lk5FVCA1LjEuNwADAACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAWgBAABAAAAlAAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAAAlR56NozS1xQAAAFRJREFUOE+1kkEOABAMBNX//8xNlgwNrUkcumTTbllh2ioIpkXV4gXPwOQgnsEzzclhYPBQNbqfSBmB2iUNuekATXcGx9UpbkhA7k/8BgZGhEcIG3SUNQ8QLldnBgAAAABJRU5ErkJggg==');
}
.ne { transform: rotate(90deg); }
.se { transform: rotate(180deg); }
.sw { transform: rotate(270deg); }
.edge
{
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCA1LjEuN4vW9zkAAAC2ZVhJZklJKgAIAAAABQAaAQUAAQAAAEoAAAAbAQUAAQAAAFIAAAAoAQMAAQAAAAIAAAAxAQIAEAAAAFoAAABphwQAAQAAAGoAAAAAAAAAYAAAAAEAAABgAAAAAQAAAFBhaW50Lk5FVCA1LjEuNwADAACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAWgBAABAAAAlAAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAAAlR56NozS1xQAAAB9JREFUOE9jYBgFFANGBgaG/+iCpAAmdIFRMAoGBAAA0EYBA3ATNTsAAAAASUVORK5CYII=');
background-repeat: repeat-x;
}
.n { flex-grow: 1; }
.e { transform: rotate(90deg); background-repeat: repeat-y; }
.s { flex-grow: 1; transform: rotate(180deg); }
.w { transform: rotate(270deg); background-repeat: repeat-x;};
<div class="block">
<div class="border" style="display:flex; flex-direction: column">
<div style="height: 16px; display:flex; flex-direction: row;">
<div class="corner nw"></div>
<div class="edge n"></div>
<div class="corner ne"></div>
</div>
<div style="flex-grow: 1; display:flex; flex-direction: row;">
<div class="edge w" style="background-color: #ffff0015; height: 16px; width: 168px; position:relative; top: 76px; right:76px"></div>
<div style="flex-grow: 1;"></div>
<div class="edge e" style="background-color: #ff000015; width: 16px;"></div>
</div>
<div style="height: 16px; display:flex; flex-direction: row;">
<div class="corner sw"></div>
<div class="edge s"></div>
<div class="corner se"></div>
</div>
</div>
<div style="padding: 12px">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</div>
I want to create fancy borders for an element but the vertical lines are giving me trouble
- the right side looks correct in this example but only works for this specific size (which i don't want) and AFAIK there is no way to calc() the width based on the height.
- I don't want to use another image for verical lines, but if there is no other solution, I would.
- I am not married to this approach but it's the only one I've been able to figure out.
Can anyone tell me how I can fix this?
.block
{
position: relative;
width: 400px;
height: 200px;
margin: auto;
background-color: silver;
}
.border
{
position: absolute;
width: 100%;
height: 100%;
}
.corner
{
width: 16px;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCA1LjEuN4vW9zkAAAC2ZVhJZklJKgAIAAAABQAaAQUAAQAAAEoAAAAbAQUAAQAAAFIAAAAoAQMAAQAAAAIAAAAxAQIAEAAAAFoAAABphwQAAQAAAGoAAAAAAAAAYAAAAAEAAABgAAAAAQAAAFBhaW50Lk5FVCA1LjEuNwADAACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAWgBAABAAAAlAAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAAAlR56NozS1xQAAAFRJREFUOE+1kkEOABAMBNX//8xNlgwNrUkcumTTbllh2ioIpkXV4gXPwOQgnsEzzclhYPBQNbqfSBmB2iUNuekATXcGx9UpbkhA7k/8BgZGhEcIG3SUNQ8QLldnBgAAAABJRU5ErkJggg==');
}
.ne { transform: rotate(90deg); }
.se { transform: rotate(180deg); }
.sw { transform: rotate(270deg); }
.edge
{
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCA1LjEuN4vW9zkAAAC2ZVhJZklJKgAIAAAABQAaAQUAAQAAAEoAAAAbAQUAAQAAAFIAAAAoAQMAAQAAAAIAAAAxAQIAEAAAAFoAAABphwQAAQAAAGoAAAAAAAAAYAAAAAEAAABgAAAAAQAAAFBhaW50Lk5FVCA1LjEuNwADAACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAWgBAABAAAAlAAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAAAlR56NozS1xQAAAB9JREFUOE9jYBgFFANGBgaG/+iCpAAmdIFRMAoGBAAA0EYBA3ATNTsAAAAASUVORK5CYII=');
background-repeat: repeat-x;
}
.n { flex-grow: 1; }
.e { transform: rotate(90deg); background-repeat: repeat-y; }
.s { flex-grow: 1; transform: rotate(180deg); }
.w { transform: rotate(270deg); background-repeat: repeat-x;};
<div class="block">
<div class="border" style="display:flex; flex-direction: column">
<div style="height: 16px; display:flex; flex-direction: row;">
<div class="corner nw"></div>
<div class="edge n"></div>
<div class="corner ne"></div>
</div>
<div style="flex-grow: 1; display:flex; flex-direction: row;">
<div class="edge w" style="background-color: #ffff0015; height: 16px; width: 168px; position:relative; top: 76px; right:76px"></div>
<div style="flex-grow: 1;"></div>
<div class="edge e" style="background-color: #ff000015; width: 16px;"></div>
</div>
<div style="height: 16px; display:flex; flex-direction: row;">
<div class="corner sw"></div>
<div class="edge s"></div>
<div class="corner se"></div>
</div>
</div>
<div style="padding: 12px">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</div>
Share
Improve this question
edited Mar 31 at 10:48
Kempeth
asked Mar 31 at 8:57
KempethKempeth
1,9482 gold badges22 silver badges40 bronze badges
3 Answers
Reset to default 1You can do it using only the corner image and a few gradients.
.box {
--c: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCA1LjEuN4vW9zkAAAC2ZVhJZklJKgAIAAAABQAaAQUAAQAAAEoAAAAbAQUAAQAAAFIAAAAoAQMAAQAAAAIAAAAxAQIAEAAAAFoAAABphwQAAQAAAGoAAAAAAAAAYAAAAAEAAABgAAAAAQAAAFBhaW50Lk5FVCA1LjEuNwADAACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAWgBAABAAAAlAAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAAAlR56NozS1xQAAAFRJREFUOE+1kkEOABAMBNX//8xNlgwNrUkcumTTbllh2ioIpkXV4gXPwOQgnsEzzclhYPBQNbqfSBmB2iUNuekATXcGx9UpbkhA7k/8BgZGhEcIG3SUNQ8QLldnBgAAAABJRU5ErkJggg==");
--_l: conic-gradient(#000 0 0) no-repeat;
background:
var(--_l) 50% 5px,
var(--_l) 5px 50%,
var(--_l) 50% calc(100% - 5px),
var(--_l) calc(100% - 5px) 50%;
background-size: calc(100% - 32px) 2px,2px calc(100% - 32px);
background-color: lightblue;
position: relative;
padding: 16px;
font-size: 20px;
}
.box:before,
.box:after,
.box i:before,
.box i:after {
content:"";
position: absolute;
width: 16px;
aspect-ratio: 1;
background: var(--c);
}
.box:before {
inset: 0 auto auto 0;
}
.box:after {
inset: auto auto 0 0;
scale: 1 -1;
}
.box i:before {
inset: auto 0 0 auto;
scale: -1;
}
.box i:after {
inset: 0 0 auto auto;
scale: -1 1;
}
<div class="box">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<i></i>
</div>
There are better ways to do this, as Temani Afif shows,
To answer your question, since you're rotating the complete element using right
and top
to align the west side, copying the same CSS for the east side (changing right
to left
) will have the same outcome
.block
{
position: relative;
width: 400px;
height: 200px;
margin: auto;
background-color: silver;
}
.border
{
position: absolute;
width: 100%;
height: 100%;
}
.corner
{
width: 16px;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCA1LjEuN4vW9zkAAAC2ZVhJZklJKgAIAAAABQAaAQUAAQAAAEoAAAAbAQUAAQAAAFIAAAAoAQMAAQAAAAIAAAAxAQIAEAAAAFoAAABphwQAAQAAAGoAAAAAAAAAYAAAAAEAAABgAAAAAQAAAFBhaW50Lk5FVCA1LjEuNwADAACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAWgBAABAAAAlAAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAAAlR56NozS1xQAAAFRJREFUOE+1kkEOABAMBNX//8xNlgwNrUkcumTTbllh2ioIpkXV4gXPwOQgnsEzzclhYPBQNbqfSBmB2iUNuekATXcGx9UpbkhA7k/8BgZGhEcIG3SUNQ8QLldnBgAAAABJRU5ErkJggg==');
}
.ne { transform: rotate(90deg); }
.se { transform: rotate(180deg); }
.sw { transform: rotate(270deg); }
.edge
{
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCA1LjEuN4vW9zkAAAC2ZVhJZklJKgAIAAAABQAaAQUAAQAAAEoAAAAbAQUAAQAAAFIAAAAoAQMAAQAAAAIAAAAxAQIAEAAAAFoAAABphwQAAQAAAGoAAAAAAAAAYAAAAAEAAABgAAAAAQAAAFBhaW50Lk5FVCA1LjEuNwADAACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAWgBAABAAAAlAAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAAAlR56NozS1xQAAAB9JREFUOE9jYBgFFANGBgaG/+iCpAAmdIFRMAoGBAAA0EYBA3ATNTsAAAAASUVORK5CYII=');
background-repeat: repeat-x;
}
.n { flex-grow: 1; }
.e { transform: rotate(90deg); background-repeat: repeat-x; }
.s { flex-grow: 1; transform: rotate(180deg); }
.w { transform: rotate(270deg); background-repeat: repeat-x;};
<div class="block">
<div class="border" style="display:flex; flex-direction: column">
<div style="height: 16px; display:flex; flex-direction: row;">
<div class="corner nw"></div>
<div class="edge n"></div>
<div class="corner ne"></div>
</div>
<div style="flex-grow: 1; display:flex; flex-direction: row;">
<div class="edge w" style="background-color: #ffff0015; height: 16px; width: 168px; position:relative; top: 76px; right:76px"></div>
<div style="flex-grow: 1;"></div>
<div class="edge e" style="background-color: #ff000015; height: 16px; width: 168px; position:relative; top: 76px; left:76px"></div>
</div>
<div style="height: 16px; display:flex; flex-direction: row;">
<div class="corner sw"></div>
<div class="edge s"></div>
<div class="corner se"></div>
</div>
</div>
<div style="padding: 12px">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</div>
After a bunch more searching it turns out that CSS actually has native functionality for this:
.block
{
position: relative;
width: 400px;
margin: auto;
background-color: silver;
}
.better .border
{
position: absolute;
width: calc(100% - 32px);
height: calc(100% - 32px);
border: 16px solid red; //needed to reserve space
border-image-source: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMAAAADACAYAAABS3GwHAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCA1LjEuN4vW9zkAAAC2ZVhJZklJKgAIAAAABQAaAQUAAQAAAEoAAAAbAQUAAQAAAFIAAAAoAQMAAQAAAAIAAAAxAQIAEAAAAFoAAABphwQAAQAAAGoAAAAAAAAA8nYBAOgDAADydgEA6AMAAFBhaW50Lk5FVCA1LjEuNwADAACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAWgBAABAAAAlAAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAABCqaniuvll8QAAAxNJREFUeF7t2cGu2jAUQMHS///n1w0rL3DSXkLomZHYRJEBmSMb5/Fr3s964c0e6wUu9dXz/Xu9ACUCIE0ApAmANAGQJgDSBEDa6Jnq0+5c+Ox7To/HrOn5mR7vJSsAaQIgTQCkCYA0AZAmANIEQNromerTpee4fNxXz7cVgDQBkCYA0h4H9nA76x5vN97Z+7mXs/N39v5LWQFIEwBpAiBNAKQJgDQBkCYA0o48B1jPcXemx+Pe7j7fLz+fFYA0AZAmANK+4T/A9HjMmp6fS8ezApAmANIEQNo7AnhsXnAb7wgAvoYASBMAaUeeA9yd/xWf9a+/n3X+duOdvf8lKwBpAiBNAKQJgDQBkCYA0gRA2nqmCp+2O9cf/c1aAUgTAGkCIG10P/V06R6O/86lvx8rAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBEDaY70w4Ge9sHjHe8JfsQKQJgDSBEDa48CefWfd0+/GO3v/zjoe1/rX+fsoKwBpAiBNAKQJgDQBkCYA0gRA2pHnAGfP2e8+HrPuPj8vP58VgDQBkCYA0gTA3fxsXqMEQJoASBMAae94DjDt7p+PWdPz/XI8KwBpAiBNAKQd+Q9wtXWPt/t8Z+/nXs7O39n7X7ICkCYA0gRAmgBIEwBpAiBNAKStZ6p3tDvn/YbvwHGXzrcVgDQBkCYA0kb3U0/Te7jp8Zg1PT/T471kBSBNAKQJgDQBkCYA0gRAmgBIGz1Tfdqd4057x3fguK+ebysAaQIgTQCkCYA0AZAmANIEQNofx71CaG/04swAAAAASUVORK5CYII=');
border-image-slice: 64; // take 64px from either image edge and use rest for border edges
border-image-width: 1; // multiplies standard border-width
}
<div class="block">
<div class="border"></div>
<div style="padding: 12px">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</div>