CSS - Make divs align horizontally - html

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.

Related

How to align HTML divs horizontally so they overflow their wrapper?

I want to align 4 divs horizontally inside a wrapper that has a fixed width and height. Each div should have the same width and height as their wrapper. When the divs are aligned, it should look something like this:
I assume the wrapper has to have the overflow: hidden; property inside its CSS style, so the overflowing divs aren't visible.
I tried using display: grid; on the wrapper but didn't get the resulting columns to overflow. I also tried display: flex; which resulted in the same output. However, if I align the divs as rows inside the wrapper, the vertical align with overflow works.
You need to put all your divs inside the same wrapper like this :
<div class="wrapper">
<div class="wrapper-item">a</div>
<div class="wrapper-item">b </div>
<div class="wrapper-item">c </div>
<div class="wrapper-item">d </div>
</div>
css :
.wrapper{
display: flex;
justify-content: center;
}
.wrapper-item{
border: 1px solid blue;
width: 200px;
height: 200px;
margin: 0 20px;
overflow-wrap: break-word;
word-wrap: break-word;
overflow-y:auto;
}
I've created a codpen, tell me if this is what you're looking for
https://codepen.io/iheb-riahi-horizon-tech-tn/pen/ExpGqrb

Why has CSS overflow property on parent effect on size of IMG child?

The following does exactly what I want, but I don't understand why, which annoys me.
I want:
the "second" div to take as much space as it can, within the constraints of its parent
then divide that space evenly amongst it's 2 child divs
scale the imgs so that they fit exactly in their parent div
<!DOCTYPE html>
<html>
<head>
<style>
.root {
width: 500px;
height: 500px;
}
.flex-container {
display: flex;
flex-direction: column;
background-color: red;
height: 100%;
width: 100%;
}
.first {
background-color: blue;
}
.second {
background-color: darkmagenta;
flex-grow: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.wrap {
height: 50%;
width: 100%;
}
img {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div class="root">
<div class="flex-container">
<div class="first">
This div should be sized accoring to it's content and wrap if needed
which it does, nice!
</div>
<div class="second">
<div class="wrap">
<img
src="https://www.publicdomainpictures.net/pictures/30000/velka/cat-13476279941Ls.jpg"
/>
</div>
<div class="wrap">
<img
src="https://www.publicdomainpictures.net/pictures/30000/velka/cat-13476279941Ls.jpg"
/>
</div>
</div>
</div>
</div>
</body>
</html>
After experimenting and messing around I arrived at this HTML and CSS. Crucial is the overflow: hidden; on the "second" div. Without it, the child imgs are displayed larger, growing the "second" div beyond its parent.
I do not understand how overflow: hidden; can affect the size of the childs - I would have expected them to be clipped. Any pointers?
I found a nicer way to do this in this post: flex child is growing out of parent
Instead of putting overflow: hidden; on the parent, that posts suggest setting min-height: 0; which allows its children to shrink and become smaller than their content.
That makes more sense to me.
EDIT
Found this post with even more detail, and a link to the flexbox spec which explains it all: Why don't flex items shrink past content size?
On a flex item whose overflow is visible in the main axis, when specified on the flex item’s main-axis min-size property, specifies an automatic minimum size. It otherwise computes to 0.

Mini-navbar with left, middle and right in HTML and CSS

I want to make a very simple navbar with HTML and CSS (so simple I prefer to do it without Bootstrap), made of just three short texts, situated on the leftmost, center, and rightmost part of one single line.
My idea is that I cut the line in two halves, put the left & middle part in the first half, and the rightmost part in the second half. So I tried the following :
.div_left {
float: left;
position: absolute;
}
.div_right {
float: right;
text-align: right;
position: absolute;
}
.container_for_mininavbar {
width: 100%;
position: absolute;
}
.mininavbar_left_half {
width: 50%;
float: left;
position: absolute;
}
.mininavbar_right_half {
width: 50%;
float: right;
position: absolute;
}
<div class="container_for_mininavbar">
<div class="mininavbar_left_half">
<div class="div_left">Left Text</div>
<div class="div_right">Center Text</div>
</div>
<div class="mininavbar_right_half">
<div class="div_right">Right Text</div>
</div>
</div>
But that doesn't work, all the texts are on top of each other.
What is the correct way to do this?
Just remove position absolute.
I'll suggest to use flexbox to do this and don't use float anymore
.div_left {
float: left;
}
.div_right {
float: right;
text-align: right;
}
.container_for_mininavbar {
width: 100%;
}
.mininavbar_left_half {
width: 50%;
float: left;
}
.mininavbar_right_half {
width: 50%;
float: right;
}
<div class="container_for_mininavbar">
<div class="mininavbar_left_half">
<div class="div_left">Left Text</div>
<div class="div_right">Center Text</div>
</div>
<div class="mininavbar_right_half">
<div class="div_right">Right Text</div>
</div>
</div>
And this is a little example with flexbox
.container_for_mininavbar {
width: 100%;
border: 1px;
display: flex;
}
.container_for_mininavbar div {
flex: 0 1 33.33%;
border: 1px solid #000;
text-align: center;
}
<div class="container_for_mininavbar">
<div>Left Text</div>
<div>Center Text</div>
<div>Right Text</div>
</div>
So, you want some links to the left, some to the center and the rest to the right?
The easiest and most effective way (by me) is to use Flexbox.
So, you need a container div, named "navigation" (or however you want) which contains another 2 divs, one for the left side, and one for the right side.
Now, assign to the navigation div, the following:
display: flex; /* is going to display the div flex */
justify-content: space-between; /* this is where magic happens, it will push the items from the nav div, which are the other 2 divs to the left and right side*/
flex-flow: row nowrap;
The first property is for it to be displayed in a row, you can set it to column too, and the nowrap is not going to let the content to deform in some sort of way, if you set that to wrap, of course, it will wrap under, but I suggest letting that nowrap, but I don't think flex-flow is 100% neccesary in this situation
Now, the flexbox works for the other 2 divs as well, maybe you want the links in the left-side div to be "justify-content: space-between;" or space-evenly, or center, space-around, etc.
I recommend you to learn Flexbox, it's very useful and simple to use.
I hope this answer will help you. :)
And to center the links in each div, use align-items: center; , it will center the links on the Y scale. (which is top-bottom)
EDIT: If you want center links too, it's the same thing, just make another div between the left-side div and the right div. And the justify-content: space-betweeen; it's going to have the same effect. And if you don't link how it scales, you can always use the margins in the div.

BFC is overlapped when designing three-column layout

.left {
float:left;
display:inline-block;
}
.right {
float:right;
display:inline-block;
}
.mid {
display:inline-block;
overflow:hidden;
text-overflow: ellipsis;
}
.container {
width:100px;
overflow:hidden;
text-overflow: ellipsis;
white-space:nowrap;
display:inline-block;
}
<div class="container">
<div class="right">right</div>
<div class="left">left</div>
<div class="mid">midmidmidmidmidmidmidmid</div>
</div>
Like above, I want the mid part get auto-fit width and it will be a long text, just show '...'.
I plan to use float to implement the three-column layout, and I learned that BFC will never be overlapped by other BFC, how does my right part get overlapped.? Help thanks!!
You can simply use Flexbox to create your layout. This resource can help you to get started with it. Using flexbox will also solve your 'overlapping' issue thanks to the property flex-wrap: wrap. Play around with it.
.flex {
display: flex;
}
<div class="flex">
<div class="right">right</div>
<div class="left">left</div>
<div class="mid">midmidmidmidmidmidmidmid</div>
</div>
In your case, your container is only allowed to be 100px wide, so it tries to fit everything in that small space. It's too small. Make your container larger, or use min-width.
Not sure how you arrived at, "I learned that BFC will never be overlapped by other BFC."
I'm going to use MDN's Block Formatting Context as a source.
Essentially, as far as floats are concerned, a new BFC will allow an element with floated descendants to "see" the whole element and not just the content of the element. When an element is floated it is taken out of the normal document flow.
The overlapping happens because of other properties that you have applied to your elements and not so much whether there's a new BFC. If I remove all the properties that are controlling what happens to the content of the .mid and .container elements, you'll get the order you want but the content of .mid is not on a single line.
The overlapping also happens because of white-space: nowrap; property on .container which forces the content of .mid to be on a single line which then overlaps the content of .right. Note that I added spaces to the text of .mid to illustrate that if the content is not too big, it will fit in the small space between .left and .right.
.left {
float: left;
display: inline-block;
}
.right {
float:right;
display: inline-block;
}
.mid {}
.container {
width: 100px;
display: inline-block;
}
<div class="container">
<div class="right">right</div>
<div class="left">left</div>
<div class="mid">mid mid mid mid mid mid mid mid</div>
</div>
To get the desired result, add white-space: nowrap; to .mid instead of .container and remove display: inline-block;.
.left {
float: left;
}
.right {
float: right;
}
.mid {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.container {
width: 100px;
overflow: hidden;
display: inline-block;
}
<div class="container">
<div class="right">right</div>
<div class="left">left</div>
<div class="mid">midmidmidmidmidmidmidmid</div>
</div>

Center floated child DIVs in a parent DIV that has fluid width

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 */
}