Given margin collapsing, how to evenly space child elements within a parent element? - margin

So margin collapsing makes a child's margin collapse to the parent's margin if there is no border. How, then, can I accomplish this?
-------------
| | <-- "Top space"
| ------- |
| | | |
| | | |
| ------- |
| | <-- "Middle space"
| ------- |
| | | |
| | | |
| ------- |
| | <-- "Middle space"
| ------- |
| | | |
| | | |
| ------- |
| | <-- "Bottom space"
-------------
^ ^
left right
space space
I want all these "spaces" to be equal.
I want the space between each child to be 10px, and the space between children and the parent to be 10px. If I have a margin of 10px for each child, and no padding for the parent, the "top space" and "bottom space" would be 0px. If I have any padding in the parent, "middle space" would be different from top/bottom space.
How can I do this? I don't particularly want to float or clear any elements, or even add new elements to accomplish this. I just think I'm missing some clever math here.

This is the easiest way:
Just add a transparent border to the containing element.
Live Demo
HTML:
<div id="container">
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
</div>
CSS:
#container {
background: #ccc;
width: 200px;
border: 1px solid transparent /* "magic border" fixes it */
}
.square {
margin: 10px;
height: 50px;
background: #f0f
}
Alternatively, you can use position: absolute:
Live Demo

You can give the child elements a margin of 10px, then the parent padding of 10px. Ill code it up
EDIT:
How about using borders? - No
parent - display:table;
HTML:
<div>
<p>Alex</p>
<p>James</p>
<p>thomas</p>
</div>
CSS:
div{display:table;}
p{margin:10px;}
http://jsfiddle.net/nqLYT/

I would try
.children{
margin: 5px;
}
.parent{
padding: 5px;
}
This should be 10px for all directions. Right?

Related

CSS to stack some elements to the bottom

I have a page with this HTML
<div>div 1</div>
<div>div 2</div>
<div>div 3</div>
<div>div 4</div>
... variable amount of divs
I want to create this layout, where the page is 100% tall and wide. The first two divs should be at the top, all following divs stacked at the bottom.
The divs are generated automatically - I can not treat the first two differently (only in the stylesheet).
How can I achieve this? I need only to support the latest version of Chrome and Chromium.
--------------------------
| ---------- ---------- |
| | div 1 | | div 2 | | <-- aligned to top of page
| | | | | |
| ---------- ---------- |
| |
| | <-- variable space
| |
| ---------------- |
| | div 3 | |
| ---------------- | <-- aligned to bottom of page
| ---------------- |
| | div 4 | |
| ---------------- |
--------------------------
you could use :nth-child to target the first two divs and stack them in a row and leave the rest stacked at bottom..
iterate through the divs on the page. Jquery can do this pretty easily.
$('div').each(function(i, elem) {
//do something with the current 'elem'.
//How do I know if its the first and 2nd div?
if(i==1||i==2)
{
//This must be the first 2 divs
}
});
EDIT:I will add that this is a bad way to do this, but is easy to follow IMO. Say you have 1000 divs, you iterate through all of them just to process a few, etc.
EDIT AGAIN: So when I say //do something, I would do $(item).addClass('customCSS'). This will allow you to target these divs, regardless of how they are generated. Hope this helps
Try with this code:
div:first-child{
width: 50%;
float: left;
}
div:nth-child(2){
width: 50%;
float: left;
}
div:nth-child(3){
width: 100%;
clear:both;
}
div:last-child{
width: 100%;
clear:both;
}
And follow this pattern with all the divs you have
It seems impossible to do the way I would have liked. I will treat the top and bottom divs differently (which I wanted to avoid) and wrap both of those groups in their own container like this:
HTML
<div id="top">
<div><h1>1</h1></div>
<div><h1>2</h1></div>
</div>
<div id="bottom">
<div><h1>3</h1></div>
<div><h1>4</h1></div>
<div><h1>5</h1></div>
<div><h1>6</h1></div>
</div>
CSS
#top div {
width: 50%;
float: left;
}
#bottom {
position: absolute;
bottom: 0;
}

Div that fills width of screen inside Centered Div

Is this possible? I have Div2 specifically positioned inside Div1. The only thing now is I would like Div2 to span the width of the entire screen, instead of just spanning the width of Div1.
|----------------------------------------------------------|
| Browser |
| |
| |
| |
| |
| -------------------------------- |
| | Div1 (relative) | |
| | | |
| | | |
|-----------|------------------------------|---------------|
| | Div2 | |
| |(currently absolute & in Div1)| |
|-----------|------------------------------|---------------|
| | | |
| | | |
| | | |
| | | |
| -------------------------------- |
| |
| |
| |
|----------------------------------------------------------|
This is the CSS I have now:
.page{
height: 300px;
width: 400px;}
.Div1{
float:left;
left: 50%;
height:200px;
width:100px;
position:relative;
background-color: red;
}
.Div2{
position:absolute;
top:21px;
width:100%;
height:24px;
background-color: yellow;
}​
Here is JSFiddle for my current problem: http://jsfiddle.net/vBqgT/21/
Thanks.
You don't really need CSS3 do accomplish this. Since div2 is inside div1, it's width is constrained by div1. Therefore, to make div2 wider than div1:
.Div2{
width:150%;
}
You can also do this:
.Div2{
left: -25%;
}
to adjust where the left edge of div2 starts.
See http://jsfiddle.net/jsxvK/.
But if the main goal is for div2 to take on the properties of the body (page in your case), consider putting the markup for div2 inside page, but not inside div. Then adjust the top position of div2 to move it up or down in the document.
Sure you can do that, but the position of div2 is given relative to div1 (thus left:0 whould place it left aligned to div1) if you make div2 a child of div1. If you don't want to place it relative to div1 you can either make div2 a sibling to div1 or you can remove position: relative; from div1. Another alternative is to use fixed position on div2. All of these have side effects that may not be desirable...
Sometimes it is necessary to use javascript to get exactly what you want. Say for example that you want to align to div1 on one axis and to the body on the other. Then it may be necessary to use scripting.
Try this CSS:
.page{
height: 300px;
width: 100%;
border: 0px solid red;
}
.Div1{
margin: 0 auto;
height:200px;
width:100px;
background-color: red;
}
.Div2{
position:absolute;
top:21px;
width:100%;
height:24px;
background-color: yellow;
left:0;
}
Here is the demo: http://jsfiddle.net/ongisnade/SqG3c/

Stick a div to the right border of a div defined later

I have a following divs defined in source:
<div id="container">
<div id="right">Right</div>
<div id="left">Left</div>
</div>​
I cannot really reorder them, so I have to play with CSS so that they appear on the page as follows:
+---------------------+
| container |
| +-------+-------+ |
| | left | right | |
| +-------+-------+ |
+---------------------+
The challenge is that contents of #left div may be of arbitrary width and whatever the width is, I need the #right div to stick to the right border of #left div. Any ideas how to achieve that?
Any help appreciated!
Also, there is a small constraint: I need both of #left and #right align to the left of border of the #container div.
You can use float: right to move div#right and div#left to the correct sides. That should also align the right side of div#left to div#right.
#right, #left {
float: right;
}
JS Fiddle Example
Try this:
#container{
margin:10px 10px;
}
#left,#right {
float:left;
padding:0px;
height:100px;
background-color:#000000;
}
#right{
background-color:#f1f1f1;
}
Better Answer
Allow #right to set edge of #left, while still giving flexibility to #left by using a trick with overflow: hidden (see fiddle):
#right {
float: right;
}
#left {
overflow: hidden; /* this causes non-floated `left` to behave different */
}
Original Answer
I would expand upon Rich and JSW189's answer as, I do not like the possibilities of just floating them right. If you can, do that, but then float the container left (see the fiddle), which requires that no width be set on container, else there is a problem again (see fiddle):
#container {
float: left;
}
#right, #left {
float: right;
}
Of course, there are applications where this will not be possible (like when you want width on the container.
In your css, try floating them both to the right, like this:
#left,#right { float:right; }
Complete CSS
#container {
background:#ddd;
width:200px;
height:100px;
}
#left, #right {
float:right;
}
#left {
width:30%;
background:green;
}
#right {
width:70%;
background:blue;
}
Here's the example in jsFiddle
Aligning them both to the left
If your not using fixed percentage widths (or no widths at all), this will result in both div#left and div#right being floated to the right like so:
+---------------------------------+
| container |
| +-------+-------+ |
| | left | right | |
| +-------+-------+ |
+---------------------------------+
If you would like to align them to the left, wrap them in a container div:
<div id="container-inner"> ... </div>
And apply this css:
#container-inner { float:left; }
Resulting in:
+---------------------------------+
| container |
| +-------+-------+ |
| | left | right | |
| +-------+-------+ |
+---------------------------------+
Hope that helps

How to center multiple inline-block elements with CSS?

I want to horizontally center two (or possibly more) inline-block elements inside a container block element. It should look like this:
--------------------------
| _____ _____ |
| | | | | |
| | foo | | bar | |
| |_____| |_____| |
|_________________________|
However, with my broken code, it is currently looking like this:
--------------------------
| _____ ____ |
|| | | | |
|| foo | | bar | |
||_____| |_____| |
|_________________________|
HTML
<div>
<a>foo</a>
<a>bar</a>
</div>
CSS
div a {
display: inline-block;
padding: 1em;
margin: 1em;
border: 1px solid black;
}
The reason why the two anchors have to be inline-block and not just plain inline is because I don't want the anchor's padding and margin to overlap.
Simply set text-align: center; on the div container.
Set text-align: center; on the parent element.
have you tried the following?
div{
text-align:center;
}
Either you can try these one
div{
text-align:center;
}
or set margin auto as shown below
div a{
margin:auto;
margin-left:1em;
margin-right:1em;
margin-top:1em;
margin-bottom:1em;
display:inline-block;
}
A good example is shown here
Just to be clear ...
<div style="display: inline-block; text-align: center">
....
</div>
doesn't work with elements of different widths, but
<div style="text-align: center;">
<div style="display: inline-block;">
....
</div>
</div>
does
I used text-align: "center" in the parent container, and that centered the ULs on the page, but it also centered the text in the ULs (not desired). So I added a text-align: "left" to the <ul> so that the text was next to the list-style.
You can also do
.div {
display: inline-block center;
text-align: center;
}
to make the inline block center horizontally!

CSS Tables & min-width container?

<div id="wrapper">
<div id="header">...</div>
<div id="main">
<div id="content">...</div>
<div id="sidebar">...</div>
</div>
</div>
#wrapper { min-width: 900px; }
#main { display: table-row; }
#content { display: table-cell; }
#sidebar { display: table-cell; width: 250px; }
The problem is that the sidebar isn't always at the right-most part of the page (depending on the width of #content). As #content's width is variable (depending on the width of the window), how to I make it so that the sidebar is always at the right-most part of its parent?
Example:
Here's what I have now:
<--- variable window width ---->
---------------------------------
| (header) |
---------------------------------
[content] | [sidebar] |
| |
| |
| |
| |
| |
| |
And here's what I want:
<--- variable window width ---->
---------------------------------
| (header) |
---------------------------------
[content] | [sidebar] |
| |
| |
| |
| |
| |
| |
Please let me know if you need anymore information to help me with this issue. Thanks!
PS - I know I can accomplish this easily with floats. I'm looking for a solution that uses CSS tables.
SOLUTION:
#wrapper { min-width: 900px; }
#main { display: table; table-layout: fixed; }
#content { display: table-cell; }
#sidebar { display: table-cell; width: 250px; }
No need to declare a table-row element, thanks to anonymous table elements.
You would need to set the style display: table (or inline-table) on a wrapper div around #main in order for the other table display types to make sense; it's undefined what happens if you put rows inside something that's not a table.
Then on that wrapper you'd have to also set table-layout: fixed; to make the browser actually respect the widths you specify (in the first table-row, if you don't have explicit columns). Otherwise you get the auto table layout algorithm second-guessing you. Finally add width: 100%; to avoid shrink-to-fit.
I'm looking for a solution that uses CSS tables.
Any reason for that, or is this just an exercise? CSS tables aren't a good choice today due to poor browser support and in the end they don't really get you anything over just using a table. CSS positioning would seem to be the better way to go for simple layouts like this.
Set the parent to position:relative. Then set the sidebar to position:absolute and snug it to the right.
So....
#main{
position:relative;
}
#sidebar{
position:absolute;
right:0px;
}
That should keep your sidebar snug to the right of main, regardless of how wide content is.

Resources