Image caption width to same as image - html

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;
}

Related

Force CSS to square image in a responsive container

I have a responsive image grid background in my website.
All its working fine with perfectly square images but when one image is for example 1px height bigger, the grid breaks.
Example OK:
[H][H][H][H][H][H]
[H][H][H][H][H][H]
[H][H][H][H][H][H]
Example FAIL
[H][H][H][H][H][H]
[H][H][H][A][H][H]
[H][H]
[H][H][H][H][H][H]
I dont want to use mansory o other plugins, this is my code:
HTML
<div class="resp pull-left">
<img class="img-responsive indexUser" src="image.jpg">
</div>
CSS
.resp{
width:10%;
height:10%;
}
.resp img{
width:100%;
}
Im using Bootstrap 3. Is it possible to do it?
EDIT WITH MORE INFORMATION
I want to put only square pictures in order, sorry, without grid. The image containers are floating. This is the screenshot with the problem:
Is responsive and I need to use % in with to adjust perfectly fullscreen allways
There are two things you can try here that might answer your question. Of course, without seeing your code it's very hard to advise in a more in-depth fashion.
If you're using Boostratp, why not wrap each row of images in a row-fluid container and use it's grid system? This will at least ensure that you don't get the dirty float bug, although it also means that you'll get a little extra space underneath the child elements of that one taller one.
Or, set the parent anchor's height and set overflow: hidden. This will essentially cut off the bottom edge of the taller image, although you would have to work through your break points.
As a code example of point two above:
.resp a{
display: block;
max-height: 300px;
overflow: hidden;
}
Bear in mind that images in Bootstrap have max-width: 100% set to them automatically so they will always flow to the width of the container if wide enough.
You will probably need to provide a height and maybe even set overflow:hidden. Please provide more markup if you want a better answer.
This is one linked image in a div, not a grid:
<div class="resp pull-left">
<img class="img-responsive indexUser" src="image.jpg">
</div>
<figure><img src="images/edu.jpg"></figure>
figure img {
width: 100%;
}

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)

Some doubts about how make an image clickable using CSS

I am studying on a tutorial how to create a tabless web template using HTML + CSS and I have a little doubt related to the following thing:
I have an header that contains a div having id=logo, something like this:
<div id="header"> <!-- HEADER -->
<div id="logo"> <!-- My Logo -->
<h1>My web site is cool</h1>
<p id="slogan">
My web site is finally online
</p>
</div>
......
OTHER HEADER STUFF
......
</div> <!-- Close header -->
And related to this #header div (and its content) I have the following CSS code:
/* For the image replacement of the logo */
h1 {
background: url(../images/logo.jpg) no-repeat;
text-indent: -9999px;
width: 224px;
height: 71px;
}
h1 a {
display: block;
width: 258px;
height: 64px;
text-decoration: none;
}
So this code put an image instead of the My web site is cool text that is in the tag.
I have some problem to understand the h1 a CSS settings, on the tutorial say that this CSS settings for h1 a:
Turns to block (from inline) the display mode of the link in the header, so I can set the width and height, and the image of the logo is now clickable
This thing is not very clear for me and I have the following doubts:
Have I to convert the a element (that is inline) into a block element to give it the same dimension of the underlying image (logo.jpg)?
Tnx
Andrea
Take this example,
an a element is inline by default, so if you were to do something like
CSS
a {background:red; height:210px; width:200px;}
HTML
test
You will notice that the width and height properties aren't working. Now for this element to be sized at that width, you need to set the element's display property to be either display:block or display:inline-block
JSFiddle Demo Example
HTML:
Without display:inline block, width and height set.
<br><br>
With display:inline block, width and height set.
<br><br>
With display:block, width and height set.
CSS:
a {background:#ccc; height:210px; width:200px;}
.inline-block { display:inline-block; }
.block { display:block; }
If you're linking an image, you don't need to give the a height/width or even a display:block. However, you really shouldn't be putting an image inside an h1 like that. You'd be better off making the a inside the h1 a block (using display:block) and setting the background to the image, then hiding the text. To the user of the site, there's not going to be much difference, but it removes images from your HTML code, makes it easier for screen readers, and is more semantically correct. So your code would be:
a { display: block; font-size:0; background-image:url("logo.png"); height:100; width:100 }

What is the best way to create space in an HTML/CSS document?

I have a div in which there are rows of 3 images each. The images are all the same size. I had been using small completely clear transparent image which I would then explicitly give height and width to form spaces between the images. An example would be something like :
div begin
space image width=15, height=1 actual image (no explicit dimensions)
space image width=10, height=1 actual image (no explicit dimensions)
space image width=10, height=1 actual image (no explicit dimensions)
space image width=900, height=20 (this is to separate rows, which should be 900 wide, space + 3 x image)
space image width=15, height=1 actual image (no explicit dimensions)
space image width=10, height=1 actual image (no explicit dimensions)
space image width=10, height=1 actual image (no explicit dimensions)
div end
These rows may or may not be generated via code and there are sometimes hrefs. I realize that I could perhaps use margins/padding on the image/or anchor element to create space. But this would require setting a class on each image. That does not seem like a good way to go about this. For a few reasons : the space would be inside the anchor tags, making it linkable. I would not be opposed to using divs and using specific classes on those. I have tried this however, and they do not seem to work as I would expect. They create line breaks, so now the images appear in a column, and they don't seem to take up any actual space anyway.
How about 2 divs, one for each row. Then set the margins on those.
<div class="row"> Your images or anchor tags</div>
<div class="row"> Your images or anchor tags</div>
Then
.row{
margin-top:10px;
}
or however much space you want between rows of images.
You may use divs for the images in order to position them on the screen better. Especially wanting to avoid adding a margin to an anchor tag.
div.img{
display:inline;
}
.firstcol{
margin-left:15px;
}
.col{
margin-left:10px;
}
and
<div class="img firstcol">The first image of teh row</div>
<div class="img col">The second image of teh row</div>
etc.
Using spacer images is rather clumsy and hardly ever needed. The simplest approach is probably to wrap all images inside a elements, using just <a><img ...></a> for those that aren’t meant to be links. Then you can set margin on the a element, without making the margin clickable.
You can also format the image gallery in rows of three images without making such division part of the HTML code. Example:
.gallery img { border: 0; margin-bottom: 20px; }
.gallery a:nth-child(3n+1) { margin-left: 15px; }
.gallery a:nth-child(3n+2) { margin-left: 10px; margin-right: 10px; }
.gallery a:nth-child(3n+3):after { content: "\A"; white-space: pre; }
This effectively makes the layout table-like, without hard-coding the division into columns in HTML. The last rule is a bit tricky (but valid) way of causing a line break after every 3rd element.
jsfiddle
P.S. This creates a 20px margin below the last row of images, too. If this is an issue, you can nullify it by setting .gallery { margin-bottom: -20px }.
This is what I have gotten to work :
.row {
margin-left:20px;
}
.space {
margin-left:12px;
display: inline;
}
.row-space {
margin-bottom:20px;
}
div class=row
a href=x img
div class=space /div
a href=x img
div class=space /div
/div
div class=row-space /div
I needed the display-inline to avoid a line break. I had read and have used float: left, in the past, but this has some other side effects which are not good for this purpose.

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.