0

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>

3 Answers 3

1

You 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>

Sign up to request clarification or add additional context in comments.

Comments

0

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>

2 Comments

Unfortunately this answer only works for elements of a know height. The right side was intended only to demonstrate the desired look.
You;re using a static height already, maybe clarify that in the OP?
0

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.