Make two CSS elements fill their container, side-by-side, with margin - html

I want two elements to take up an exact percent of the parent's width, but I also need margins on them holding them apart. I have the following markup:
<div class='wrap'>
<div class='element'>HELLO</div><div class='element'>WORLD</div>
</div>​
.wrap {
background:red;
white-space:nowrap;
width:300px;
}
.element {
background:#009; color:#cef; text-align:center;
display:inline-block;
width:50%;
margin:4px;
}
As you can see in http://jsfiddle.net/NTE2Q/ the result is that the children overflow the wrapper:
How can I get them to fit within the space? Sadly, there is no box-sizing:margin-box for this case.

Technique #1 - Modern CSS3 calc()
Using CSS3's calc() length, you can do this by setting the width of the .element to:
.element {
width: 49%; /* poor approximation for old browsers */
width: calc(50% - 8px); /* standards-based answer for IE9+, FF16+ */
width: -moz-calc(50% - 8px); /* support for FF4 - FF15 */
width: -webkit-calc(50% - 8px); /* support for Chrome19+ and Safari6+ */
}
Demo: http://jsfiddle.net/NTE2Q/1/
See http://caniuse.com/calc for details on which browsers and versions support this.
Technique #2 - Old School Wrapping
Calculations can be made by piling up multiple elements. For this case, we wrap each 'element' in a wrapper that is 50% wide but with a 4px padding:
<div class='wrap'>
<div class='ele1'>
<div class='element'>HELLO</div>
</div><div class="ele1">
<div class='element'>WORLD</div>
</div>
</div>​
.ele1 {
display:inline-block;
width:50%;
padding:4px;
box-sizing:border-box; /* Make sure that 50% includes the padding */
-moz-box-sizing:border-box; /* For Firefox */
-webkit-box-sizing:border-box; /* For old mobile Safari */
}
.element {
background:#009; color:#cef; text-align:center;
display:block;
}
Demo: http://jsfiddle.net/NTE2Q/2/
​
Technique #3 - Using (CSS) Tables
The same result can be made by treating the wrapper as a 'table' and each element as a cell within the same row. With this, whitespace between elements is not important:
<div class='wrap'>
<div class='element'>HELLO</div>
<div class='element'>WORLD</div>
</div>​
.wrap {
background:red;
width:300px;
display:table;
border-spacing:4px
}
.element {
background:#009; color:#cef; text-align:center;
width:50%;
display:table-cell;
}
​
Demo: http://jsfiddle.net/NTE2Q/4/
Note that this last technique collapses the 4px spacing between the two elements, while the first two techniques cause 8px to appear between the two items and 4px at the edges.

What you are describing is basically a border. So why not to use CSS border property with background-clip? Just don't forget appropriate vendor prefixes.
http://jsfiddle.net/NTE2Q/8/
.wrap {
background-color: red;
white-space:nowrap;
width:300px;
}
.element {
background:#009; color:#cef; text-align:center;
display:inline-block;
width:50%;
border:4px solid rgba(0,0,0,0);
box-sizing: border-box;
background-clip: padding-box;
}

None of the above techniques worked consistently enough cross browser for me. I found a slightly different technique using display:table-cell allowed me to place 2 or more elements next to each other. Here is an example of it in action.
The CSS:
display:table-cell;
background:#009; color:#cef; text-align:center;
width:22%; /*Set percentage based on # of elements*/
border:4px solid rgb(255,0,0);/*no longer need background to be red, just make border red*/
You no longer even need the wrapper since the div is now treated as a <td>.

Though I strongly suggest using Phorgz's calc() technique whenever possible, I also want to propose an old-school way of doing this that uses only one wrapper and position: relative to achieve the effect.
.two-blocks-by-side() LESS Mixin:
.two-blocks-by-side(#padding) {
padding: #padding (#padding + #padding / 2);
font-size: 0;
& > div {
position: relative;
display: inline-block;
font-size: initial;
width: 50%;
&:first-child { left: -1 * #padding / 2 };
&:last-child { right: -1 * #padding / 2 };
}
}
JS Bin example

Related

Height of the division in CSS3

I am trying out forms in HTML.
Fiddle
For the div #status, the CSS rules are-
#status{
margin:auto;
width:50%;
border:2px solid red;
background:white;
height:40%;
}
But I cannot understand why the height of divison does not get altered by height rule in the CSS. More over If I try out-
#status{
margin:auto;
width:50%;
border:2px solid red;
background:white;
height:40px;
}
JSFiddle
This leaves the text on the bottom while div is placed at some random place.
Could some help with placing this division below E-mail ID field so that text appears inside it?
Also, which rule in my CSS is responsible for this positioning of div.
You're inserting the div under elements that are floating. You need to add clear: both to your #status CSS rules:
#status {
margin: auto;
width: 50%;
border: 2px solid red;
background: white;
height: 40%; /* or 40px, which will look slightly different. Your choice. */
clear: both;
}
Updated Fiddle

Equal width in percentages using table-cell

http://jsfiddle.net/hw98P/
While this is not a huge deal, it bothers me to not know why this behavior is happening. I have 3 divs set as table-cells. What I want is the left col at 20% and the middle and right cols to be at 40%, after padding has been added into that. I changed my px padding to percentages and have allotted for that difference in my calculations, but the middle and right cells are not the same width. The middle shows 482px and the right shows 508px.
My question is why is this happening? Is it possible to get the middle and right cols exactly the same width?
#content {
padding:15px 0;
display:table;
width:100%;
}
#content #col1 {
border-right:1px solid #E2E2E2;
padding-right:1%;
width:19%;
display:table-cell;
}
#content #col2 {
border-right:1px solid #E2E2E2;
padding-right:1%;
padding-left:1%;
width:38%;
display:table-cell;
}
#content #col3 {
width:39%;
padding-left:1%;
display:table-cell;
}
<div id="content">
<div id="col1">1</div>
<div id="col2">2</div>
<div id="col3">3</div>
</div>
EDIT:
I have also tried setting table-layout: fixed; on #col1 but this changes nothing.
It is all because of width calculation. So try to use box-sizing property. Update your CSS like below. More Information about box-sizing property
#content {
padding:15px 0;
display:table;
width:100%;
}
#content #col1 {
border-right:1px solid #E2E2E2;
padding-right:1%;
width:20%;
display:table-cell;
box-sizing:border-box;
}
#content #col2 {
border-right:1px solid #E2E2E2;
padding-right:1%;
padding-left:1%;
width:40%;
display:table-cell;
box-sizing:border-box;
}
#content #col3 {
width:40%;
padding-left:1%;
display:table-cell;
box-sizing:border-box;
}
FIDDLE DEMO
It is absolutely possible. You can use the calc() CSS3 function which should make your measurements to your standard.
Example:
.style{
width:calc(50% - 10px);
}
Example explained: So lets say the my screen width resolution is 1000px the value 50% holds is 500px. This value is then taken 10px away from. The final value will give you for 490px for the width.
More info at https://developer.mozilla.org/en-US/docs/Web/CSS/calc
If you have any questions or this did not help, please comment back or contact me.
Here I've used box-sizing: border-box; and using of pseudo element all innderdiv width are equal now. Check the DEMO.
#content {
padding:15px 0;
width: 100%;
display: table;
table-layout: fixed;
}
#content div{
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}
#content #col1 {
display:table-cell;
background:gold;
position:relative;
}
#content #col2:after, #content #col3:before{
position: absolute;
content: " ";
top:0;
left:0;
display:block;
width: inherit;
}
#content #col2 {
display:table-cell;
background:green;
position:relative;
}
#content #col3 {
display:table-cell;
background:yellow;
position:relative;
}
If you want to retain your code structure (by this I mean use table/table-cell), here's a better approach with the same concept: http://jsfiddle.net/darcher/hw98P/23/
BUT
To start, You have multiple options here to achieve what you need. position, table-cell, float, and flexbox. I've used all four in this fiddle demo. They have varying levels of support, so make sure you research the best option for you (you can check caniuse.com for this). I recommend float's as it's tried and true; however, flexbox is certainly picking up speed.
Onto your OP
The cause is probably the use of uneven paddings for each cell in conjunction with % width and right borders.
Disclaimer: Now, admittedly, I'm unsure of all the factors for the various browsers rendering of display:table.
I'm very inclined to believe it's the way you have structured the css and how the cells are inheriting padding, most specifically the order in which they're rendering.
I don't have an exact answer as to why, but I do have a solution. You can rework it using left borders and like paddings or clearing the left/right most paddings after declaring like paddings. You should attempt to be as consistent as possible when developing layout based code for factors ranging from scalability to error reduction and compatibility, it's just good practice. You can probably override the differing paddings structure by way of relatively positioning the cells, but I don't see a reason for the extra mark-up or time when there's a simple solution that promotes cleaner, better structured approaches.
1) Bear in mind there are limitations in support for calc(): http://caniuse.com/calc, you can use box-shadow:-1px 0 1px -1px #eee to avoid the 1px border-width and avoid using calc() altogether, but it too has its limitations: http://caniuse.com/box-shadow.
2) The border-box needs to be prefixed (even still) in order for this to react the same in Mozilla as it does in Chrome. While using this method, the browser calculates the padding and border-width into the element width for you. If you use the below you won't require calc() or offsetting your widths from your paddings. http://www.paulirish.com/2012/box-sizing-border-box-ftw/
How I'd do it: If I HAD to use display:table
*,*:before,*:after{/* 2 */
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box}
.content {
display:table;
padding:15px 0;
width:100% }
div[class^=col] {
display:table-cell;
padding:0 15px }
.col1 { width:20%; }
.col2, .col3{
box-shadow:-1px 0 1px -1px grey; /* 1 */
width:40% }

Chrome and Opera creating small padding when using display:table

I've noticed that Chrome (34.0.1847.131 m) and Opera (21.0.1432.67) are creating an small gap between two divs when using the property display:table;. (and not when using display:block, for example)
Here's a fiddle reproducing it. (adjust the width of the panel, it doesn't take place with every width)
To reproduce it:
HTML
<div class="left"></div>
<div class="right"></div>
CSS
.left {
left: 0px;
}
.right {
right:0px;
}
.left, .right {
width: 50%;
position: absolute;
height: 350px;
background:#000;
display:table;
border-spacing:0;
border:0;
margin:0;
padding:0;
}
How can I get rid of this gap? Is this some kind of bug?
Changing table to table-cell seemed to do the trick:
http://jsfiddle.net/3z24S/7/
add 1 px to the placement of the right div:
.right {
right:1px;
}
http://jsfiddle.net/3z24S/12/
I have two potential solutions:
Option 1:
Use css calc(); to set the width of the two divs, like so:
Working Example 1
.left, .right {
width: calc(50% + 0.1px); /* Important bit */
position: absolute;
height: 350px;
background:#000;
display:table;
border-spacing:0;
border:0;
margin:0;
padding:0;
}
Option 2:
Use JavaScript to set the width of the two divs, like so:
Working Example 2
wid = function () {
$('.left, .right').width(Math.ceil($(window).width() / 2)); //Math.ceil() will round the value up
};
$(document).ready(wid);
$(window).resize(wid);
If you can get away with using calc() its probably the better option, using JavaScript seems expensive for something like this.
If it is a matter of vertical-align and known height, you can do without display:table/table-cell; DEMO or you could do without absolute position.
You may use inline-block, vertical-align and pseudo élément.
HTML :
<div class="left">
<div class='content'>
<p>content</p>
</div>
</div>
<div class="right">
<div class='content'>
<p>content</p>
<p>content</p>
</div>
</div>
the div.content will be inline-block or is display:table-cell in your problem.
CSS
.left {
left: 0px;
}
.right {
right:0px;
}
.left, .right {
width: 50%;
position: absolute;
height: 350px;
background:#000;
color:white;
border-spacing:0;
border:0;
margin:0;
padding:0;
}
.left:before,
.right:before ,
.content {
display:inline-block;
vertical-align:middle;
max-width:95%;
}
.left:before,
.right:before {
content:'';
height:100%;
width:0;
}
Even answering here to your question , i still do not understand why position:absolute; and still not sure if elements are suppose to have an known height. It looks more like you are not using the proper or best method to your needs.
The pixel bug is, in my opinion, already answered in comments and obviously a different way for chrome to handle this display value.

linbreak text inside div between two fixed width divs

My pen: http://codepen.io/helloworld/pen/vzuLC
How can I tell the orange div to line-break its text/content so that the yellow div does not linebreak?
div green and div yellow must have a fixed width. The div between them should have width:auto that means the div grows with the content and breaks with the content.
I do only IE9+ and latest Chrome/FF
Set its width with CSS calc().
Demo
#address{
width: calc(100% - 100px);
}
Browser support for calc()
#Itay 's answer is great, but I would recommend you use absolute position for compatibility reason. For front-end developers, compatibility is everything.
.wrapper{
position: relative;
border-top:white solid 1px;
border-bottom:#ddd solid 1px;
}
#alarmNumber{
position: absolute;
left:0;
width:50px;
background:lightgreen;
}
#address{
float:left;
margin: 0 50px;
}
#expander{
position:absolute;
right:0;
background:yellow;
text-align:center;
width:50px;
height:100%;
}
DEMO
You could do this with position:absolute and box-sizing
#alarmNumber{
float:left;
width:50px;
background:lightgreen;
position:relative; /* add this */
z-index:1; /* add this so that it appears on top of address */
}
#address{
width:100%;
padding: 0 50px; /* add this */
position:absolute; /* add this */
-moz-box-sizing: border-box;
box-sizing: border-box; /* add this */
}
UPDATED CODEPEN

How equal separate 3 div inside 1 div

I'm currently learning HTML. I'm trying to add 3 images inside a div, the images need to have the same amount of space between them. How to do this?
Example: https://docs.google.com/drawings/d/1WZdL0WVz-VndX2qP0Ig0S8fZnCGW2k37RHvWXLdgWz0/edit?usp=sharing
The code I currently have:
<style type="text/css">
.maindiv{
position: relative;
width:90%;
height:50%;
border-style:solid;
border-color:Red;
border-width:2px;
}
.imgbott{
height:auto;
width:auto;
max-width:200px;
max-height:200px;
float:left;
text-align: center;
}
</style>
<body>
<div class="maindiv">
<div class="imgbott">
<img src="https://sites.google.com/a/itcld.com.br/portal-de-treinadores/_/rsrc/1377018552616/imagens/images.jpg" alt="">
<a>TESTE</a>
</div>
<div class="imgbott">
<img src="https://sites.google.com/a/itcld.com.br/portal-de-treinadores/_/rsrc/1377018552616/imagens/images.jpg" alt="">
<a>TESTE</a>
</div>
<div class="imgbott">
<img src="https://sites.google.com/a/itcld.com.br/portal-de-treinadores/_/rsrc/1377018552616/imagens/images.jpg" alt="">
<a>TESTE</a>
</div>
</div>
</body>
Code runing: https://script.google.com/a/macros/itcld.com.br/s/AKfycbyjeAIFhKnAXzvXd8lS3S-ND4H0n63i-FBxr-i9Z1omeFmBYtA/exec
Thank you.
Change your css to:
.imgbott{
margin: 0px 10px;
height:auto;
width:auto;
max-width:200px;
max-height:200px;
float:left;
text-align: center;
}
The margin: 0px 10px means 0px margin to the top and bottom, and 10px margin to the left and right. Maybe one would expect 20px margin between the divs then, but there is a effect called "margin collapsing" which prevents that.
is this what you looking for
http://jsfiddle.net/Gfnjz/
.box {
display:table;
table-layout:fixed;
min-width:900px; /* some minimum width is a good idea. */
border-spacing:20px 0; /* note that spacing is also applied to right and left ends */
background-color:#666;
margin:0 auto;
}
.box div {
display:table-cell;
width:33%;
vertical-align:middle;
border:1px solid #bbb;
background-color:#eee;
padding:30px;
}
You can do something like this:
.divName{
width:300px;
display: inline-block;
margin: 0 20px 0 0;
float: left;
}
Then for the last box, apply a .lastBox class as well to force no margin, that way they are perfectly centered, assuming your parent container is centered that is:
.lastBox{
margin-right: 0;
}
The HTML:
<div class="divName">
<p>stuff</p>
</div>
<div class="divName">
<p>stuff</p>
</div>
<div class="divName lastBox">
<p>stuff</p>
</div>
if you only want the same space between the "imgbott" divs, set their margin instead of width attribute.
Your class will looks like
.imgbott{
margin: 0px 10px;
float: left;
text-align: center;
}
.imgbott a
{
display:block;
}
Then doesn't matter what is the width of the images inside, the space will always be 20px between the images.
In additional you can remove the margin-left of the first image using the first-child selector
.imgbott:first-child {
margin-left:0px;
}
You can achieve this result by using inline-blocks and text-align: justify, with adding some fake content before and after the divs to be aligned via pseudo-elements:
.maindiv{
width:90%;
border: 2px solid red;
text-align: justify; /* turns on justification 'magic' */
line-height: 0; /* removes extra space below divs because of extra line */
}
.maindiv:before {
font-size: .1px;
content: 'i'; /* adds nearly invisible fake content in the beginning of the line */
}
.maindiv:after {
font-size: .1px;
content: 'i i'; /* adds nearly invisible fake content in the of the line */
word-spacing: 99in; /* huge word-spacing assures that the 2nd 'i' wraps to the next line making 'justify' work */
background: #ccc;
}
.imgbott{
display: inline-block;
line-height: 1; /* restore the normal line height inside divs */
}
JSFiddle
Optionally, you can prohibit the wrapping of the divs if the container is narrower than the sum of their widths by adding white-space: nowrap to the container and normal to its :after: see edited JSFiddle
This solution may look a bit tricky, but it works for arbitrary number of blocks of arbitrary (possibly different) widths.