How can I prevent HTML text orphans? - css

I often have an image that I wrap text around, and sometimes the texts wraps awkwardly, like so:
In the HTML, the image is floated to the left and the text simply follows:
<p><img style="float:left;" src="/images/[image]" /></p>
<p>This is my David Copperfield, <em>I was born</em> kind of bio.  For a more concise one, please see the press kit.</p>
...
This mostly works, except when the text length just happens to run past the bottom of the image and flow back to the left margin, and when the amount of text isn't long enough to fill more than one line (in this case, it's only one word). When that happens, it looks really bad.
So, is there a way to control the text flow so that this doesn't happen?

What you could do is add overflow: hidden to the p tags where there is text. This will make it so any text that wraps after the image will be in line with the larger part. Now when you have large paragraphs this may look funny, however if your paragraphs are all fairly short this should help.
Example: http://jsfiddle.net/8ZsKy/2/
alternately you could just add a class rule and apply it to potential "problem" paragraphs.
p.wrap-inline {
overflow:hidden;
}
EDIT: updated jsfiddle (oops)

This question actually had me thinking although it is actually annoying sometimes, In the past i have fixed similar problems to this by adjusting the line height a little,
line-height:20px;
or adjusting the actual size of the image a little bigger or smaller,
<img style="float:left;" src="/images/[image]" width="100" height="200" />
or alter the tracking of the text
letter-spacing: 0.1em;
or use hyphenation (I don't like it or recommend it)
hyphens: auto;
However as far as my knowledge goes i do not know of any css rules to eliminate text orphans. There might be scripts but i have never heard of it and have doen a bit of research on it a while back. Hope it helped :)

This is how floating works. If you don’t want that, don’t use float; you can e.g. use positioning instead, so that the text appears as a block on the right of the image.
There’s unfortunately no way to use floating and request e.g. that the last line should not be short. You can prevent the very last word from appearing on a line of its own by using a no-break space between it and the preceding word, e.g. it will. And you could extend this to a group of short words. But this would just mean that the group appears on a line of its own and the preceding line is correspondingly shorter (and may therefore look odd).
If the text is just a little too long, you could modify its rendering to take less space vertically e.g. by removing empty lines between paragraphs, though this would be a major layout change (though perhaps a good one):
p { margin: 0 }
p + p { text-indent: 1.3em; }

<img style="float:left; clear="both" src="/images/[image]" />

Related

Vertical Align Text to a Floated Image that is on the Left

Now I know there are similar questions posted, but I'm looking for a solution for pixel perfection.
Sandbox: http://jsfiddle.net/unqc4a0f/1/
Problem trying to solve:
Attempted code:
.mi{float:left; width:150px;height:200px;padding-right:10px;/*margin-top:3px;*/}
.mt{float:left; width:400px;margin:0;}
In the past I've used the padding/margin hacks to push the image or the text objects down a few pixels to make them visually align at the top edge. And by visually I mean that I know that the fonts have a size and line height, but even taking that into account, the height of the actual font characters may include some space. This you can see in my example above. I've also —based on other threads here —tried using line-height, and although that did achieve pixel perfect alignment, it mangled the the vertical line spacing of the entire paragraph.
My question essentially is whether to continue using the padding/margin hacks or is there a more 'legit' solution. I ask this in regards to building layouts that are responsive and then having no issues with uniform layouts.
Thanks in advance.
Realize it's an old question but...
In CSS one can use a ::before element add a negative margin-top value to it.
Specifically, I wanted to share this Interactive Text-Crop tool I found that helps create a SASS mixin for this purpose.
The gist in this tool is that you remove the capital height from the (font-size * line-height) and then divide by two. But that is a simplification of how your font may or may not be structured.
In reality - There is no "pixel-perfect" answer because when it comes down to it, the physical structure of fonts doesn't always match their font-size and different font-families at the same font-sizes can still look taller or shorter.
Instead of float use a display:table; layout for a perfect inline placement and vertical alignment.
It only requires that you wrap them within an element...
Updated JSFiddle
.wrapper {
display: table;
}
.mi{width:200px;height:200px;display: table-cell;}
.mt{display: table-cell;vertical-align:middle;}
<div class="wrapper">
<img src="http://www.thehollywoodnews.com/wp-content/uploads/2839335-morgan_freeman_wallpaper_4_normal.jpg" class="mi">
<p class="mt">Join me in San Diego at the Global Event for Data-Driven Engagement Marketers. DMA is doing great work to protect marketers around the world, come and hear from leading marketers how DMA is enabling them to NOT MARKET ALONE</p>
</div>
The space is supposed to be there it normally comes from line height which is something you need. If you font size is 14px and you reduce the linee-height to 11px you see the gap will vanish from the top, but the text will look very cramped..
Sometimes to get pixel perfect you have to just tweak like you have with the margin on the image..

CSS - Wrapping very last text to another line if it doesn't fit

I have a link at the very end of 4 paragraphs. Something like:
Here is my text, and it's just an example of text to show
And I am wanting to wrap the last bit of text, which happens
to be a link, but I need the link to either stay on the line
that is the available width and not break to another line,
unless it can't fit left-aligned on that line like this
http://mylink.com
So, the actual code for this would be as follows in HTML:
<p>Here is my text, and it's just an example of text to show
And I am wanting to wrap the last bit of text, which happens
to be a link, but I need the link to either stay on the line
that is the available width and not break to another line,
unless it can't fit left-aligned on that line like this<br />
http://mylink.com</p>
I am using <br /> here, but I don't want to use <br /> because the screen captures how much text actually shows and sometimes it could look like this:
Here is my text, and it's just an example of text to show And I am wanting to wrap
the last bit of text, which happens to be a link, but I need the link to either stay
on the line that is the available width and not break to another line, unless it can't
fit left-aligned on that line like this
http://mylink.com
So, in a situation like above, I would need it to not use a <br /> tag to break it up and it should render like this instead:
Here is my text, and it's just an example of text to show And I am wanting to wrap
the last bit of text, which happens to be a link, but I need the link to either stay
on the line that is the available width and not break to another line, unless it can't
fit left-aligned on that line like this http://mylink.com
Is this possible to do via CSS? Some text-align value perhaps, or something else in order to accomplish this without using <br /> tags at all? But if the link can fit on the line naturally, than it shouldn't move to the next line down. Instead it should stay on that line.
Thanks!
Some browsers interpret the slash in your URL as a character it is allowed to break your word on, while others will not. All you should need to do is adjust the white-space property of the link
http://jsfiddle.net/Msc4S/
a {
white-space: pre;
}
Use this html as you want:
<p>Here is my text, and it's just an example of text to show
And I am wanting to wrap the last bit of text, which happens
to be a link, but I need the link to either stay on the line
that is the available width and not break to another line,
unless it can't fit left-aligned on that line like this
http://mylink.com</p>
But add this into the CSS.
a {
display: block;
}
However this will make a on the new line everywhere, so you have to specify it more with this CSS
p a {
display: block;
}
Here is the jsfiddle example http://jsfiddle.net/vzmtB/ (without using p a) and http://jsfiddle.net/vzmtB/1/ (with using p a).
I think the default word-wrap without break does this already. when some thing doesn't fit in line It moves to next line, but If it can be fit then it doesn't move to next line. You need to have a defined width of parent element, in which text gonna be fit. check this fiddle.
nothing you need to do in css.

How can I "display:none" to some adjacent text with CSS?

The code I need to work on looks like this:
<p>
<a href="http://creativecommons.org/publicdomain/mark/1.0/" rel="license">
<img alt="Public Domain Mark" src="http://i.creativecommons.org/p/mark/1.0/88x31.png" style=""></a>
<br> This work is free of known copyright restrictions...
</p>
It displays an image and then some text after the image. I need neither to display.
This works fine to get rid of the image:
a[rel="license"] {display:none;}
However, I need a way to get rid of the text after the <br> (and its unclosed tag if possible) and can't lose the closing </p> tag.
I am grabbing the HTML from a remote site and have no control over the markup there.
Thanks in advance for your help!
There's no way to hide this text using CSS, without adding a tag aground it- depending on how you're grabbing the site, your best bet would be to attempt to find "This work is free of known copyright restrictions..." and replace it with the same text surrounded by <span></span>; or simply deleting it altogether.
I realize this is an old question, but I found it interesting. I'm wondering if it wouldn't work to fiddle with the box model of the <p> tag, so that you hide what you want to "get rid of", even though it's still there?
For instance, say I wanted to display the image, but not the non-element text following. (I realize you want to eliminate the image as well, but for demonstration purposes having some visible content inside the <p> is helpful.) Since I know the image is 31px tall, I might just go with something like:
p {
height: 31px;
overflow: hidden;
}
Et voilà. Whether or not that would work for your specific need, I feel like we don't have enough context to determine. What you're asking for is to be left with an empty paragraph containing an invisible link, which absent larger context has no obvious purpose.
Come to think of it, though… if I then wanted to also hide the image, I'd just use a slight modification of your style above, and append:
a[rel="license"] { visibility: hidden; }
(You don't want to use display: none, as that will affect the dimensions of the <p> CSS box.)
This certainly has unfortunate implications for screen readers and the like, but for certain quick-and-dirty display needs it might suffice.

Stacking two characters vertically in a table with no space between them

This should be really simple, but I can't figure it out. So: how do I get these two characters to merge up in a table?
〳 1st row, U+3033 VERTICAL KANA REPEAT MARK UPPER HALF
〵 2nd row, U+3035 VERTICAL KANA REPEAT MARK LOWER HALF
Those are used in the vertical writing of Japanese, and they're supposed to look like a big version of U+3031 VERTICAL KANA REPEAT MARK 〱 when combined. But simply setting border-spacing, padding, collapse etc isn't enough, since there's still space above and below the chars themselves. Failed attempt:
<table style='border-collapse:collapse'>
<tr><td>〳</td></tr>
<tr><td>〵</td></tr>
</table>
So how do I squeeze the juice out of the text? I suppose the ideal answer would be to use 'real' vertical writing capabilities in a browser, but as far as I can tell this is still a utopian draft.
You need to also use border-spacing: 0;. That along with padding:0; will help. They should match, however, depending on the padding the actual font character has, you might have to use a div, and set the height/width so that it clips.
You might be better off with Div's, if you are simply trying to display the character.
http://www.gateshosting.com/test/slash.html
<div>
<div style='border:0;padding:0;font-family:tahoma;font-size:15px;height:14px;'>/</div>
<div style='border:0;padding:0;font-family:tahoma;font-size:15px;height:14px;''>\</div>
</div>
Surely there has to be a solution if you search for it on a Japanese blog or something.
If you can wrap them in a span, then this works http://jsfiddle.net/zdqvM/5/ and the shift seems to be correct even at higher font-size: http://jsfiddle.net/zdqvM/6/.

What is the best UI/CSS combination when displaying strings of unknown length?

I have a list of items that I am displaying in a floated list, with each item in the list at a fixed width so that there's two per row. What is the best practice to prevent this horrible thing from happening:
alt text http://x01.co.uk/floated_items.gif
Possibilites:
Trim to a specified number of characters before displaying the data. Requires guesswork on how many characters will be "safe".
Overflow: hidden. Hacky.
Remove the background and just have a top border on each item.
Possible but silly:
Have a scrollbar in each item by doing overflow: auto, this will look horrendous.
Add a background image to the container. It's not guaranteed that there's always an equal number of items so this option is out.
Any help on this irritating issue appreciated!
Are you using a fixed font size, i.e. specified in px? If not you also need to consider the various text size options of each browser which is probably going to make the concept of trimming the string redundant. If it is fixed then perhaps seeing how many Ws you can fit in and restricting your text to that -3 and appending an ellipsis, not sure what this list is for so that's one approach.
Personally I'd probably use overflow:hidden as that covers all eventualities and ensures that it'll always keep your layout consistent.
I guess the last option would be to keep a tight control over what can be added to the list and prevent the problem occuring in the first place. Prevention better than cure as they say, although probably unhelpfully.
There are scripts that help with this by comparing the li in blocks of two and making them both equal to the tallest.
Usually, rather than thinking what's best from a css point of view though, you should consider what presentation you want, then get the css/JavaScript to get you to your desired effect.
If this is something that you're just wanting out of the way, consider using a gradient background image that highlights the top of the li and suggests the block without actually filling it in.
Adding link to a jQuery solution: Equalize
One solution would be to have a alpha-based PNG that would slowly fade the text to the backgroundcolor of your container, on the last 10px or so. That would look good if some text are considerebly shorter than the long ones, however in the case where the text would be equal to the container it could look kinda silly.
Of course, in combination with display: hidden and white-space: no-wrap
From an accessibility point of view it's not a good idea to simply hide the title, since that could hide content on people who increase font sizes due to bad eyesight. Your design should be able to float when hit by bad resolutions or similar obstructions, even if it floats into something less pleasing to the eye.
Now if I understand your issue with the background image correctly, I believe your problem could be solved using the techniques describes in the ALA article on sliding doors, where the background image expands with the content.
Here's some controversy for you.. use a table?
Sounds like you have a grid of data to me, would a table answer this problem for you?
It also raises the question, do you actually want the items to be the same height, or just have the same amount of black background behind them? You could apply the black to the row's background, then create the centre white separator with borders and margins.
You could try using:
ul li{
display:block;
float:left;
width:6em;
height:4em;
background-color:black;
color:white;
margin-right:1em;
}
ul{
height:100%;
overflow:hidden;
}
div{
height:3em;
overflow:hidden;
background-color:blue;
}
Don't know about cross browser consistensy though.
EDIT: This is the html I'm assuming:
<div>
<ul>
<li>asdf
<li>asdf trey tyeu ereyuioquoi
<li>fdas dasf erqwt ytwere r
<li>dfsaklñd s jfañlsdjf ñkljdk ñlfas
<li>ksdflñajñldsafjñlksdjfñalksdfjlkdhfc,v.mxzn
</ul>
</div>

Resources