I have a container containing multiple elements with a min-width and some padding to the right and left, the problem is in need them centered and in a column with each one in a separate row, the content of each one of them differs, causing the elements to have different width, like this
+--------- container ---------+
|child1 is too long|
|child2|
|child3 is long|
|child4|
+-----------------------------+
how can I make them all have the width of the largest element while maintaining a max-width in the same time, i.e. if the content gets too long, it breaks down to the next line while maintaining the width.
Attached below a screenshot, the above is the current situation, the one below is the desired result
You can wrap the items with a display:inline-block element,
and wrap that element in a text-align:center element so it would be centered:
.centered{ text-align:center; }
.wrapper{
display: inline-block;
font: 24px Arial;
text-align: left;
}
.wrapper > div{
border: 2px dashed pink;
margin-bottom: 4px;
}
<div class='centered'>
<div class='wrapper'>
<div contenteditable>try typing here</div>
<div contenteditable>aaaaa</div>
<div contenteditable>aaaaa aaaaa</div>
<div contenteditable>aa</div>
<div contenteditable>aaaaaaaaa</div>
</div>
</div>
The inner children are block level elements (<div>) which means they will take the whole width of their parent element, where the parent is an inline-block. This will result the parent is as wide as the widest child.
I have a div with floated children.
I know I can stretch the height in the following 2 ways:
.container {
border: 2px solid #ccc;
margin-bottom: 250px;
}
.container-2::after {
content: '';
display: block;
height: 0;
font-size: 0;
clear: both;
}
.container-3 {
overflow: hidden;
}
.item {
float: left;
width: 200px;
height: 50px;
background: red;
margin: 10px;
}
<div class="container container-1">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="container container-2">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="container container-3">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
But I think they have the different principles: the clear:both ::after element stays away from the float brothers, and force the parent div to stretch the height; the overflow:hidden style makes the div have the BFC, and according to standard, BFC will stretch its height to include its float children.
The advantages and disadvantages are not important,but the how they works.
Am I right, they are different but have the same result?
Do clear:both and overflow:hidden work the same way to make a container wrap floated children?
No. They perform different functions.
clear:both
The clear property controls whether an element can be next to or below floated elements that come before it. It controls whether an element can clear the floated elements.
clear:both, when applied to a non-floating, block-level element:
Requires that the top border edge of the box be below the bottom outer edge of any right-floating and left-floating boxes that resulted from elements earlier in the source document.
source: https://www.w3.org/TR/CSS2/visuren.html#propdef-clear
So the clear property more likely applies to a sibling of floated elements. It has nothing to do with stretching the height of div which has float children (as stated in your question).
overflow:hidden (or overflow:auto)
The overflow property, when used with a value other than visible, creates a new block formatting context. This causes the element containing floats to expand in order to contain its floated children.
In summary, one property clears an element past floated elements. The other stretches the container to wrap floated elements. The output may appear the same for both. But each property is fundamentally different.
Further reading:
3. Scrollable Overflow: the overflow-x, overflow-y, and overflow properties
What is a clearfix?
What methods of ‘clearfix’ can I use?
I have 3 divs like so:
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
with the following CSS:
div {
border: 1px solid black;
display: inline-block;
height: 100px;
width: 100px;
}
When the divs are empty, this code works fine. All divs align along the same horizontal plane. But! When I put any content in 1 or 2 divs, the divs with the content move down about 90% of the height:
<div class="div1">X</div>
<div class="div2">Y</div>
<div class="div3"></div>
Divs 1 and 2 are now spaced down in comparison to the normally aligned div 3. The plot really thickens when I add content to the final div:
<div class="div1">X</div>
<div class="div2">Y</div>
<div class="div3">Z</div>
Now all three divs are properly aligned at page top again. Not sure what's happening here or the proper work around?
This is happening because the default vertical-align for a inline block element is baseline*.
This image from CSS Tricks helps to demonstrate the baseline of text:
As you can see, the baseline isn't how far down the text goes, it is the line that the text is aligned on. With vertical-align:baseline, the div with no content aligns with the baseline created by the <div>'s with content.
This image may help you visualize what's happening(or, you can play with the jsfiddle):
To make all your <div>'s align, no matter the content, set vertical-align:top;:
div {
border: 1px solid black;
display: inline-block;
height: 100px;
width: 100px;
vertical-align:top;
}
This article also helps explain vertical-align some more
* W3 Specs
How do I set the width of a div if I want it to be exactly as wide as its contents are. However, I have many children in my DIV that inevitable collapse because they take up more horizontal space than the div allows.
I have this CSS:
.outer{
width: 100%;
background-color: green;
}
.inner{
width: auto;
display: inline-block;
margin: 0 auto;
background-color: red;
}
.row{
float: left;
width: 250px;
background-color: blue;
display: inline-block;
}
And this is my HTML:
<div class="outer">
<div class="inner">
<div class="row">asd1</div>
<div class="row">asd2</div>
<div class="row">asd3</div>
<div class="row">asd4</div>
</div>
<div class="clear"></div>
</div>
Here is my jsfiddle: http://jsfiddle.net/vullnetyy/pshao68g/
What I want to do here is:
the red div must be exactly as wide as the 3 blue divs in its first row
the red div must be centered within the green div
javascript must be avoided
no static width may be set to the red or green divs (because this is supposed to be responsive, and an arbitrary number of blue divs may be provided)
First of all, if you want to center an Element you need to make it:
display: block;
width : %/px;
margin-left: auto;
margin-right:auto;
If you want the 3 blue divs to be inside of the red div and to be exactly 3 blue = 1red width, give each blue 33.333% width.
such as in this example: https://jsfiddle.net/vullnetyy/pshao68g/
Theres two conflicting issues here.
1)You must have a set width in order to do margin-left/right auto.
2)If you float to try to match child width you cant do margin auto. Now I know you didnt put float left on inner. But you did do display:inline-block which has float left and a few other rules attached.
In this particular case, you have to compromise just a little to get the results you want. Simply set .inner to the same as the row aka 250px since we know thats how large the child will be, and remove display:inline-block and PRESTO!
try this for to your inner and see what happens.
.inner{
width: 250px;
margin: 0 auto;
background-color: red;
}
I want a container with two columns. Details:
The container
Width should adjust to 100% of its parent element (easily accomplished).
Height must adjust to contain both columns (i.e. its height should be exactly equal to the larger height of the two columns, so there is no overflow and scrollbars never show)
Should have a minimum size equal to double the width of the left column.
The columns in general
Should be of variable height, adjusting to the height of their content.
Should be side-by-side, such that their top edges are in line.
Should not break the layout or wrap under each other if even a single pixel of border, padding, or margin is applied to either one, because that would be extremely unstable and unfortunate.
The left column specifically
Must have a fixed, absolute width in pixel units.
The right column specifically
Width must fill the remaining space in the container. In other words...
Width must equal the container width minus the width of the left column, such that if I place a DIV block element inside this column, set its width to 100%, give it a height of something like 10px, and give it a background color, I will see a 10px high colored strip that goes from the right edge of the left column to the right edge of the container (i.e. it fills the right column's width).
Required stability
The container should be able to resize (by resizing the browser window) down to its minimum width (specified earlier) or to a much larger width without breaking the layout. "Breaking" would include the left column changing size at all (remember it's supposed to have a fixed pixel width), the right column wrapping under the left one, scrollbars appearing, block elements in the right column failing to take up the entire column width, and in general any of the aforementioned specifications failing to remain true.
Background
If floating elements are used, there should be no chance that the right column will wrap under the left one, that the container will fail to contain both columns (by clipping any part of the column or allowing any part of the columns to overflow its boundary), or that scrollbars will appear (so I'd be weary of suggesting the use of anything other than overflow:hidden to trigger floating-element containment). Applying borders to the columns should not break the layout. The content of the columns, especially of the right column, should not break the layout.
There seems to be a simple table-based solution to this, but under every circumstance it fails miserably. For example, in Safari, my fixed-width left column will shrink if the container gets too small, rather than maintaining the width I specified. It also seems to be the case that CSS width, when applied to a TD element refers to a minimum width, such that if something larger is placed inside it, it will expand. I've tried using table-layout:fixed; doesn't help. I've also seen the case where the TD element representing the right column will not expand to fill the remaining area, or it will appear to (for example a third column 1px wide will be pushed all the way to the right side), but putting a border around the right column will show that it's only as wide as its inline content, and block-level elements with their width set to 100% do not fill the width of the column, but rather match the width of the inline-content (i.e. the width of the TD seems to be completely dependent on the content).
One potential solution I have seen is too complex; the solution needs to work in IE8, Firefox 4, and Safari 5.
Here you go:
<html>
<head>
<title>Cols</title>
<style>
#left {
width: 200px;
float: left;
}
#right {
margin-left: 200px;
/* Change this to whatever the width of your left column is*/
}
.clear {
clear: both;
}
</style>
</head>
<body>
<div id="container">
<div id="left">
Hello
</div>
<div id="right">
<div style="background-color: red; height: 10px;">Hello</div>
</div>
<div class="clear"></div>
</div>
</body>
</html>
See it in action here: http://jsfiddle.net/FVLMX/
Try this: Live Demo
display: table is surprisingly good. Once you don't care about IE7, you're free to use it. It doesn't really have any of the usual downsides of <table>.
CSS:
#container {
background: #ccc;
display: table
}
#left, #right {
display: table-cell
}
#left {
width: 150px;
background: #f0f;
border: 5px dotted blue;
}
#right {
background: #aaa;
border: 3px solid #000
}
Piece of cake.
Use 960Grids Go to the automatic layout builder and make a two column, fluid design. Build a left column to the width of grids that works....this is the only challenge using grids and it's very easy once you read a tutorial. In a nutshell, each column in a grid is a certain width, and you set the amount of columns you want to use. To get a column that's exactly a certain width, you have to adjust your math so that your column width is exact. Not too tough.
No chance of wrapping because others have already fought that battle for you. Compatibility back as far as you likely will ever need to go. Quick and easy....Now, download, customize and deploy.
Voila. Grids FTW.
Over 11 years later. Apply display:grid to the container and divide the available space by grid-template-columns: 100px 1fr. Where 1fr represents a fraction of 100% of the remaining space.
<html>
<head>
<title>Cols</title>
<style>
#container {
display: grid;
grid-template-columns: 100px 1fr;
}
</style>
</head>
<body>
<div id="container">
<div id="left">
Hello
</div>
<div id="right">
<div style="background-color: red; height: 10px;">Hello</div>
</div>
</div>
</body>
</html>
As suggested by mtmurdock it is possible to remove the .clear rule and move it to the pseudo-element #container::after.
<html>
<head>
<title>Cols</title>
<style>
#left {
width: 200px;
float: left;
}
#right {
margin-left: 200px;
/* Change this to whatever the width of your left column is*/
}
#container::after {
clear : left;
display: block;
content: '';
}
</style>
</head>
<body>
<div id="container">
<div id="left">
Hello
</div>
<div id="right">
<div style="background-color: red; height: 10px;">Hello</div>
</div>
</div>
</body>
</html>
Another idea is to include the left div in the right div,
which in turn coincides with the line container:
[right][left] ... [/left] ..... [/right]
x { border: thick solid navy; padding: 2px; }
.lineContainer, .container > p {
padding-left: 100px;
margin: 0;
line-height: 1.5;
}
.left, em {
margin-left: -100px;
display:inline-block; box-sizing: border-box; width: 100px;
vertical-align: top;
}
.div-in-div {
display:inline-block; box-sizing: border-box; width: 100%;
vertical-align: top;
}
<h3>Layout: div-left is contained within the right-div / lineContainer</h3>
<pre>
[right][left] … [/left] … [/right]
</pre>
<div class="lineContainer" style="background:floralwhite; "><div class="left">Hello</div>Hello there</div>
<p>Using the above scheme,
we can make old-fashioned typewriter tab stops as shown here.</p>
<h3>The Capital Cities of the UK</h3>
<div class="container" style="background-color: floralwhite; ">
<p><em>England</em> - The capital is London.</p>
<p><em>Scotland</em> - The capital is Edinburgh.</p>
<p><em>Wales</em> - The capital is Cardiff.</p>
<p><em>Northern Ireland</em> - The capital is Belfast.</p>
<p><em>The capital of the UK is</em> - London.</p>
<p><em>Source</em>- Project Britain, capitals.</p>
</div>
<h3>Div in div</h3>
<div class="lineContainer" style="background:floralwhite; ">
<div class="left">Div in container</div><!--No white space here
--><p class="div-in-div" style="background: red; font-size: x-large; margin: auto 0; ">Hello there</p>
</div>