Stacking borders in CSS - border

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:
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).

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.

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!

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;
}

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>

Related

How to show the border css over the div element?

Image attached in this link
In number 9 cell border is over the background color
How do I show the border over the div or background Color and it should be responsive?
<div className="borderOverDiv"><div>
<div className="backgroundClr"></div>
.borderOverDiv{
position: absolute;
border: 1px solid red;
width: calc(100% - 94%);
height: 30px;
border-radius: 10px;
}
.backgroundClr{
background: blue
}
this code as I tried, seems not working
I am assuming that you are new to css so I will try to explain what is going on with this code the best that i can.
The fun part is in .element.active:after
There is a few thing
position: absolute this will allow us to set this element absolutly to container. But witch container? First that has position set to a different value than static or its initial value. That is why .element has position: relative which doesn't do anything on its own.
top, right, bottom, left which tell that this element will be exceeding parent element on every side by 5px.
z-index Simply the higher the value the "closer" this element is to user. initial value is 0 so 1 is placing this element above every other element.
content is required in pseudo-element :after in order to show them. This property just needs to be set and doesn't have to have any value specified.
The reis is just to make it look nicer.
And thats it.
You can use other element inside .element if you feel like it.
For example
<div class="element">
<div class="overlay"></div>
</div>
and it will work just fine if you will follow point form 1 to 3 (point 4 is required, as I said earlier, only in pseudo-element) but it will be less responsive. For example what will you have to do when other element needs this overlay? You will have to use javascript to append .overlay element to .element and with pseudo-element you just need to append class. or just show this overlay on hover. Other advantage is that it look prettier and doesn't bloat you html.
.container {
padding: 5px;
display: flex;
}
.element {
position: relative;
background-color: #0000ff;
padding: 10px 20px;
display: inline-block;
color: #ffffff;
}
.element.active:after {
content: '';
position: absolute;
top: -5px;
right: -5px;
bottom: -5px;
left: -5px;
border-radius: 40px;
background-color: rgba(200, 200, 200, .4);
border: 1px solid rgba(200, 200, 200 ,.8);
z-index: 1;
}
<div class="container">
<div class="element">7</div>
<div class="element active">8</div>
<div class="element">9</div>
</div>
replacing className with class should do the trick

Adjusting CSS border without affecting div placement

I'm attempting to adjust the margins on the border-right property I added to create a vertical border between two divs. When adjusting these margins in the class that produces the margin, I am affecting the margins of the whole div rather then just the border.
I've attempted to add a pseudo-class that would only affect the border but it has no affect to the border display.
How can I affect the margins of just the border?
.border {
border-right: 3px solid
}
.border:after {
margin-left: 30px
}
.width {
width: 20%;
}
<div class='width border'>
<p> hello </p>
</div>
I would approach this using a background-color in the pseudo-class to mimic a border. By making the :after content an absolutely positioned element of the now relative parent, .mydiv, we can pin the new "border" to be 30px away from the right edge of the parent, whatever its width may be.
.mydiv {
position: relative;
width: 20%;
}
.border:after {
margin-left: 30px;
content: '';
position: absolute;
top: 0;
right: -30px;
width: 3px;
height: 100%;
background-color: black;
}
<div class='width border mydiv'>
<p> hello </p>
</div>

z-index wont work positions

I'm trying to achieve that the erf_fromto would have a higher z-index than left_side, cause left_side do have a border, while i want the erf_fromto to be over the border.
this is how it looks like currently, while I want the erf_fromto to be over the line.
<body class="parent" ng-app="myApp">
<div class="left_side child"></div>
<div class="right_side">
<div class="erf_block" style="position:relative;">
<div class="erf_fromto">2011 - 2012</div>
</div>
</div>
</body>
css:
.left_side {
width:35%;
float:left;
border-right: 3px solid #F6F6F6;
}
.parent {
overflow: hidden;
position: relative;
}
.child {
height: 100%;
position: absolute;
}
.erf_fromto {
position: absolute;
left: -122px;
border: 2px solid #F6F6F6;
padding: 5px;
font-weight: bold;
box-shadow: 0px 0px 2px #F6F6F6;
font-size: 15px;
z-index: 99;
overflow: hidden;
}
codepen: http://codepen.io/anon/pen/XjzwdN
z-index applies to an element and it's children. Since .erf_fromto is nested inside .erf_block, which is inside .right_side you'll want to ensure that it's .right_side that has the higher z-index than .left_side!
From MDN:
The z-index property specifies the z-order of an element and its descendants. When elements overlap, z-order determines which one covers the other. An element with a larger z-index generally covers an element with a lower one.
If you also put a position: relative; and z-index:0; to the .left_side child it will work
Maria,
If you add a background to left_side and erf_fromto you will see they are on the correct position.
I think you just need add background property on your erf_fromto class:
.erf_fromto {
...
background: white;
...
}
I hope it helps...
Good Luck!

Parent inset box-shadow overlapped by children divs

I am having an issue where the children divs are overlapping the parents box-shadow bottom.
The parent has a max-height w/ overflow-y: scroll. Any help would be great!
http://i.stack.imgur.com/jQe0r.png
HTML:
<div class="capture sh-btm">
<div class="threads">
<div class="thread"></div>
<div class="thread"></div>
<div class="thread"></div>
<div class="thread"></div>
</div>
</div>
CSS:
.capture {
width: 100%;
height: 100%;
overflow-y: scroll;
overflow-x: hidden;
position: relative;
}
.threads {
height: 250px;
width: 100%;
display: inline-block;
padding-bottom: 10px;
position: relative;
clear: left;
}
.thread {
width: 248px;
float: left;
margin-right: 8px;
margin-top: 6px;
border-bottom: 2px solid #dadada;
overflow: hidden;
zoom: 1;
}
.sh-btm {
box-shadow: inset 0px -5px 9px -2px #000;
}
No, what you're asking can be done quite easily. However, for ease I would advise for using a background-image or a CSS gradient instead of inset box-shadows. You'll have to tweak the CSS a bit to get exactly what you wanted. (for example to make sure the bottom overlay doesn't cover the bottom arrow of your scrollbar).
Setting a z-index on the child elements will only work if you have nothing more than static text and images to show, and no links or interactive content. You're also not allowed to set a background for the parent, or it will hide the children.
To achieve this, you need to make 2 separate shadow overlay divs, and position them absolutely in a parent container. Your structure will be like this:
Parent container
Shadow overlay left
Shadow overlay bottom
Threadcontainer (overflow is set on this div)
Thread
Thread
Here is a working demo: http://jsbin.com/avafaq/1/edit
<div class="capture sh-btm">
<div id="shadow_overlay_left"></div>
<div id="shadow_overlay_bottom"></div>
<div class="threads">
<div class="thread"></div>
<div class="thread"></div>
</div>
</div>
#shadow_overlay_left{
width: 10px;
height: 100%;
position: absolute;
z-index: 5;
box-shadow: inset 3px -2px 5px 0px #000;
}
#shadow_overlay_bottom{
width: 100%;
min-height: 10px;
position: absolute;
bottom: 0%;
z-index: 5;
box-shadow: inset 0px -5px 9px 0px #000;
}
.threads {
overflow-y: scroll;
overflow-x: hidden;
}
Notice I put the overflow properties on the .threads container instead of the parent container. This is because else your absolutely positioned divs will scroll too, and will not fill their respective widths/ heights.
Again, you can apply box-shadow, a background-image or CSS gradients to your shadow overlay divs.
You can do it with positioning and box-shadow alone, but browser support would be poor. I used position: sticky (no Chrome support), but a fun experiment anyway.
<div class="wrap">
<!-- We set the overflow on the parent -->
<div class="shadow"></div>
<!-- Create a new container as a layer over the rest of the content -->
<div class="content">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
Use position: sticky instead of absolute, .shadow will stay at the top of its parent as long as the parent is visible, so we set it up with the full height of the parent and offset the content with a negative margin to align it with the top of the parent. Sticky doesn't scroll down with the content like an absolute positioned element would.
You can now set the inset box-shadow to any value and use pointer-events: none to allow interaction with the layer behind the layer with the box-shadow (because positioned elements with a higher z-index will prevent you from interacting with elements behind them).
.wrap{
border: 1px solid #dadada;
/* You'll need a fixed height - assuming that's the case already, given the overflow */
height: 400px;
margin: 5vh auto;
overflow-y: auto;
width: 50vw;
}
.content{
margin-top: -400px;
}
.shadow{
box-shadow: 10px -10px 10px rgba(0, 0, 0, 0.3) inset;
height: 100%;
/* To avoid objects below not being accessible we use pointer events - CSS4 and wonky IE support again */
pointer-events: none;
position: sticky;
/* Firefox doesn't really need the vendor prefix and Chrome doesn't support this */
position: -webkit-sticky;
position: -moz-sticky;
position: -ms-sticky;
position: -o-sticky;
top: 0;
width: 100%;
}
.item{
/* You would obviously add your own styling - just making boxes that show the concept */
background: white;
border: 1px solid #dadada;
box-sizing: border-box;
float: left;
height: 250px;
margin: 1%;
width: 23%;
}
.item:hover{
/* To demonstrate the click through the top layer and :hover works */
background: #f3f3f3;
}
Again - this is experimental and browser support is lacking in places, but proves that you can do it with CSS only.
Fiddle here ...
The problem is that the child elements are higher in the stacking context that the parent. To make the shadow show through, you need to make them lower than the parent.
First of all you need to position the element to make z-index apply, then reduce the z-index to a value lower than the parent. Eg.
.thread {
position: relative;
z-index: -1;
}
http://jsfiddle.net/7PhfJ/
Or as .threads is already positioned, and the box-shadow is on its parent, you can add the z-index directly on that element:
.threads {
z-index: -1;
}
http://jsfiddle.net/7PhfJ/1/

controlling border length

i want to limit the border length applied to a div element(or any HTML elements) . For example consider a div of width 100px, is there anyway to apply the border to only 40px width itself?
You will need to use a child div of the appropriate width to do that. For example:
<div id="outer">
<div id="border"></div>
<p>...</p>
</div>
with:
#outer { width: 100px; padding-top: 0; }
#border { width: 40px; border-top: 1px solid black; margin-top: 0; }
You need to use a nested div or a narrow image as background.
Try not to add a div only to display the border, always try to be semantic. Probably your design need a supplementary section.
Instead of adding another <div> you can simply use a the pseudo selector :before and :after:
div {
position: relative;
}
div:before {
position: absolute;
content:'';
height: 1px;
width: 40%;
background-color: black;
}
here is the fiddle.