I have the following HTML:
<div id="parent">
<div class="child">Box1</div>
<div class="child">Box2</div>
<div class="child">Box3</div>
<div class="child">Box4</div>
<div class="child">Box5</div>
<div class="child">Box6</div>
<div class="child">Box7</div>
<div class="child">Box8</div>
<div class="child">Box9</div>
<div class="child">Box10</div>
</div>
And the following CSS:
#parent {
display: inline-block;
max-width: 1000px;
height: 500px;
border: 1px solid #000000;
text-align: center;
}
.child {
width: 100px;
height: 100px;
border: 1px solid #000000;
margin: 10px;
float: left;
}
I want to float left the child DIVs and at the same time center them in the parent DIV that does't have a fixed width.
The reason I don't want to use display: inline-block for the child DIVs is that if a row has only 1 or 2 boxes , they will be centred and i want them to be aligned to the left with the boxes on the previous rows.
The second reason is that more data will be loaded using ajax. So, if the last row has only 1 or 2 boxes and still can accommodate more boxes, they will be inserted into a new line instead of being appended to the last row. I'm not sure of this point but I think that what would happen when using display inline-block. Float instead doesn't have this behaviour.
Forgot to mention that the parent should be display: inline-block because another box will be aligned next to it.
I created a fiddle for you to play with:
http://jsfiddle.net/6a2eqpmu/
Unfortunately you are unable to do this using pure css. If you are willing to use a bit of javascript and jQuery you can easily achieve what you want:
var parent = $('#parent'),
container = $('#container'),
children = container.children('.child'),
width = children.eq(0).outerWidth() + parseInt(children.eq(0).css('margin-left')) + parseInt(children.eq(0).css('margin-right')),
maxWidth = children.length * width;
function resizeContainer() {
var newWidth = Math.floor(parent.width() / width) * width;
if (newWidth <= maxWidth && newWidth > 0) {
container.width(newWidth);
}
}
$(window).resize(resizeContainer);
resizeContainer();
Example
Simply add margin: 0 auto; to #parent. This will center the parent div when the document width is over 1000px wide.
If your parent element doesn't have a fixed width you can't center his child elements with only CSS. I think you have to write some script that calculate the parent width, every row width and set to them the properly margin-right and margin-left.
text-align works on inline elements. If I understand your problem, you should remove the float and put the boxes in display:inline-block.
Something like this : http://jsfiddle.net/6a2eqpmu/7/
#parent {
max-width: 1500px;
height: 500px;
border: 1px solid #000000;
text-align: center;
}
.child {
width: 100px;
height: 100px;
border: 1px solid #000000;
margin: 10px;
display:inline-block;
}
I added html comments to avoid the white-space problem, and put a max-width of 1500px in order to see the boxes centered.
You can add invisible placeholders to the end of your inline blocks. That will left-align the last row.
http://jsfiddle.net/aakt65x4/
If you don't fill up the first row, the entire thing will appear left-aligned. But I think that's what you want.
HTML:
<!--
Centers a group of boxes that wrap to the width of its container.
Also left-aligns them inside the container.
Issue: Does not center group if there aren't enough boxes to fill
the first row.
-->
<div class="container">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<!--
How many placeholders do you need?
At least the number of blocks minus two.
-->
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
</div>
CSS:
body {
text-align: center; /* center a max-width container */
font-size: 0; /* remove spaces between blocks */
}
.container { /* you don't need this */
background-color: #eee; /* so you can see what's happening */
max-width: 960px; /* to demonstrate the centering of a max-width container */
display: inline-block; /* center the max-width container */
text-align: center; /* center the group of blocks */
}
.block {
display: inline-block; /* left-align within the group */
background-color: red; /* so you can see what's happening */
height: 100px;
width: 100px;
margin: 10px;
}
.placeholder {
display: inline-block; /* add to the line of blocks */
width: 120px; /* width + margin of a block */
}
Related
This question already has answers here:
Parent is inline-block and child has % padding = strange behaviour
(3 answers)
Closed 17 days ago.
I have a component in HTML consisting of 3 nested divs. The overall size of the component is to be controlled by the height and width of the inner div (green). The middle (blue) and outer (red) divs are to wrap the inner div with a 15% gap (so they will both be the same size), so the result should look like this:
To accomplish the gap, I can either:
add 15% padding to the middle div, or
add 15% margin to the inner div
However, doing either of these causes the middle and outer divs to expand vertically by 15% but not horizontally. The inner div is still moved to the right by 15% (because of the left-hand padding/margin) but this results in it overflowing the right-hand side of the middle/outer divs.
The following image shows 3 examples:
No margin/padding, so all 3 divs are (correctly) the same size, i.e. that of the inner div
The middle div has 15% padding
The inner div has 15% margin
So how can I force the middle and outer divs to respect the horizontal padding/margin, so it's applied equally to all sides of the inner div?
.outer {
border: red 1px dashed;
display: inline-block;
margin-left: 50px;
/* Just to space the examples out */
}
.middle {
border: blue 1px dashed;
display: block;
}
.inner {
border: forestgreen 1px dashed;
display: block;
height: 100px;
width: 100px;
}
.has-padding {
padding: 15%;
}
.has-margin {
margin: 15%;
}
<div class="outer">
<label class="middle">
<div class="inner"></div>
</label>
</div>
<div class="outer">
<label class="middle has-padding">
<div class="inner"></div>
</label>
</div>
<div class="outer">
<label class="middle">
<div class="inner has-margin"></div>
</label>
</div>
You can get the result you're looking for using inline-flex for the .outer and .middle.
As pointed out in a comment, px and rem works, because it's essentially a "known" value. When you use a %, it's a percentage of the element, parent elements are not affected by this value - so the child will overflow.
flex parents will take the child width into consideration - including its margin property.
padding on the .inner element will affect its direct parent (.middle), but the .outer is not affected by the .middle element, so it will overflow.
I'll update this answer when I can find the MDN info about this.
* {
box-sizing: border-box;
}
.outer {
border: red 1px dashed;
display: inline-flex;
}
.middle {
border: blue 1px dashed;
display: inline-flex;
}
.inner {
border: forestgreen 1px dashed;
height: 100px;
width: 142.835px;
margin: 15%;
}
<div class="outer">
<label class="middle">
<div class="inner"></div>
</label>
</div>
I have the parent's block (red) that should change its size by height relatively the content filling inside the green block.
The green block has an absolute position, and this is a must.
The question is about the content filling of the green block and the logical automatical size changing of the red block.
So, 2 question:
How to center the green block by the horizontal/center?
How to automatically change the red block's height relatively the content filling of the green block?
<body>
<div class="some"></div>
<div class="container">
<div class="main">
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
</div>
</div>
</body>
body {
background: purple;
}
.some {
height: 100px;
}
.container {
width: 1030px;
height: 600px;
background: red;
position: relative;
margin: auto;
}
.main {
position: absolute;
background: green;
margin-top: -50px;
width: 400px;
}
.content {
width: 300px;
height: 100px;
background: blue;
margin: 20px auto;
display: flex;
justify-content: center;
align-items: center;
color: white;
}
http://jsfiddle.net/xtupmyvf/2/
I have created a sample solution here https://jsfiddle.net/saksham_malhotra/upnrfjm0/
There is a lot going on in your code which is unnecessary and I have written a simplified version of it. The crux is to take care of the display properties to get a good layout.
You need not make the left section absolute positioned to stick it to the left. Just make the wrapping container display: block to not to take the whole width.
This is fairly a simple question but I cant wrap my head around a simple solution. I need to center 3 squares in a row, but I dont know the total amount of squares (while the simple solution to this would be to use text-align: center), BUT I dont want to center the last elements. Long story short, how to create float: left effect + centering all elements inside the main container?
JSfiddle here.
HTML:
<div class="row b">
<div class="col-lg-6 col-md-6 col-sm-12 col-lg-offset-3 col-md-offset-3">
<div class="row maxW b">
<div class="postContainer"></div>
<div class="postContainer"></div>
<div class="postContainer"></div>
<div class="postContainer"></div>
</div>
</div>
</div>
CSS:
.postContainer {
width: 230px;
height: 230px;
border: 1px solid lightblue;
display: inline-block;
}
.maxW {
max-width: 900px;
}
.ce {
text-align: center;
}
.b{
border:1px solid black;
}
Expected result:
These squares should be responsive, max squares per row is 3. If I use float: left, I get almost what I need, but the squares are pulled to the left and not centered inside the main container. If I use text-align: center, the squares are centered in the main container, but I dont want the last squares to be centered, they must remain floated to the left.
I would recommend using flexbox. It's a pretty new concept in css, but it has good support in all modern browsers. I personally use it in production.
The markup would be simplified as:
<div class="posts">
<div class="postContainer"></div>
<div class="postContainer"></div>
<div class="postContainer"></div>
<div class="postContainer"></div>
</div>
And the container would have the CSS:
.posts {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
margin: 0 auto;
}
Display: flex tells the browser it's a flexbox, flex-flow says that it should be rows that wraps when full and that the content should be left-aligned by flex-start.
Fiddle
Flexbox basics
You can set the container width to 33% and then set the post border and width on a contained div.
.postContainer {
width: 33%;
display: inline-block;
text-align: center;
}
.post {
width: 230px;
height: 230px;
border: 1px solid lightblue;
display: inline-block;
}
https://jsfiddle.net/k9597cLq/
You can just use display:inline-block; instead of float.
You CSS would look something like this:
.maxW{
border:1px solid black;
padding:5px;
}
.postContainer{
width:150px;
height:150px;
border:1px solid black;
display:inline-block; /* <-- the magic part*/
}
DEMO
I want an element (100px) centered on the display. This element has on each side elements with eg 300px and 200px.
I did it with flex an as a result there are 2 free spaces / flexible width elements. Centered element is centered in the free space no with the whole display width. You can see it in the image as well at codepen.
I want 100px box (as in green row) in the middle. I am not using float left/right for side elements and then center middle element because I need to apply a background image to flexible width elements.
The codepen.
html, body, div {
width: 100%;
}
.row {
height: 100px;
}
.row.row-flex {
display: flex;
}
.row.row-green {
background-color: green;
}
.row.row-red {
background-color: red;
}
.col {
margin: 0 auto;
height: 100%;
border: 1px solid black;
text-align: center;
}
.col.col-100 {
width: 100px;
}
.col.col-200 {
width: 200px;
}
.col.col-300 {
width: 300px;
}
.col.col-flex {
flex: 1;
}
<div class="row row-flex row-red">
<div class="col col-300">300px</div>
<div class="col col-flex"></div>
<div class="col col-100">100px</div>
<div class="col col-flex"></div>
<div class="col col-200">200px</div>
</div>
<div class="row row-green">
<div class="col col-100">100px</div>
</div>
In this case, I think absolute positioning is the way. Flex positions its children in a way that each gets fair share of free space. Add
row {position: relative;}
and
&.col-100{position: absolute; top: 0; left: calc(50% - 50px);}
to align 100px div against whole row.
Edited codepen: https://codepen.io/anon/pen/pRwOYv
I have a container div with a fixed width and height, with overflow: hidden.
I want a horizontal row of float: left divs within this container. Divs which are floated left will naturally push onto the 'line' below after they read the right bound of their parent. This will happen even if the height of the parent should not allow this. This is how this looks:
How I would like it to look:
![Right][2] - removed image shack image that had been replaced by an advert
Note: the effect I want can be achieved by using inline elements & white-space: no-wrap (that is how I did it in the image shown). This, however, is no good to me (for reasons too lengthy to explain here), as the child divs need to be floated block level elements.
You may put an inner div in the container that is enough wide to hold all the floated divs.
#container {
background-color: red;
overflow: hidden;
width: 200px;
}
#inner {
overflow: hidden;
width: 2000px;
}
.child {
float: left;
background-color: blue;
width: 50px;
height: 50px;
}
<div id="container">
<div id="inner">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
style="overflow:hidden" for parent div and style="float: left" for all the child divs are important to make the divs align horizontally for old browsers like IE7 and below.
For modern browsers, you can use style="display: table-cell" for all the child divs and it would render horizontally properly.
You can now use css flexbox to align divs horizontally and vertically if you need to. general formula goes like this
parent-div {
display: flex;
flex-wrap: wrap;
/* for horizontal aligning of child divs */
justify-content: center;
/* for vertical aligning */
align-items: center;
}
child-div {
width: /* yoursize for each div */
;
}
This seems close to what you want:
#foo {
background: red;
max-height: 100px;
overflow-y: hidden;
}
.bar {
background: blue;
width: 100px;
height: 100px;
float: left;
margin: 1em;
}
<div id="foo">
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
</div>
you can use the clip property:
#container {
position: absolute;
clip: rect(0px,200px,100px,0px);
overflow: hidden;
background: red;
}
note the position: absolute and overflow: hidden needed in order to get clip to work.
Float: left, display: inline-block will both fail to align the elements horizontally if they exceed the width of the container.
It's important to note that the container should not wrap if the elements MUST display horizontally:
white-space: nowrap
Float them left. In Chrome, at least, you don't need to have a wrapper, id="container", in LucaM's example.