最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

css - How can I use a rotated, repeating background image (inside a partially flex-box-ed container)? - Stack Overflow

programmeradmin2浏览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>

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
Add a comment  | 

3 Answers 3

Reset to default 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>

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>

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论