简体   繁体   中英

CSS - border around group of divs

I am backend dev, trying to get better at frontend things. I am wondering if there is any way, if you have a group of divs next to each other to draw a border around them when they do not represent a square shape. Here an example of what I am trying:

 #child1 { top: 0px; left: 0px; background:red; } #child2 { top: 50px; left: 0px; background:blue; } #child3 { top: 0px; left: 50px; background:green; }.child { position: absolute; width: 48px; height: 48px; border: 2px black solid; }
 <div> <div style="position: relative" class="parent"> <div id="child1" class="child">1</div> <div id="child2" class="child">2</div> <div id="child3" class="child">3</div> </div> </div>

https://jsfiddle.net/udxes0z3/

I would like to have the borders you can see but not the borders between "1" + "3" and "1" + "2". Is there any way this can done via CSS ? I would like to avoid calculating those borders programmatically (that is what I am currently doing, which is causing performance issues).

Thx for any hints or telling me this is not possible;-)

*edit

The example is over simplified compared to the "real" problem, actuals shapes may look like this:

实际形状示例

This is possible by introducing a pseudo element on each square.

We draw the initial setup but with each square having twice the desired end-result border width. Then overlay each square with a square of the same color, with no border, slightly bigger and higher z index.

This then covers half the border round itself. And as the squares' borders overlap each other these overlaid squares between them overlay the inner borders and leave half the width of the outer border (ie you get the desired outer width).

There is a wrinkle. The content of each square gets overlaid as well. For this test I've put the content into the content of the pseudo element. But this may not be suitable for an entirely general situation and we'd have to look at putting an extra element inside each square with its content and showing that above the pseudo element.

Assuming this is the desire outcome for now: 在此处输入图像描述

Here is the snippet. Note, dimensions and colors have been put into CSS variables to make it easier to try different layouts.

 * { margin: 0; padding: 0; } #child1 { top: 0px; left: 0px; --bg: red; } #child2 { top: var(--w); --bg: blue; } #child3 { top: 0px; left: var(--w); --bg: green; }.child { --w: 50px;/* width and height of each square */ --b: 2px;/* width of border */ position: absolute; background-color: var(--bg); width: calc(var(--w) - (2 * var(--b))); height: calc(var(--w) - (2 * var(--b))); border: calc(2 * var(--b)) black solid; }.child::after { content: '1'; position: absolute; background-color: var(--bg); top: calc(var(--b) * -1); left: calc(var(--b) * -1); width: calc(var(--w) - var(--b)); height: calc(var(--w) - var(--b)); opacity: 1; border: 1px transparent solid; z-index: 9999; } #child1::after { content: '1'; } #child2::after { content: '2'; } #child3::after { content: '3'; }
 <div> <div style="position: relative" class="parent"> <div id="child1" class="child"></div> <div id="child2" class="child"></div> <div id="child3" class="child"></div> </div> </div>

Here is my attempt, although it is not completely dynamic as it will rely on additional css class against the parent element:

 .parent { border: 2px black solid; display: grid; grid-template-columns: 1fr 1fr; }.parent.odd:after { content: ''; border-top: 2px black solid; border-left: 2px black solid; box-shadow: 2px 2px 0 0 white; // box-shadow covers parent's border }.child { height: 48px; } #child1 { background:red; } #child2 { background:blue; } #child3 { background:green; }
 <div> <:-- add "odd" css class from code behind --> <div style="position: relative" class="parent odd"> <div id="child1" class="child">1</div> <div id="child2" class="child">2</div> <div id="child3" class="child">3</div> </div> </div>

I am also using css grid in this example, which may not be the right solution depending on browser support needed - https://caniuse.com/?search=grid

Just remove the borders where you want that to occur.

 .child { position: absolute; width: 48px; height: 48px; border: 2px black solid; } #child1 { top: 0px; left: 0px; background: red; border-right-style: none; border-bottom-style: none; } #child2 { top: 50px; left: 0px; background: blue; border-top-style: none; } #child3 { top: 0px; left: 50px; background: green; border-left-style: none; }
 <div> <div style="position: relative" class="parent"> <div id="child1" class="child">1</div> <div id="child2" class="child">2</div> <div id="child3" class="child">3</div> </div> </div>

Note: on high def screens, eg retina, where several screen pixels make up one CSS pixel you may see a faint line between some squares. I think this depends on whether the calculation results in part-CSS pixels. We may need to expand each overlaid square by a pixel to get over this, but I haven't experimented as yet.


Now of course the challenge is to not have this so simplified. Thus we might slide them under the sibling but not have borders on the "first" sibling (red). Since you are positioning them, this sort of works.

 .child { position: absolute; width: 48px; height: 48px; border: 2px black solid; } #child1 { top: 0px; left: 0px; background: red; border-right-style: none; border-bottom-style: none; z-index: 1; } #child2 { top: 50px; top: 48px; left: 0px; background: blue; z-index: -10; } #child3 { top: 0px; left: 50px; left: 48px; background: green; z-index: -10; }
 <div> <div style="position: relative" class="parent"> <div id="child1" class="child">1</div> <div id="child2" class="child">2</div> <div id="child3" class="child">3</div> </div> </div>

Since you are positioning them, this sort of works if you use flex.

I don't have time to fully vet that but perhaps some use as in this question which is slightly related to that concept How to create “collapsed” borders around flex items and their container?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM