Vertical-align works strangely (on cell-tabs) - html

I have a problem using the vertical-align:top; property on a cell-tab css content.
Here the picture : http://img4.hostingpics.net/pics/157625Capture.png
My HTML code :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="style_test.css" />
<title>Test</title>
</head>
<body>
<div class='tableau'>
AAAA<img class='img1' src='images/drapeau_anglais.gif' />
<img class='img2' src='images/drapeau_anglais.gif' />
<span>BBBB</span>
<!-- This text lose the vertical-align:top; propertie because it is in the <span> => WHY ??? -->
<p>CCCC<img src='images/drapeau_anglais.gif' />DDDD</p>
<!-- As in the span, everything in my <p> loose it s vertical align propertie -->
</div>
</body>
</html>
My CSS code :
.tableau
{
display:table-cell;
border:1px solid black;
vertical-align:top;
}
.tableau p
{
display:inline-block;
}
.img1
{
/* I dont say anything here. img1 SHOULD be on top because of the ".tableau" class but it doesnt... why???*/
}
.img2
{
/* I force the vertical align on my image (but I shouldnt have to do that normally ?) But with this "trick" it works */
vertical-align:top;
}
Thanks a lot for your help !

I commend you for wanting to understand. The problem with vertical-align is that it doesn't take much HTML and CSS for there to be quite a lot going on. What we can do it to build the layout up piece by piece.
AAAA
This text is placed in a anonymous inline box. This goes in a line box, preceded by a zero-width inline box that's the height of the container element's font, called the strut. The strut and the AAAA text are vertically aligned with each other with respect to each others baseline. So already, we have
<img class='img1' src='...' />
The vertical-align of the .img1 element is the default which is baseline, and images are replaced inline elements, so the baseline of the image is its bottom margin edge. .img1 has no margins, border or padding, so that makes it the bottom edge of the image itself, so now, if we assume that the image is taller than the font, we have
Note that the line box is now taller than previously to accommodate the image. In fact the line box is taller than any of its component parts.
<img class='img2' src='...' /> part one
We'll skip the second image for the moment and come back to it later. We'll just leave a placeholder for now.
<span>BBBB</span>
Exactly as AAAA, except that here the inline box is formed from a real element rather than being anonymous. This gives us
CCCC<img src='...' />DDDD
This is exactly like AAAA<img src='...' />BBBB`. Nothing new to add here.
<p>CC...DD</p>
The p element is set to inline-block, which means that its line-height contribution to the line it is in is its margin box. It has default margins from the user agent stylesheet of (typically) 1em top and bottom. It too is aligned to the other elements on the line using its baseline. So now we have
Again the line box grows in height, this time to accommodate the p element's margin box.
<img class='img2' src='...' /> part two
Now we can fill in the placeholder we left earlier for .img2. This image is vertical align:top, so it doesn't align with the other elements, but with the top of the line box. So that gives us
.tableau { display:table-cell; vertical-align:top; }
Then the whole thing is wrapped up as one and positioned at the top of the table-cell.
Wrap up
Finally, we need to account for why "AAAA" appears at the top in your picture and not aligned to the other text as depicted in my answer above. This seems to be because you captured the picture from Chrome, and was therefore subjected to Chrome's screwy vertical-align implementation. Firefox and IE display the layout correctly.

With your vertial-align: top You mean about effect like here: http://jsfiddle.net/bdoq99a2/1/
I've simply changed this:
.tableau *{
display: inline;
}
Image: http://take.ms/BxlzD

The problem comes from the browser stylesheet, in this case the default margin for paragraphs. No need to fuss around with display: table-cell and vertical-align: top. Just check the fiddle: http://jsfiddle.net/bdoq99a2/2/
.tableau {
border:1px solid black;
}
.tableau p {
display: inline-block;
margin: 0;
}
<div class='tableau'>
AAAA<img class='img1' src='http://lorempixel.com/400/200/' />
<img class='img3' src='http://lorempixel.com/300/200/' />
<span>BBBB</span>
<p>CCCC<img src='http://lorempixel.com/300/200/' />DDDD</p>
</div>

Related

positioning an image next to a menu bar with html/css

I am very new to html and css. I am trying to build my first website. I would like to have a picture on the same line as a nav bar, with the picture to the left. I first tried using some prewritten code for a drop down nav bar, but I was unable to position an image to the left of it. I tried some very basic code, but I still cannot figure our how to put a div (my image) next to a nav. I don't quite know when to use position and when to use float. My goal is simple to start. Get a div and nav to sit side-by side. Here is the html I am using to test:
<!DOCTYPE html>
<html>
<head>
<title>
Nav and div
</title>
<link rel="stylesheet" type="text/css" href="styleside.css">
</head>
<body>
<div>
<img src="images/basil.jpg" alt="picture here" height="20%" width="20%">
</div>
<nav>
<ul>
<li>Home</li>
<li>Big Friendly Button</li>
<li>TARDIS</li>
</ul>
</nav>
</body>
</html>
Can Anyone point me to a starting place for how to move these elements around? Thank you!
<sytle> // Put this in css
.anynames{ // this css is for position an image to the left
position:relative;
float:left;
}
</sytle>
<div id="anynames"> //<---- Id this use to indicate specific DIV
<img src="images/basil.jpg" alt="picture here" height="20%" width="20%" />
</div>
If this is correct Mark it if this is not We Finds ways :D
There are two common methods of forcing two block (commonly div) elements to sit beside each other.
Floats
Floats are used to force elements to strictly align along the left or right of a page. However, they are also useful for placing two block elements beside one another:
div.image {
float: left;
}
nav {
float: left;
}
See this Fiddle
One key advantage floating elements over inline blocks is that floating elements don't have a default margin to space text (see Inline blocks section).
You can also change the code under nav to float: right; which will separate the image and nav on separate sides of the screen.
Inline blocks
Inline blocks are often used to display block elements inside a paragraph. But since two inline elements are placed beside each other given enough room, we can use these to position blocks horizontally:
div.image {
display: inline-block;
}
nav {
display: inline-block;
}
And the Fiddle.
In the Fiddle I've colored the nav red to show the space in between the two elements. If you did the same for the floating elements, you'll see no space between the image and the nav. However, here there is a small margin caused by the default spacing given to inline-block elements - the browser wants to put space between an inline element and the surrounding text. To get rid of the space, you must add
body {
font-size: 0;
}
nav {
font-size: 12pt;
}
Why would you want no spacing? We often want widths described in percentages. However, if you were to keep the spacing while specifying percentages that add up to 100%, the second element would spill over onto the next line because we didn't take the extra spacing into account: see this Fiddle.
Your two elements div and nav need to be formated in CSS. Like this:
<style>
.myDiv{
display:inline-block;
width:50%;
}
nav{
display:inline-block;
width:50%;
}
</style>
You must enter in a class for div to understand this code
<div class="myDiv">
The code inline-block will allow elements that are smaller then the remaining width of the page to be stacked beside it.
Hope this helps!

Flowing text with minimum column width around floated image

I would like a way to prevent columns of flowing text from becoming too narrow. For example, in a column of HTML text, there is an image floated to the left. Text flows down the right-hand side of the column around the image, as expected:
However, if the image is almost as wide as the column, then the text ends up being very narrow:
In this case I want the text to simply not flow past the image, but to drop below it as if the image were a block:
I am trying to find a simple and general way of doing this. It's for a blog - I want to be able to add the image and text, maybe add a class or paste in a bit of markup (sigh), and have the flow work. I would prefer to do it with CSS and HTML only because it's hard to insert JavaScript to the blog posts. I have a couple of methods (see my answers) but neither is satisfactory. Can you do better?
When you set display: inline-block; to an element, the element will be flowed with surrounding content.
So you would need to add a line-break <br> to produce a line break in text, but the vertical space of the line will remains as you mentioned. [and one more thing happens is the horizontal scroll-bar which will appear if you decrease the width of the panel.]
Introduction
Using <table></table> element has a lot of benefits here.
When you use <table> element (as the following), it causes the content goes to the next line. And when the remain horizontal space gets lower than width of the <table>, it'll go to the next line and push the content down.
And also, horizontally scroll-bar won't appear in this case, because browsers won't display the <table> when it hasn't any element inside or any specific height or border properties.
(different browsers have different behavior, Mozilla Firefox doesn't display table element with a specific border property but Google Chrome does.)
HTML:
<img src="http://placehold.it/100x50" alt="">
<table></table>
Lorem ipsum dolor sit amet...
CSS:
img { float: left; }
table { width: 12em; }
Here is the JSBin Demo.
The Solution
As a pure CSS way, I used ::before pseudo-element to create a element which behaves like the <table> HTML element.
HTML:
<div>
<img src="http://placehold.it/400x400" alt="">
<p class="content">
<!-- Here is the content... -->
</p>
</div>
CSS:
img { float: left; }
.content:before {
content: ' ';
display: table;
width: 10em; /* <-- Change the current width size */
}
Here is the JSBin demo.
A better solution is to give every paragraph an invisible CSS pseudo-element with the desired minimum paragraph width. If there isn't enough space to fit this pseudo-element, then it will be pushed down underneath the image, taking the paragraph with it.
If the img is flot: right, add clear: left to the p:before.
And if the img is float: left, add clear: right to the p:before
p:before {
content: "";
width: 10em;
display: block;
overflow: hidden;
clear: left; //use clear:right if img is float:left
}
I tried adding an extra element before the text. I think this would probably just about work. Something like this:
<style>
.shim { display: inline-block; height: 0; width: 12em; }
</style>
<img class="floated">
<div class="shim"></div><br>
If one examines Derridaist reading...
This is OK - if the flow column is narrow then the shim drops below the image and the text follows it. I have to add the <br> to stop the text being indented by 12 ems, which adds a line of vertical space. I guess I could reduce the line-height on the <br>but the whole thing might end up being a bit verbose.
The simplest method I found is to set the minimum width of the column by preventing the first few words from wrapping:
<style>
.chunk { white-space: nowrap; }
</style>
<p><span class="chunk">If one examines</span> Derridaist reading...
This works well, but:
I have to manually edit the text each time I do this
I can't precisely control the column width (in ems or pixels)

Why does this css/html display extra padding?

For the past few days, I've been struggling with some odd spacing on a website I'm building. Originally, I thought it was a display issue with Chrome, but I've been able to duplicate the problem in IE8, IE9, Firefox and Safari. I'm using old school HTML/CSS for backwards compatibility, so I can say it's not IE handling of HTML5 or some other bleeding edge update.
While some of the solutions on line have led me to try different things including floating the hedad, nothing's been successful & I always have padding on one of the long sides.
I have stripped this down to the BAREST of essentials to reproduce the problem, and have included a screen shot of the padding I can see on my end. I would certianly appreciate another set or seven of eyes showing me what I missed.
EDIT: line height turned out to the the culprit on this one, but vertically aligning the image to top per suggestion left the text at the top of the div. My sense would be that the header tag would preserve the default value, but that the and the img tag within the header would override that. Or can I only have one vertical align per div?
Second, is there a way to collapse line-height with CSS?
HTML CODE
<html>
<head>
<title>Test</title>
<LINK rel="stylesheet" href="test.css">
</head>
<body>
<div id="header">
<img src="bluespacer.gif" height=125 width=400>
TEST
</div>
</body>
</html>
CSS CODE
#header {
font: serif;
color: blue;
background-color: gray;
}
My output looks like below
and here's the bluespacer.gif; 1px x 1px. Look close, it's like a dust speck!
( ) <---
You're looking at the wrong spot. It's not padding but line-height, that generates that white space.
Try to vertically align the image:
#header img {
vertical-align: bottom;
}
Explanation: In the default style, the image is placed on the baseline of text. That is, the lower edge aligns roughly with the lower edge of, say, the letter 'x'. But because text has descenders (like 'g' or 'j'), the surrounding box is drawn higher, which leads to the extra space below the image.
It's a weird issue. You can do this.
#header img { line-height: 0; }
#header img {
display: block;
}

Image caption width to same as image

How can I make image caption width same as image? Now I have the following code:
<div class="image">
<img src="foo.jpg" alt="" />
<div>This is the caption.</div>
</div>
I've tried a lot of things (floating, absolute positioning etc), but if the caption is long, it always makes the div wide instead of going on many lines. The problem is that I don't know the width of image (or the length of caption). Is the only way to solve this use tables?
So the problem is that you don't know how wide the img will be, and the caption for the img may exceed the width of the img, in which case you want to restrict the width of the caption to the width of the img.
In my case, I applied display:table on the parent element, and applied display:table-caption and caption-side:bottom on the caption element like this:
<div class="image" style="display:table;">
<img src="foo.jpg" alt="" />
<div style="display:table-caption;caption-side:bottom;">This is the caption.</div>
</div>
You can apply display:table; and an arbitrary initial width, eg. width:7px; to the parent block like figure and everything will work as expected!
Here is a live demo:
http://jsfiddle.net/blaker/8snwd/
This solution's limitation is that IE 7 and earlier do not support display:table; and IE 8 requires your doctype to be !DOCTYPE.
Sources:
http://www.lifeathighroad.com/web-development/forcing-to-wraps-to-the-width-of-an-image-using-css-only/
W3Schools (can't post link due to stackoverflow's 2-link limit for people with less than 10 rep)
If the problem is the caption being too long, you can always use
div.image {
width: 200px; /* the width you want */
max-width: 200px; /* same as above */
}
div.image div {
width: 100%;
}
And the caption will stay static. Also, the tag name is img, not image.
Or, if you want to detect your image width, you can use jQuery:
$(document).ready(function() {
var imgWidth = $('.image img').width();
$('.image div').css({width: imgWidth});
});
That way, you're getting the image width, then you set the caption width to it.
The only way to do captioning properly is to enclose the image and caption in a table constructed from span elements with table, table-row and table-cell css attributes.
Any other method (including HTML5 figure tags) either gives width mismatches or causes unwanted line breaks.
If your method must work in a non-css3 browser, then a table is probably the best bet.
You could try to set the image div wrapper display:inline-block
http://jsfiddle.net/steweb/98Xvr/
If the caption is long, the only solution will be to set a fixed width, or set the .image div width by js. I'm trying to think about a pure css solution, but I think it's an hard challenge :)
The key is to treat the image as having a certain width some length. In the example below I checked and my image was 200px wide. And then treat the caption as an inline-block.
HTML:
<div style="width:200px;">
<img src="anImage.png" alt="Image description"/>
<div class="caption">This can be as long as you want.</div>
</div>
CSS:
.caption {
display: inline-block;
}
You can also replace the inline-block with text that is left justified, right, or stretched over the exact image width by replacing above css with one of the following:
.caption {
/* text-align: left; */
/* text-align: right; */
text-align: justify;
}

Should I use a table for this?

Unluckily I don't know what to do :(
I want to align the text "bla bla...." at the bottom of the left div.
Setting it as position:absolute & bottom=0 doesnt work always because there are cases where image does not exist, and that would be a problem as if the text wont increase container div height...
I could change the layout if there is no img with php but that doesnt guarantee that in case img has less height than text, text overflow etc...
I know this is strange, the table is the only solution I have?
A table is rarely (if at all) a good solution for layout.
You could do a min-height so if the img does not exist, you will always have a height that will be adhered to.
You can use display:table-cell.
http://jsfiddle.net/JeaffreyGilbert/32NWh/
<style type="text/css">
div#leftContent { float : left; position : relative;}
div#rightContent { float : right; position : relative;}
.bottom { position : absolute; bottom : 0; }
</style>
This is a rough Stylesheet emulating your skeleton; combined with something like...
<div id="leftContent">
<p class="bottom">Your text, as a 'p' element--but it could be any element.</p>
</div>
<div id="rightContent">
<img src="" />
</div>
Your <p> element (or any element for that matter) would be positioned at the bottom of the left div, wherein you could change the padding/positioning to whatever you'd like; this still allows you to style the image in the adjacent div anyway you'd like.