remove/ignore float from outer div - css

This may sound weird but i have some css which aligns mys divs. In one place i also use http://www.brunildo.org/test/img_center.html which centers images.
Now i want my divs inside a larger div to go to another line if this one gets full. float: left seems to be the answer. The problem is it ruins my formatting. Including solution in the above link. I have this test code. If i remove the width and float it looks fine except it may take up too much space and not go to another line.
I was thinking i could use float on an outerdiv and center the image within. However float: left is still breaking it. I am hoping there is a way to remove the float so each div does go left but the div inside centers correctly not breaking my formatting.
<style type="text/css">
.wraptocenter {
display: table-cell;
text-align: center;
vertical-align: middle;
width: 200px;
height: 200px;
background: blue;
}
.wraptocenter * {
vertical-align: middle;
}
/*\*//*/
.wraptocenter {
display: block;
}
.wraptocenter span {
display: inline-block;
height: 100%;
width: 1px;
}
/**/
div.c
{
background: red;
overflow: hidden;
min-width: 400px;
max-width: 400px;
}
div.c div
{
float: left;
}
</style>
<!--[if lt IE 8]><style>
.wraptocenter span {
display: inline-block;
height: 100%;
}
</style><![endif]-->
<div class="c">
<div>
<div>
<div class="wraptocenter"><span></span><img src="a.jpg" alt="/a.jpg"></div>
<div class="wraptocenter"><span></span><img src="a.jpg" alt="/a.jpg"></div>
<div class="wraptocenter"><span></span><img src="a.jpg" alt="/a.jpg"></div>
</div></div></div>

regular old display:inline can be used on the images themselves (or a container div). this will let the items flow onto multiple lines depending on the width of the enclosing div.
to center the top-level div, something like margin: 0 auto should do it (if the parent has a width) or the good old <center> tag if not.

Related

row of images evenly distributed

I want a row of images evenly distributed and justified, after some research I've found this elegant method:
#container {
text-align: justify;
background-color: #FF0000;
}
#container img {
display: inline-block;
}
#container:after {
content: "";
width: 100%;
display: inline-block;
}
<div id="container">
<img src="http://placehold.it/150x100" />
<img src="http://placehold.it/100x150" />
<img src="http://placehold.it/250x50" />
<img src="http://placehold.it/150x150" />
</div>
See the result here: http://codepen.io/naio/pen/vbgrm
Why that little margin on the right?
How can I get rid of the empty space added below the images?
You can remove the bottom whitespace using the following adjustments to your CSS:
#container {
text-align: justify;
background-color: #FF0000;
line-height: 0;
}
#container img {
display: inline-block;
}
#container:after {
content: "";
width: 100%;
display: inline-block;
vertical-align: bottom;
}
The generated content from the pseudo-elememt (empty string) creates an inline box that has a height equal to the line height of the containing block (#container in this example).
By setting line-height: 0, this forces any inline boxes to shrink to zero height.
Footnote
In Chrome (and similar webkit browsers), you will see some extra space to the right of the right-most element on the line. This extra space is not seen in Firefox (where I tested the code).
The extra space is the result of the white space in the original HTML mark-up. The right-most element has a white space character (CR/LF) before the closing </div> tag and this generated content is placed after the white-space, which shows up in some browsers.
You can get rid of it by modifying the HTML as follows:
<div id="container">
<img src="http://placehold.it/150x100" />
<img src="http://placehold.it/100x150" />
<img src="http://placehold.it/250x50" />
<img src="http://placehold.it/150x150" /></div>
that is, keep the closing </div> tag right next to the final img tag.
If you put some text in the #container:after's content property you will notice what it does
#container {
text-align: justify;
background-color: #FF0000;
}
#container img {
display: inline-block;
}
#container:after {
content: "This is some text";
width: 100%;
display: inline-block;
}
http://www.w3schools.com/cssref/sel_after.asp
Check out this link for more details. #container:after adds content after everything else in the container is loaded.
One way to solve your problem is to set the container's height to 150px, but that's not a very flexible solution. If I were you I wouldn't use these styles. When you create a div and not set it's width and height it resizes automatically to fit it's children. Somehow the #container:after is blocking this feature. Just use something else :)
another approach that doesn't have this whitespace & padding issue would be:
http://jsfiddle.net/eNKhy/3/
#container {
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
}
.stretch {
width: 100%;
display: inline-block;
font-size: 0;
vertical-align: bottom;
}
#container, #container img, .stretch{
line-height:0;
}
and add <span class="stretch"></span> in the end of your div

Children element with height: 100% getting pushed by siblings

I have a very simple structure:
<div class="parent">
<h1>Element taking space</h1>
<div class="stretch">
Not much content, but needs to be stretched to the end.
</div>
</div>
The parent div has a set height, and I want div.stretch to stretch all the way to that height, regardless of how little content it has. Using height: 100% does the trick, until you add some other element which pushes the content down.
I guess that specifying height: 100% means that the element should have the exact same absolute/computed height as the parent element, and not the remainder of the height after all the other elements have been computed.
Setting overflow: hidden obviously hides the overflowing content, but that's not an option for me.
Is there any way I can achieve that in pure CSS?
Demo of my problem
In the time since this question was asked and answered, a better way to achieve this has come into existence: flex-box.
Just set the parent's display to "flex" and flex-direction to "column", and set the "stretchy" child's height to "inherit". The child will inherit a height of however many pixels are left over to fill up its parent.
In the following example, lines marked /* important */ are part of the actual solution; the rest of the CSS is just to make it visually easier to understand.
.parent {
display: flex; /* important */
flex-direction: column; /* important */
height: 150px;
border: 6px solid green;
}
h1 {
background: blue;
margin: 0px;
height: 90px
}
.stretch {
background: red;
height: inherit; /* important */
}
<div class="parent">
<h1>Element taking space</h1>
<div class="stretch">
Not much content, but needs to be stretched to the end.
</div>
</div>
You could float the h1 element. It would work no matter what height it is, and the content of the stretch element will be pushed below it. But I'm not entirely sure if this is what you are looking for.
EDIT: I'm not certain what kind of browser support you're looking for, but you could also set the display to table on .parent and then have .stretch inherit the height. Then you can nest the column divs inside of .stretch and float them.
Updated: http://jsbin.com/oluyin/2/edit
HTML
<div class="parent">
<h1>Element taking space</h1>
<div class="stretch">
<div class="col">Not much content, but needs to be stretched to the end.</div>
<div class="col">Not much content, but needs to be stretched to the end.</div>
</div>
</div>
CSS
.parent {
display: table;
}
.stretch {
height: inherit;
}
.col {
float: left;
width: 50%;
}
If you know the height of your H1 you can do this to fill out the child:
.parent {
background-color: #eee;
border: 1px solid black;
width: 300px;
height: 600px;
position:relative;
}
h1 { Height: 100px; }
.stretch
{
background-color:#dddddd;
position: absolute;
left: 0;
width: 100%;
top: 100px;
bottom: 0;
}
Example: http://jsbin.com/apocuh/1/edit
If you don't know the height of H1, I'm afraid you will probably need to use JavaScript or thgaskell's method.
Take a look at this post for more information, and an example with JS: CSS: height- fill out rest of div?
Maybe using display:table properties fits your needs ?
Edit: This answer actually looks like thgaskell's one, but instead of using floats I use table-row and table-cell display, and it seems to achieve what you are looking for.
Here is the jsfiddle : http://jsbin.com/ebojok/17/edit
.parent {
background-color: #eee;
border: 1px solid black;
width: 600px;
height: 600px;
display:table;
}
h1{
display:table-row;
width:100%;
}
.stretch{
vertical-align:top;
display:table-cell;
height:100%;
background-color: #ddd;
}
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<div class="parent">
<h1>Element taking space</h1>
<div class="stretch">Not much content, but needs to be stretched to the end.</div>
</div>
</body>
</html>
CSS
.parent {
background-color: #eee;
border: 1px solid black;
width: 300px;
height: 600px;
position:relative;
}
.stretch {
background-color: #ddd;
height: 100%;
position: absolute;
top: 0;
}
http://jsbin.com/amesox/1/edit
This will cover your h1 element as the .stretched goes over it. You could get around this by using z-index: 1; on your h1 element, but I'd advise against it if you want text in your .stretched element.
You need position:relative; on your parent div to give position: absolute something to 'hook on' to. absolute positioned elements, ignore other elements and are placed on top of them unless their z-index is higher or they are its children.

Vertically center content of floating div

How do I verically center the content of floating div (which height I don't know)?
There is very simple HTML and CSS (see this fiddle: http://jsfiddle.net/DeH6E/1/)
<div class="floating">
This should be in the middle
</div>
​
.floating {
height: 100px;
float: left;
border: 1px solid red;
vertical-align: middle;
} ​
How do I make the sentence "This should be in the middle" appear really in the middle (vertically centered)? vertical-align: middle does not seem to work. I have tried display: table-cell and it didn't work either. What's the best way to solve this issue? I'd like to avoid inserting any other HTML tags, do it just via CSS.
(Just to make it clear: I don't know the actual height of the container, 100px is just for the example)
EDIT: I'd like you to understand me, so... Always when I design web page, I follow the rule that HTML holds the content and CSS is responsible for the visual style. I never mix them up together or use one just to enable the other. In this case, I want to stick with this rule too. I don't want to insert HTML element just for the CSS.
The others are right, you need to nest two DOM elements which gives you more options controlling the centering. Here's the code:
.floating {
display: table;
float: right;
height: 200px;
width: 400px;
border: 1px solid red;
}
.floating p {
display: table-cell;
vertical-align: middle;
text-align: center;
}
<div class="floating">
<p>This is the proper way that validates and breaks across multiple
lines, if the text is longer than just a few words and still
should be vertically centered. Here, it's also horizontally
centered for added joy.</p>
</div>
Add the text inside a <p>.
HTML
<div class="floating">
<p>This should be in the middle</p>
</div>
CSS
.floating {
height: 100px;
border: 1px solid #f00;
display: table-cell;
vertical-align: middle;
}
​
If you know the height, then
line-height:100px;
If not, use javascript to set line-height after rendering.
http://jsfiddle.net/DeH6E/4/
I was also looking for a solution to this and eventually came up with this:
http://jsfiddle.net/w6j9mgjp/1/
.floating {
height: 100px;
float: left;
border: 1px solid red;
}
.floating::before {
content: "a";
display: block;
visibility: hidden;
height: 50%;
margin-top: -.7em;
}
it only works for a single line of text, though.
http://jsfiddle.net/DeH6E/2/
the text inside of your div needs to be in its own div tag, and that div tag needs to be set to display:table-cell; and vertical-align:middle; while your .floating div needs to be set as display:table;
or you can set a p tag or some other sort of formatting tag in there to contain your text, eg span, or p
Just play with the pseudo selector.
.floating {
height: 100px;
float: left;
border: 1px solid red;
}
.floating::before {
content: '';
display: inline-block;
vertical-align: middle;
height: 100%;
}

Position images of various size in a grid with CSS

I have a series of images (about a 100 or so) that have been resized so that they fit in a background box that is 130x130. The images are either 130 wide or 130 high. How do I style the image so that they appear in the middle of the 130px box.
This is the effect I want to achieve: http://i.imgur.com/LY1Ag.png
Here's another method that has two main differences: avoids the use of background images (the use of which is semantically weird as Nightfirecat mentioned) and puts the images within an unordered list. The latter isn't necessary but is arguably follows CSS best practices.
I haven't tested extensively but on recent Firefox, Chrome and IE for PC. I had to add a hack for IE7 based on this page's suggestions. That's the reason for the empty <span> for each list item.
CSS:
<style type="text/css">
#boxes {
list-style: none outside none;
margin: 0;
overflow: hidden;
padding: 0;
}
#boxes li {
float: left;
border: 1px solid #333;
margin: 30px;
}
#boxes li div {
position: relative;
width: 130px;
height: 130px;
text-align: center;
display: block
}
#boxes li div img {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto
}
</style>
<!--[if IE 7]>
<style type="text/css">
#boxes li div * {
vertical-align: middle;
}
#boxes li div img {
position: relative;
}
#boxes li div span {
display: inline-block;
height: 100%;
}
</style>
<![endif]-->
HTML:
<ul id="boxes">
<li><div><span></span><img src="wide1.jpg"></div></li>
<li><div><span></span><img src="wide2.jpg"></div></li>
<li><div><span></span><img src="wide3.jpg"></div></li>
<li><div><span></span><img src="tall1.jpg"></div></li>
<li><div><span></span><img src="wide4.jpg"></div></li>
<li><div><span></span><img src="tall2.jpg"></div></li>
</ul>
Done quickly, so it's entirely possible that there are some bugs.
If you use them as backgrounds for a div, you're all set:
CSS:
div.box-images div {
float: left; /* has them left-align */
height: 130px;
width: 130px;
margin: 12px; /* gives them gutters in between */
background-position: 50% 50%; /* ensures they're centered */
background-repeat: no-repeat;
border: 2px solid #ccc;
}
HTML:
<div class='box-images'>
<div style='background-image: url(images/sample1.png);'></div>
<div style='background-image: url(images/sample2.png);'></div>
[etc.]
<br style='clear: both;' />
</div>
I personally wouldn't use background images.
I would, if possible, apply a class to each box that holds these image. the box would have set height and width as you mentioned.
Then, with jQuery or javascript, add a class depending on the images height or width. so if the width is 130px, add the class of top and bottom padding. If the image is 130 high, add the left and right padding class.
Hope this makes sense and helps you. Let me know if you need me to elaborate.
Although I only tested in fx, chrome and IE9 but you can use vertical-align: middle + line-height: 130px on the image like this:
css:
div.box {
width: 130px;
height: 130px;
text-align: center;
line-height: 130px;
}
div.box img {
vertical-align:middle;
}
html
<div class="box">
<img src="image1.jpg">
</div>
<div class="box">
<img src="image2.jpg">
</div>
I'm getting a little bit of a push though, when the image is the same height as the box. Anyone else know why? You can see it here: http://jsfiddle.net/9bu5Z/1/

How to align the top lines of two DIVs?

I want the top lines of two DIVs (<div></div>) to be aligned horizontally, how to do it?
Steven,
In addition to T. Stone's suggestion to float both divs, a simple way to align two divs is to make both have the display: inline-block; CSS rule and give the lower div the vertical-align: top; CSS rule.
Take a look at this simple jsFiddle example to see how this works.
div {
display: inline-block;
}
div#tall {
height: 4em;
}
div#short {
height: 2em;
vertical-align: top;
}
In response to "is there another way to do it", sure you could use display: inline but you have a bunch of hacks to remember to get it to work in IE6/7. This way is generally better (but it all comes down to the individual circumstances)
<style type="text/css">
.keeper {
overflow: hidden; /* expand to contain floated children */
}
.keeper div {
width: 200px;
height: 30px;
float: left;
border-top: 1px solid red; /* so you can see the 'tops' */
}
</style>
<div class="keeper">
<div>
</div>
<div>
</div>
</div>
Float them in a container.
.parent div { float: left; width: 50%; }
<div class="parent">
<div>1</div>
<div>2</div>
</div>
Note: The sum of the width of the child divs can not be greater than 100% of the parent div, including margin and padding.
Alternative
If maintaining flow with the page isn't a requirement, and all that really matters is aligning, them, the divs can always be positioned absolutely.
.abs { position: absolute; top: 100px; width: 50px; }
.left { left: 0px; }
.right { left: 50px; }
<div class="abs left">1</div>
<div class="abs right">2</div>

Resources