Uncle Bojangles
Uncle Bojangles

Reputation: 99

Stacking borders in CSS

I'm filling a parent div with dynamically generated child divs. I'd like for the child divs to be bound by the parent (so they can't expand the parent's shape horizontally as they fill with content). At the same time, I'd like for the child div borders to sit on top of the parent div borders, as well as each others. I threw together a diagram to better explain:

Diagram

What is the best way to accomplish this via CSS? I've looked around, and I can't seem to find a solution that both stacks the borders, but also keeps the child divs restricted by the parent div (on the x axis).

Upvotes: 4

Views: 4508

Answers (4)

Erdem
Erdem

Reputation: 32

you can also try this one. Define two different classes. "Border" class for border width and style. And a color class. Like this:

<style>
     .border { 
              border: 5px solid;
             }

    .green {
            border-color: green;
            border-top-width: 0px;
           }

    .yellow {
             border-color: yellow;
            }
  /*I do not use a border-top-width to remowe top because this is the first div.*/

    .red {
          border-color: red;  
          border-top-width: 0px;
         }
</style>
    <div class="container">
      <div class="border yellow">yellow</div>
      <div class="border green">green</div>
      <div class="border red">black</div>

    </div>

Upvotes: 0

Ines Montani
Ines Montani

Reputation: 7105

Overlapping borders are always a little tricky. In your case, I wouldn't recommend working with absolute positions and z-indexes – this will only make things more complicated and you won't be able to rely on the native behaviour of block elements anymore.

Let's say your HTML looks like this:

<div class="parent">
    <div class="child yellow"></div>
    <div class="child blue"></div>
    <div class="child red"></div>
</div>

You can achieve the illusion of overlapping children by only applying a top border to the :first-child. Even if you add more divs dynamically to the top, the first one will always be the one that appears to be "on top":

.child {
    border-style: solid;
    border-width: 0 2px 2px 2px;
    background: white;
}

.child:first-child {
    border-top-width: 2px;
}

.yellow { 
    border-color: yellow;
}

.blue {
    border-color: blue;
}

.red {
    border-color: red;
}

The parent needs a little hack, because if you added a regular border around it, it would be displayed around the children.

.parent {
    width: 500px; /* or any other width */
    height: 100vh; /* or any other fixed height */
    overflow-y: auto; /* make scrollable */
    box-shadow: inset 2px 2px 0 black, inset -2px -2px 0 black;
}

The inset box-shadow creates the illusion of solid border on the inside of the parent. To make sure it's not visible underneath the children borders (box-shadows tend to be slightly blurrier than borders), you need to make sure the children have a background colour.

Edit: Here's a demo.

Upvotes: 6

Gabriela Marques
Gabriela Marques

Reputation: 111

If I understand you right, you could place the border of the parent using :after and position absolute, with z-index:-1:

.parent { position: relative; }
.parent:after {
  content: '';
  position: absolute;
  z-index: -1;
  left: 0px;
  right: 0px;
  top: 0px;
  bottom: 0px;
  border: 1px solid black;
}

and for the children, you could remove the top border if not the : first:

.child:not(:first-child) {
  border-top: 0;
}

Upvotes: 0

phenomenia
phenomenia

Reputation: 109

You can influence the stack order in css with z-index but you need to use a position:absolute or position:fixed on these elements.

.div1 {
    width: 200px;
    height: 100px
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1    
}
.div2 {
    width: 200px;
    height: 100px
    position: absolute;
    top: 190px;
    left: 0;
    z-index: 2    
}

That css should display the .div2 10px overlapping the .div1 If the height is dynamic you can either add it by JS or add on div as child in the next. Note that each "position" attribute relates to the recent parent position relative or absolute!

Upvotes: 0

Related Questions