Collapse borders of nested DIVs - css

I have a problem styling nested DIVs (see here for an example).
I have some nested DIVs (with class="box") which are dynamically rendered, e.g:
<div class="box" id="1">
other content
<div class="box" id="2">
<div class="box" id="3">
</div>
</div>
other content
<div class="box" id="4">
</div>
</div>
other content
I'd like these DIVs to have a border at the bottom:
<style>
div.box {border-bottom: solid 1px gray;}
</style>
The problem is, when the bottom border of two nested DIVs are adjacent (e.g. box 2 and 3 or box 1 and 4), then the result is a gray line of 2 (or more pixels) height.
Is it possible to collapse the borders of nested DIVs, if they are adjacent?
I tried adding border-collapse: collapse, but that didn't help.

border-collapse property is only applicable to table and inline-table elements.
Try adding margin-bottom property to .box elements with a negative value to overlap the borders as follows:
Example Here
div.box {
border-bottom: solid 1px gray;
margin-bottom: -1px;
}

The border collapse doesn't work, I got it working with your JsFiddle but you probably have to change it because you're DIVs are dynamically created.
div.box > div.box {
border-bottom: solid 1px gray;
}
div.box > div.box > div.box:last-child {
border-bottom: none;
}

css property border-collapse works only with tables...
If you are using div then you can use :last-child selector of css3 to desable border on last .box element
e.g.
box .box:last-child{border:none;}

There is many ways to do that:
1) Make your divs behave like table\table-cell elements.
HTML
<div class="wrapper2">
<div class="row"></div>
<div class="row"></div>
</div>
SCSS
.wrapper2 {
display: table; border-collapse: collapse; margin-bottom: 15px;
.row {
width: 200px; height: 100px; background: green; border: 1px solid red; display: table-cell;
}
}
2) Just select div you need and remove border from one side
HTML
<div class="wrapper">
<div class="row"></div>
<div class="row"></div>
<div class="clearfix"></div>
</div>
SCSS
.wrapper {
width: 404px; margin-bottom: 15px;
.row {
width: 200px; height: 100px; background: green; border: 1px solid red; float: right;
&:first-child { border-left: 0; }
}
.clearfix { clear: both; }
}
3) Overlap divs
HTML
<div class="wrapper3">
<div class="row"></div>
<div class="row move-left"></div>
<div class="clearfix"></div>
</div>
SCSS
.wrapper3 {
width: 404px; margin-bottom: 15px;
.row {
position: relative; width: 200px; height: 100px; background: green; border: 1px solid red; float: left;
&.move-left { left: -1px }
}
.clearfix { clear: both; }
}
All 3 examples on jsfiddle
Just pick something that till fit your project

Related

CSS display:table-row How to width:100%? And border-bottom for rows with padding for table content?

trying to create table with 100% width content, but "width" did not work. can anyone help plz. how can I fix it? And there is "div" inside table cos I can't padding content another way. I need paddin from table borders, and i need bottom lines between table rows. without "border-collapse" "border-bottom" did not work for table rows. So i need add one more div just to do padding :(. Can anyone show me how to do it right without adding one more "div" inside table.
.tabble {
display: table;
border-collapse: collapse;
border-spacing: 10px;
border-radius: 6px;
width: 100%;
}
.table__row {
display: table-row;
width: 100%;
border-bottom: 1px solid red;
}
.table__row:last-child {
border: none;
}
.table__cell {
display: table-cell;
width: 20%;
padding: 10px;
text-align: left;
}
.padding-div {
padding: 5px 20px;
width: 100%"
}
</style>
<div class="tabble">
<div class="padding-div">
<div class="table__row">
<div class="table__cell">1</div>
<div class="table__cell">1</div>
</div>
<div class="table__row">
<div class="table__cell">2</div>
<div class="table__cell">2</div>
</div>
</div>
</div>```
There are a number of things wrong with your table.
There is a typo, " instead of ; in the CSS for .padding-div.
The table cells have width:20%, which interferes with the width calculations. The browser won't know whether to make the two cells together 40% or 100% wide. Remove this.
And the biggest problem, the padding div. You can't have an ordinary div inside a table and with a table row inside. Remove this div. If you want space around the whole table, apply a margin to the table itself.
Then it will have the desired result. That is, if what you want is to make the whole table as wide as the viewport.
.tabble {
display: table;
border-collapse: collapse;
border-spacing: 10px;
border-radius: 6px;
width: calc(100% - 40px); /* changed */
margin: 5px 20px; /* new */
}
.table__row {
display: table-row;
width: 100%;
border-bottom: 1px solid red;
}
.table__row:last-child {
border: none;
}
.table__cell {
display: table-cell;
/*width: 20%;*/ /* removed */
padding: 10px;
text-align: left;
}
.padding-div {
padding: 5px 20px;
width: 100%
}
<div class="tabble">
<div class="table__row">
<div class="table__cell">1</div>
<div class="table__cell">1</div>
</div>
<div class="table__row">
<div class="table__cell">2</div>
<div class="table__cell">2</div>
</div>
</div>
Note: if you do want the table to have a border, as you said in the comments, the solution changes a bit. Then the table itself needs to have a padding, and that means you can't use border-collapse, you'll have to use border-spacing:0 instead, which also means you'll need to apply the inside borders to the cells rather than the rows.
.tabble {
display: table;
border-spacing: 0; /* changed */
border-radius: 6px;
width: calc(100% - 40px); /* changed */
padding: 5px 20px; /* new */
border: 1px solid tan; /* purely for demo purposes */
}
.table__row {
display: table-row;
width: 100%;
}
.table__cell {
display: table-cell;
padding: 10px;
text-align: left;
}
.table__row:not(:last-child) .table__cell {
border-bottom: 1px solid red;
}
<div class="tabble">
<div class="table__row">
<div class="table__cell">1</div>
<div class="table__cell">1</div>
</div>
<div class="table__row">
<div class="table__cell">2</div>
<div class="table__cell">2</div>
</div>
</div>

Wrap container around inline divs

Here is my problem. I have inline-block divs inside another div.
.timeEvents {
width: 100%;
overflow: hidden;
text-align: center;
}
.timeline {
border: 1px solid;
}
.events1, .events2 {
border: 1px solid;
}
.ev1, .ev3 {
border: 1px solid red;
}
.ev2 {
margin: 0 auto;
border: 1px solid red;
display: inline-block;
}
.mDiv {
display: inline-block;
padding-left: 12px;
padding-right: 12px;
border: 1px solid blue;
}
<div class="timeEvents">
<div class="events1">
<div class="ev1">Data Field 1</div>
</div>
<div class="timeline">
<div class="ev2">
<div class="mDiv">5</div>
<div class="mDiv">10</div>
<div class="mDiv">15</div>
<div class="mDiv">20</div>
<div class="mDiv">25</div>
</div>
</div>
<div class="events2">
<div class="ev3">Data Field 2</div>
</div>
</div>
I want the .ev2 to be wrapped around its children which are inline. Then, the two data fields, respectively .ev1 and .ev3 placed above and below, should have the same width as .ev2. Which means that all divs with a red border (in my JSFiddle) should have the same width (dynamic, I don't know it) and that width should not be 100% as it's in the jsFiddle example: https://jsfiddle.net/mzjqw2wx/17/.
EDIT - I updated my fiddle. I don't want to lose the outside 100% divs, I want to align the three red sections to have the same width, the page and the outside divs all remain 100%. The tip to use inline-block on the wrapper was great, it did what I wanted with the middle one. I wanted to align all red containers and I did it with jQuery.
You need to also set display: inline-block; for the common wrapper (and give text-align: center to its parent)
body { text-align: center; }
.timeEvents {
display: inline-block;
margin: 0 auto;
}
JSFiddle
Result:
That's pretty easy to implement using Flexbox.
Just assign display: flex; to .ev2 and flex-grow: 1; to the the .myDiv class.
You can see it in the following code:
.timeEvents {
width: 100%;
overflow: hidden;
text-align: center;
}
.timeline {
border: 1px solid;
}
.events1, .events2 {
border: 1px solid;
}
.ev1, .ev3 {
border: 1px solid red;
}
.ev2 {
margin: 0 auto;
border: 1px solid red;
display: flex;
}
.mDiv {
display: inline-block;
padding-left: 12px;
padding-right: 12px;
border: 1px solid blue;
flex-grow: 1;
}
<div class="timeEvents">
<div class="events1">
<div class="ev1">Data Field 1</div>
</div>
<div class="timeline">
<div class="ev2">
<div class="mDiv">5</div>
<div class="mDiv">10</div>
<div class="mDiv">15</div>
<div class="mDiv">20</div>
<div class="mDiv">25</div>
</div>
</div>
<div class="events2">
<div class="ev3">Data Field 2</div>
</div>
</div>
Check out CSS-Trick's Complete guide to Flexbox for more information.
Use display:table to timeEvents and remove width:100% will make as per your expected.
.timeEvents {
display: table;
overflow: hidden;
text-align: center;
}
Fiddle

Aligning DIVs vertically

How do I align the red box with the gray box vertically?
http://jsfiddle.net/sLZzK/1/
I need several box combinations like that on my page, which is why I cannot simply push the red box up manually. A negative margin won't work either, since I do not know in advance how much content will be in the gray box. And the red box must overlap other page content, hence the absolute positioning. (http://jsfiddle.net/xMm82/)
CSS:
body {
padding: 0;
margin: 10px;
}
.left_div {
margin-bottom: 10px;
width: 300px;
height: 70px;
border: 1px solid gray;
}
.right_div {
position: absolute;
border: 1px solid red;
left: 311px;
width: 200px;
height: 200px;
}
HTML:
<div class="left_div">gray box
<div class="right_div">red box</div>
</div>
Why are you using absolute positioning for such structure? In the case the better solution is to use float: left for each div. If you want to have two divs aligned vertically use display: table-cell rule. Here it is:
FIDDLE
UPDATE: Try to use this:
FIDDLE
what I've understood is you want gray box on top of Red box:
first of all wrap them in a parent div.
set the width of wrapper to desirable width.
set width to 100%(both red and gray) and you are done !! (fiddle)
If you want to arrange them horizontally:
left_div will be wrapper
it will contain 2 child div's
left one will have content and right one will be red box.(fiddle)
I would do it this way:
HTML:
<div class="container">
<div class="left_div">gray box</div>
<div class="right_div yellow">red box</div>
<div class="clr"></div>
</div>
CSS:
.container:not(:last-child){margin-bottom: 10px;}
.left_div,.right_div{float:left;}
.clr{clear:both;}
Fiddle here.
use float to arrange vertically and clear:both to prevent any errors
here's the corrected one
.left{
float:left;
width: 300px;
}
.right{
float:left;
width: 200px;
}
.left_div {
width: 300px;
height: 70px;
border: 1px solid gray;
}
.right_div {
border: 1px solid red;
width: 200px;
height: 200px;
}
<div class="left">
<div class="left_div">
</div>
</div>
<div class="right">
<div class="right_div">
</div>
</div>
<div style="clear:both"></div>
http://jsfiddle.net/sLZzK/8/
There you go: http://jsfiddle.net/sLZzK/14/
HTML:
<div class="wrapper">
<div class="left_div">gray box</div>
<div class="right_div">red box</div>
</div>
CSS:
.wrapper {
border: 1px solid #369;
padding: 10px;
}
.wrapper > div {
display: inline-block;
vertical-align: middle;
}
You might also want to read about flexbox which will give you a similar and more consistent result, however it's not fully supported on various browsers yet.

Weird three divs side by side

I'm a tables guy, but I'll need to drag and drop some divs, so I tried doing it tabeless (the right way).
This is what I want to do:
The space between all elements should be 24px. My main problem is having the divs (1,2,3) occupying 100% of available space. The width: 100% its sending them beyond the main container.
This is my code so far:
html
<div id="mainContainer">
<div id="topContainer">Just the top one
</div>
<div id="table">
<div id="Line1Container">
<div id="container1" class="container">1
</div>
<div id="container2" class="container">2
</div>
<div id="container3" class="container">3
</div>
</div>
<div id="Line2Container">
<div id="container4" class="container">4
</div>
<div id="container5" class="container">5
</div>
<div id="container6" class="container">6
</div>
</div>
</div>
</div>
And my css
#mainContainer {
border: 1px solid lightgray;
position:fixed;
top: 80px;
bottom:20px;
left:80px;
right:80px;
overflow-y: scroll;
overflow-x: hidden;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
}
#topContainer {
border: 1px solid lightgray;
border-radius: 10px;
margin-left: 24px;
margin-right: 24px;
margin-top: 24px;
}
#table {
display: table;
margin: 24px;
width: 95%;
}
#Line1Container, #Line2Container {
display: table-row;
}
.container {
border: 1px solid lightgray;
display: table-cell;
width: 33%;
border-radius: 10px;
}
As you see I tried the table-cell approach, but before I have tried the float: left approach.
Thanks
Fiddle
You can't properly use px values with % values together with dynamic sizes.
You should use x% instead of 24px.
And you can use float: left on the "cells"
How about using a table for separating the divs? that way with the td padding there will always be 24px between them
check out this fiddle:
http://jsfiddle.net/5zfEq/
added:
#Line1Container {
padding:12px;
}
#inner-table {
width: 100%;
}
#inner-table td {
padding: 12px;
}
based on #Edifice fiddle .... thanks ;)

Two Divs on the same row and center align both of them

I have two divs like this
<div style="border:1px solid #000; float:left">Div 1</div>
<div style="border:1px solid red; float:left">Div 2</div>
I want them to display on the same row, so I used float:left.
I want both of them to be at center of the page as well, so I tried to wrap them with another div like this
<div style="width:100%; margin:0px auto;">
<div style="border:1px solid #000; float:left">Div 1</div>
<div style="border:1px solid red; float:left">Div 2</div>
</div>
But it doesn't work. If I change the code to this
<div style="width:100%; margin-left:50%; margin-right:50%">
<div style="border:1px solid #000; float:left">Div 1</div>
<div style="border:1px solid red; float:left">Div 2</div>
</div>
then it's going to the center, but the horizontal scrollbar is there and it seems like it's not really centered as well.
Can you please kindly suggest to me how can I achieve this? Thanks.
Edit: I want the inner div (Div 1 and Div 2) to be center align as well.
You could do this
<div style="text-align:center;">
<div style="border:1px solid #000; display:inline-block;">Div 1</div>
<div style="border:1px solid red; display:inline-block;">Div 2</div>
</div>
http://jsfiddle.net/jasongennaro/MZrym/
wrap it in a div with text-align:center;
give the innder divs a display:inline-block; instead of a float
Best also to put that css in a stylesheet.
Could this do for you? Check my JSFiddle
And the code:
HTML
<div class="container">
<div class="div1">Div 1</div>
<div class="div2">Div 2</div>
</div>
CSS
div.container {
background-color: #FF0000;
margin: auto;
width: 304px;
}
div.div1 {
border: 1px solid #000;
float: left;
width: 150px;
}
div.div2 {
border: 1px solid red;
float: left;
width: 150px;
}
both floated divs need to have a width!
set 50% of width to both and it works.
BTW, the outer div, with its margin: 0 auto will only center itself not the ones inside.
Align to the center, using display: inline-block and text-align: center.
.outerdiv
{
height:100px;
width:500px;
background: red;
margin: 0 auto;
text-align: center;
}
.innerdiv
{
height:40px;
width: 100px;
margin: 2px;
box-sizing: border-box;
background: green;
display: inline-block;
}
<div class="outerdiv">
<div class="innerdiv"></div>
<div class="innerdiv"></div>
</div>
Align to the center using display: flex and justify-content: center
.outerdiv
{
height:100px;
width:500px;
background: red;
display: flex;
flex-direction: row;
justify-content: center;
}
.innerdiv
{
height:40px;
width: 100px;
margin: 2px;
box-sizing: border-box;
background: green;
}
<div class="outerdiv">
<div class="innerdiv"></div>
<div class="innerdiv"></div>
</div>
Align to the center vertically and horizontally using display: flex, justify-content: center and align-items:center.
.outerdiv
{
height:100px;
width:500px;
background: red;
display: flex;
flex-direction: row;
justify-content: center;
align-items:center;
}
.innerdiv
{
height:40px;
width: 100px;
margin: 2px;
box-sizing: border-box;
background: green;
}
<div class="outerdiv">
<div class="innerdiv"></div>
<div class="innerdiv"></div>
</div>
I would vote against display: inline-block since its not supported across browsers, IE < 8 specifically.
.wrapper {
width:500px; /* Adjust to a total width of both .left and .right */
margin: 0 auto;
}
.left {
float: left;
width: 49%; /* Not 50% because of 1px border. */
border: 1px solid #000;
}
.right {
float: right;
width: 49%; /* Not 50% because of 1px border. */
border: 1px solid #F00;
}
<div class="wrapper">
<div class="left">Div 1</div>
<div class="right">Div 2</div>
</div>
EDIT: If no spacing between the cells is desired just change both .left and .right to use float: left;
Better way till now:
If you give display:inline-block; to inner divs then child elements of inner divs will also get this property and disturb alignment of inner divs.
Better way is to use two different classes for inner divs with width, margin and float.
Best way till now:
Use flexbox.
http://css-tricks.com/snippets/css/a-guide-to-flexbox/
Please take a look on flex it will help you make things right,
on the main div set css display :flex
the div's that inside set css: flex:1 1 auto;
attached jsfiddle link as example enjoy :)
https://jsfiddle.net/hodca/v1uLsxbg/

Resources