How do I align these links inside inline-blocks to the top? - html

I'm having a little CSS problem with a list of thumbnails. Here's an example:
http://jsfiddle.net/22hs8/
The problem is that when the link is too long to fit in the 150px block it will push the image down. By using inline-block on the list elements instead of a float I could get the images to line up properly, but now I want to have the links at the same height as well.
One thing I tried is making the links itself a block (or surrounding it by a div) and giving that a height, but that would mean they are always the same height even if none of the links uses two rules. Also, if a link is so long it uses three lines the same problem would occur.
In short: how do I align the links to the top of the list items, without breaking the image alignment?

To address one issue, you can add vertical-align:top; to the <li> tag in order to align the content to the top of the element, but unfortunately, I don't believe there's a way to resolve the issue entirely without also implementing one of the following methods:
Placing all of the tags in a separate
Specifying a height on the tags
Using javascript to equalize heights
Options
1. Separate Div
By moving the anchor tags into a separate div, they could be given the same width as the images and floated or displayed inline accordingly, but your markup becomes less semantic when you separate the anchor from the content (and may also be programmatically more complex if these are being dynamically generated).
2. Specifying a Height
This option can be thrown out almost immediately because, as you've stated, the anchor lengths can fluctuate to multiple lines. You could specify the height the the largest know line length, but then you'll ultimately end up with unnecessary white space with groups of short links.
3. JavaScript (jQuery)
While It would be ideal to resolve this issue without the requirement of JavaScript, I think it may be the only option that would allow you to preserve the semantics of your markup, and also apply an equal height to each of the anchor tags.
Recommended Solution
I would recommend setting a default height on the anchors of the largest known line length, then applying a bit of jQuery to normalize the heights of the anchors. This way, if the JavaScript parsing fails or JavaScript is disabled, the user still sees a uniform layout (albeit with potentially more whitespace), and with JavaScript active the heights are normalized.
Apply vertical-align:top; to the <li>
Define default height for non-js users
Equalize heights using jQuery:
(function(){
$.fn.equalizeHeights = function(){
return this.height( Math.max.apply(this, $(this).map(function(i,e){ return $(e).height() }).get() ))
}
$(function(){ $('li a').equalizeHeights(); });
})();
Example: http://jsfiddle.net/Eg7hy/

How is this:
http://jsfiddle.net/22hs8/3/

So you're saying that you want the links to not push the content down? I don't see that as being possible unless you don't allow your content to stretch at all. It's natural flow of a page for something above content to force the content down after it if it needs more space.
Have you thought about chopping off the text after a certain number of characters, with a '...' and providing the full text through a title, and providing the full text through a popup (since I assume you're creating some kind of photo gallery)?

The first answer that came to mind was:
"just use a table, it makes this really easy, and works everywhere"
Live Demo
However, I would probably get down voted into oblivion if I posted an answer only containing a <table> tag version, so here's a version using CSS display: table and friends:
Live Demo
Of course, that won't work in IE7 because that browser doesn't support display: table.
I can't think of a way to do this using code closer to your original and display: inline-block, which would also support an arbitrary number of lines. I'd love to see a better way to do this.
HTML:
<div id="container">
<div class="row">
<div class="cell">Some text</div>
<div class="cell">Some more text (too long)</div>
<div class="cell">Some text</div>
<div class="cell">Some text (seriously too long) text text text text text text text text text text text text text</div>
</div>
<div class="row">
<div class="cell"><div class="image">image</div></div>
<div class="cell"><div class="image">image</div></div>
<div class="cell"><div class="image">image</div></div>
<div class="cell"><div class="image">image</div></div>
</div>
</div>
(you could change some of those div tags into ul and li if you wanted to)
CSS:
#container {
display: table
}
.row {
display: table-row;
text-align: center
}
.cell {
display: table-cell;
width: 150px
}
.image {
width: 150px;
height: 150px;
background: grey
}

Add vertical-align:top; to the images.

Related

Change the way the text is display on screen with html and css

I am setting up a simple blog website and need help formatting the posts that are submitted to the front page of the site.
You can achieve this in multiple ways. Maybe the easiest way is to put your text in a container and give this a width. The text will wrap itself.
<div class="text">Your text here</div>
and your CSS. If you want to break within the word you can use word-wrap:break-word;.
.text {
width: 100px;
}
You have many options for this. simple one put you text in a <div> tag and give width to div as much you like.
<div style="width:100px">"Hello, this is my first post. As you can see, it wraps all the way around the text box and into another line."</div>
You should add a word-wrap css property and set it to break-word. This forces the text to wrap inside a container.
.container {
word-wrap: break-word;
}

How do I vertically align text next to img in Genesis columns?

I've researched similar questions and tried using display:table-cell; inline-block; vertical-align:middle all over the place, but I can't get this to work. In this sample Genesis theme page (please look), it demos the use of columns using 'one-half' and 'first' CSS classes. Using DevTools/Inspector you can go in and add <img src="http://placehold.it/140x240"> before the paragraph like I've shown below. Maybe there's something in the Genesis columns that's making this harder than it should be, or more likely I'm missing the obvious.
In that first column I need the img to appear to the left of the text, while the text is vertically aligned. I can't seem to find out the combination that will do it. NB I do know the height of the image - it's not dynamic. I could use spans if easier in stead of P.
<h3>Two-Columns</h3>
<div class="one-half first">
<img src="http://placehold.it/140x240">
<p>This is an example of a WordPress post, you could edit this to put information about yourself or your site so readers know where you are coming from. You can create as many posts as you like in order to share with your readers what exactly is on your mind.</p>
</div>
The key here is declaration of the widths. p by default will have 100% width even if you set the display to inline-block, so you need to set it up with something like this:
<h3>Two-Columns</h3>
<div class="one-half first">
<img src="http://placehold.it/140x240" class="OneHalfItem"><p class="OneHalfItem OneHalfText">
This is an example of a WordPress post, you could edit this to put information about yourself or your site so readers know where you are coming from. You can create as many posts as you like in order to share with your readers what exactly is on your mind.
</p>
</div>
Note the classes added to the children, with the CSS now applied:
.OneHalfItem {
display:inline-block;
vertical-align:middle;
box-sizing:border-box;
}
.OneHalfText {
width:calc(100% - 140px);
padding:10px;
}
Now it lines up nice and dandy, with the use of calc. Couple of things:
This works easily because the picture is a fixed width; if the imgsize is variable, you need to declare it's width as well (a percentage or something), then calculate the p size based on that
I eliminated the white space between the end of the img tag and the beginning of the p tag, because by default inline-block will add in a 4px margin to the right of each element. By removing the white space between the tags, it eliminates that empty margin.
Note that this will only work for IE9+ (and real browsers, of course), so if you need to support IE8- then you'll need to do the same kind of width calculation via JS, but easily done.
Here is a jsFiddle to show it working.

Why is there a gap between the img tags?

html
<div id="home_header_minitab">
<img src="topnavi_1.gif" />
<img src="topnavi_2.gif" />
<img src="topnavi_3.gif" />
<img src="topnavi_4.gif" />
</div>
css
#home_header_minitab{
width: 100%;
float: right;
text-align: right;
}
and the result,
If i delete float and text-align, it prints fine. but if i add that two, it shows like that. but the requirement is to locate the images to the right side. :(
If I'm wrong, I'll appreciate if there is a better way to print images straight forward.
Replaced inline elements are treated in the same way as characters.
There is a space between <img> <img> for the same reason that there is a space between a a.
Remove the whitespace between the elements from the HTML.
Unless otherwise specified, whitespace in HTML is usually collapsed into a single space. So in your code there is actually a space between the images.
Now, because img tags are inline elements, they are part of the normal text flow and as such will appear as if they are text elements themselves—separated by a space. That space will be rendered as a normal space with its normal size between the images which is why you see it.
There are usually two ways to solve this without replacing the inline layout by your own (e.g. using floats). The first way is to simply get rid of any whitespace between the elements in HTML. This is the easiest and most effective solution.
The other solution would be to change the font size to zero, so the space actually has no size itself:
#home_header_minitab {
font-size: 0;
}
Note that you need to be careful here in case you want to actually display text, or if you want a fallback to the alternative image titles.

Attach font icon to last word in text string and prevent from wrapping

I want to attach a Font Awesome icon to the last word in a text string:
foo bar●
But if a line wrap is required, I want the icon to attach to the last word and have them wrap together:
foo
bar●
My problem is very similar to:
Prevent :after element from wrapping to next line
However, the solution assumes I have access to the last word. In my case, the text will be generated dynamically. Is there a css/html-only way to ensure the icon wraps with the last word?
Here's a jsfiddle.
I just wanted to point out why the change that #Unmocked provided actually works, and it has to do with the difference between display: inline and display: inline-block.
To explain, here's a little background on the difference between block display and inline display.
Block Display
block elements, in general, are elements which cause layout. They receive their own bounding box, and have the ability to push other elements around to some degree in order to fit into the space available within the browser's rendering area. Examples of block items include: h1, p, ul, and table. Note that each of these items, by default, starts a new line and also ends its own line when closed. In other words - they fit into a block of text by creating their own paragraph-level section.
Inline Display
inline elements, in general, are displayed in-line with the text. In other words, they are designed to display with-in the line of text. Examples include i, b, or span. Note that each of these items, by default, continues with the flow of its surrounding text, without forcing a newline before or after itself.
Enter the mid-way case...
Inline-Block Display
inline-block is a hybrid of the above two. In essence, an inline-block element starts wherever its preceding text leaves off, and attempts to fit into the flow of the document inline. However, if it reaches a point where it needs to wrap, it will drop to a new line, as if it were a block element. Subsequent text will then continue immediately following the inline-block element, and continue wrapping as normal. This can lead to some strange situations.
Here is an example, to show what I mean. To see it in action, check out this cssdesk snippet.
In your example, you were setting the :after pseudo-element to be display: inline-block - which meant that when it happened to extend past the right-most boundary of the wrapping display, it acted like the light-blue text in the example - and wrapped, as a block. When you instead change the :after element to display: inline, it causes it to act just like any other text - and without whitespace between it and the preceding letters, the word-wrap acts as you wanted it to.
I hope this helps!
Note: The other thing which changed between your original fiddle and the updated one is the elimination of white-space around the text.
In the first fiddle, your HTML looks like:
<div class="container2">
foo bar
</div>
While the browser doesn't display the spaces before and after the text, it does contain the spaces, and when the :after element is rendered, it is as if this is happening:
<div class="container2"> foo bar :after</div>
The browser compresses the multiple spaces into single spaces, but still puts a space between the word "bar" and the :after element. Just like a space between any other words, this will cause the wrap to occur after "bar" but before :after at a certain width.
In the second fiddle, you are using:
<div class="container-wide">foo bar</div>
<div class="container-narrow">foo bar</div>
In this case, because there are no spaces trailing the "foo bar" strings, the browser renders the :after element displayed immediately following the end of the content string. It is as if this is happening:
<div class="container-narrow">foo bar:after</div>
No break in inline-rendered text means no break.
For an example demonstrating this, please see this update to your jsFiddle.
Interestingly enough, I found you only need to change one line of code for this to work.
Testing on your .container2 element in jsFiddle, change this
.container2:after {
font-family: FontAwesome;
content: "\f111";
display: inline-block;
}
to
.container2:after {
font-family: FontAwesome;
content: "\f111";
display: inline;
}
It seems to work with any width I set the container to and will stay connected to what ever foo will be.
You can use negative margin the width of the icon and css transform. Here a fiddle how to do :
.container {
width: 50px;
}
.icon-circle {
background:black;
height:10px;
width:10px;
display: inline-block;
margin-left:5px;
}
.ANSWER{
display:block;
padding-right:15px; /* width of the icon */
}
.ANSWER .icon-circle{
margin-left:-10px;
transform:translate(15px);
}
<h4>What we want</h4>
<div class="this-is-how-it-should-wrap">
foo bar<i class="icon-circle"></i>
</div>
<div style="margin-top:25px"></div>
<h4>What happenned</h4>
<div class="container NORMAL">
foo bar<i class="icon-circle"></i>
</div>
<div style="margin-top:25px"></div>
<h3>The answer</h3>
<div class="container ANSWER">
foo bar<i class="icon-circle"></i>
</div>
Have a nice day!

CSS: Force text to wrap (OR defining element width by only one of its children)

Okay, this is a weird one to me. Here's the HTML element I'm working with:
LOLZ http://www.ubuntu-pics.de/bild/14571/screenshot_030_0O2o3D.png
A photo with a caption. Ideally, I'd like it to look like this, through pure CSS:
alt text http://www.ubuntu-pics.de/bild/14572/screenshot_031_mp84u7.png
The width of the image's parent element needs to be dependent on the image's size.
I can change the markup all I need to. (The text isn't currently in its own div, but it can be if necessary.) Is there any way in CSS to accomplish this? I get the impression that I need to "force" the text to wrap as much as possible (which doesn't seem achievable), or make the whole element's width dependent on just one element and ignore the other (which I've never heard of before).
Is there a real way? Or do I need to use magical Javascript instead? (The JS solution is fairly simple, but fairly lame...)
Check out this great article on the best ways of handling the image-with-a-caption scenario.
Personally this is one of those cases where you gotta suck it up and go with that works.
Make the container a table with table-layout:fixed and put the image in the top row. You can also do this with pure CSS using the display:table-* properties (and the IE7-js library for IE6 compatibility).
What table-layout:fixed does is make the table drawing algorithm lock the width of each table column once the width of the first cell in that column is known. The caption will have nowhere to expand to so it will wrap to the width of the image (the first cell).
Alright, it looks like there's no simple solution that I can pull off. Thanks for helping me work that out :)
I think that, given how I'll be storing those images, accessing width won't involve constant recalculation. I may just use that server-side magic instead.
Thanks!
Here's a solution that probably does not work for you even though it does produce the layout you requested:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<style>
div.a {float: left;
position:relative;}
div.b {
position: absolute;
top: 100%;
left: 0;
right: 0;
text-align: center;
background-color:gray;}
</style>
</head>
<body>
<div class="a">
<img src="http://stackoverflow.com/content/img/so/logo.png" alt="">
<div class="b">Caption text Caption text Caption text Caption text Caption text </div>
</div>
</body>
</html>
You see the reason why it is unsatisfactory if you place some content below the div a. It will overlap with the caption, because the absolutely positioned caption did not extend the parent div vertically. It still may work for you if you have enough white space below anyway or you are willing to reserve it.
I came up with a working and fairly clean solution.
The solution uses a table (or div with display:table if you prefer) and adds a second column to "push" the first cell into the minimum space it really needs. The table can be set to 1px width to stop it growing across the page. I've put together a demo to show this in action:
http://test.dev.arc.net.au/caption-layout.html
Tested and working in IE8, Firefox and Safari/Win
The table answer would work. Easily. I can't encourage its use but ease-of-use does have merit. I was going to suggest using the clip: CSS property, but I can't get it to work on my local machine (for some reason, though it renders the example at cssplay.co.uk perfectly).
The downside of this is that it probably only works if you define fixed-widths for the containers. I'm sure there must be a way, though. I'll keep looking.