How can I style an HTML element to avoid hanging text? - javascript

I'm creating a page where there's a textbox that displays a text string from the database, and its length varies. Because of this, some strings happen to be long enough to run onto two lines, but that second line is short, and this doesn't look good:
Here the blue box shows the div that contains the content. It's got a fixed width (80% of the container), and text-align:center.
So my question is: how can I get the text to flow into lines where the line widths are closer to each other? I'm willing to do some math and dynamically adjust the width or font size, but I'm not sure how to do this reliably.

You need JavaScript to do this. CSS alone cannot fix this issue if you are using dynamic text.
Once you've detected that the height of the box goes beyond the limit of one line you can either shrink the font, expand the box or calculate the mid-point to add a break and have two balanced lines.
Here are various jQuery plugins that an do this for you. There are many if you look.
http://fittextjs.com/
https://github.com/jquery-textfill/jquery-textfill

personally I don't like use javascript to "simple things"
you use the following properties
overflow
white-space
http://jsfiddle.net/ALWqd/

Related

Dynamic text height plus wrapping to fill textarea in CSS

I am new to coding so I hope this is not too unclear:
I am learning Javascript, CSS and HTML through making a simple HTML calculator of which the display is a textarea (unless there is a better option for what I describe below).
I would like the contents of the textarea to be the same height as it at first, becoming smaller as the numbers require more width. However, I would like there to be a particular text size at which it begins to wrap (break onto the next line) without overflow. Ideally, the text would continue to get smaller and wrap onto more lines in order to fit in the textarea (this may not be practical for a real calculator, but this is also an exercise in design).
I have tried a few ways with word-break, word-wrap and overflow-wrap but none have had any effect, I imagine it might require some script as well and maybe some a more nuanced definition of the textarea size.
This may be complex or too ambitious but I would like to see if it is possible first!
Thanks a lot in advance.

Javascript retrieve linebreaks from dom [duplicate]

I need to add line breaks in the positions that the browser naturally adds a newline in a paragraph of text.
For example:
<p>This is some very long text \n that spans a number of lines in the paragraph.</p>
This is a paragraph that the browser chose to break at the position of the \n
I need to find this position and insert a <br />
Does anyone know of any JS libraries or functions that are able to do this?
The only solutuion that I have found so far is to remove tokens from the paragraph and observe the clientHeight property to detect a change in element height. I don't have time to finish this and would like to find something that's already tested.
Edit:
The reason I need to do this is that I need to accurately convert HTML to PDF. Acrobat renders text narrower than the browser does. This results in text that breaks in different positions. I need an identical ragged edge and the same number of lines in the converted PDF.
Edit:
#dtsazza: Thanks for your considered answer. It's not impossible to produce a layout editor that almost exactly replciates HTML I've written 99% of one ;)
The app I'm working on allows a user to create a product catalogue by dragging on 'tiles' The tiles are fixed width, absolutely positioned divs that contain images and text. All elemets are styled so font size is fixed. My solution for finding \n in paragraph is ok 80% of the time and when it works with a given paragrah the resulting PDF is so close to the on-screen version that the differences do not matter. Paragraphs are the same height (to the pixel), images are replaced with high res versions and all bitmap artwork is replaced with SVGs generated server side.
The only slight difference between my HTML and PDF is that Acrobat renderes text slightly more narrowly which results in line slightly shorter line length.
Diodeus's solution of adding span's and finding their coords is a very good one and should give me the location of the BRs. Please remember that the user will never see the HTML with the inserted BRs - these are added so that the PDF conversion produces a paragraph that is exactly the same size.
There are lots of people that seem to think this is impossible. I already have a working app that created extremely accurate HTML->PDF conversion of our docs - I just need a better solution of adding BRs because my solution sometimes misses a BR. BTW when it does work my paragraphs are the same height as the HTML equivalents which is the result we are after.
If anyone is interested in the type of doc i'm converting then you can check ou this screen cast:
http://www.localsa.com.au/brochure/brochure.html
Edit: Many thanks to Diodeus - your suggestion was spot on.
Solution:
for my situation it made more sense to wrap the words in spans instead of the spaces.
var text = paragraphElement.innerHTML.replace(/ /g, '</span> <span>');
text = "<span>"+text+"</span>"; //wrap first and last words.
This wraps each word in a span. I can now query the document to get all the words, iterate and compare y position. When y pos changes add a br.
This works flawlessly and gives me the results I need - Thank you!
I would suggest wrapping all spaces in a span tag and finding the coordinates of each tag. When the Y-value changes, you're on a new line.
I don't think there's going to be a very clean solution to this one, if any at all. The browser will flow a paragraph to fit the available space, linebreaking where needed. Consider that if a user resizes the browser window, all the paragraphs will be rerendered and almost certainly will change their break positions. If the user changes the size of the text on the page, the paragraphs will be rerendered with different line break points. If you (or some script on your page) changes the size of another element on the page, this will change the amount of space available to a floating paragraph and again - different line break points.
Besides, changing the actual markup of your page to mimic something that the browser does for you (and does very well) seems like the wrong approach to whatever you're doing. What's the actual problem you're trying to solve here? There's probably a better way to achieve it.
Edit: OK, so you want to render to PDF the same as "the screen version". Do you have a specific definitive screen version nominated - in terms of browser window dimensions, user stylesheets, font preferences and adjusted font size? The critical thing about HTML is that it deliberately does not specify a specific layout. It simply describes what is on the page, what they are and where they are in relation to one another.
I've seen several misguided attempts before to produce some HTML that will exactly replicate a printed creative, designed in something like a DTP application where a definitive absolute layout is essential. Those efforts were doomed to failure because of the nature of HTML, and doing it the other way round (as you're trying to) will be even worse because you don't even have a definitive starting point to work from.
On the assumption that this is all out of your hands and you'll have to do it anyway, my suggestion would be to give up on the idea of mangling the HTML. Look at the PDF conversion software - if it's any good it should give you some options for font kerning and similar settings. Playing around with the details here should get you something that approximates the font rendering in the browser and thus breaks lines at the same places.
Failing that, all I can suggest is taking screenshots of the browser and parsing these with OCR to work out where the lines break (it shouldn't require a very accurate OCR since you know what the raw text is anyway, it essentially just has to count spaces). Or perhaps just embed the screenshot in the PDF if text search/selection isn't a big deal.
Finally doing it by hand is likely the only way to make this work definitively and reliably.
But really, this is still just wrong and any attempts to revise the requirements would be better. Keep going up one step in the chain - why does the PDF have to have the exact same ragged edge as some arbitrary browser rendering? Can you achieve that purpose in another (better) way?
Sounds like a bad idea when you account for user set font sizes, MS Windows accessibility mode, and the hundreds of different mobile devices. Let the browser do it's thing - trying to have exact control over the rendering will only cause you hours of frustration.
I don't think you'll be able to do this with any kind of accuracy without embedding Gecko/WebKit/Trident or essentially recreating them.
Maybe an alternative: do all line-breaks yourself, instead of relying on the browser. Place all text in pre tags, and add your own linebreaks. Now at least you don't have to figure out where the browser put them.

How to find the first line in auto wrapping html

Assuming I have a div with a fixed width and some auto wrapping text inside. Now I want to insert a span element at the end of the first line. Because the text isn’t written in a specific structure, the first line could contain five words as well as three or just one. So I would need to find the position on which the automatic line-break happens. Is that possible or do I need to insert a manual br or some marker?
It's painfully possible. The question is why are you trying to do this? There may be an easier way to accomplish what you need.
If you decide you still need to do this, what you would have to do is create a clone of this div that cannot be seen. You would set this cloned div's height to 1px or something like that. You can then fill this clone with identical text word by word. Once the div's scrollHeight jumps, you know that the first word wrap has occurred. You can then use this data to figure out where the original paragraph' first line has word wrapped.
You need add or some marker. Different browser calculate how many words should be placed in the first line. And if user change setting of browser, for instance increase font size, the first line will change number of words.

Dynamic text in fixed-size div

I have a fixed-size div with generated text inside it.
Is there some simple way to cut the text before div's end and add "..." at the end using DOJO or plain Javascript? Is there a way to do it regardless of what size of font i use?
The only way that comes to my mind is to calculate how many characters with actual font fits into my div and than cut the text to be that long, but this looks pretty lame :-) any suggestions?
May be it helps dojo.html.ellipsis

Coloring lines inside textarea

Is there any way to make textarea display lines in colors? What I am trying to achieve is every second line colored, i.e. white,grey,white,grey,white,grey... for better readability. Users are supposed to write in lots of stuff, as in "enter names, each one from new line".
I do use jQuery anyway so if they made some simpler solution for this it would be perfect.
What you are looking for is called Zebra striping, maybe that will help with some google searching. However, I don't think there is a way to currently do this to text within a textarea (besides using the background image hack).
CSS3 has a lot of powerful features such as the nth-child psuedo class. There might be a way to do it using that, but again, it probably has no way to do that within a text area.
Perhaps another solution would be to do something like SO does -- where you enter text into a textarea and then next to it or below it it shows a nicely formatted version. You would use jquery to parse the text in real time and display it zebra striped.
Edit: I had another idea that might work, but would take some experimenting. There is probably a way using jquery to get the absolute position of each line of text in the text area. I would think you could at least get the absolute position of the top left of the textarea, get the line height of the text, multiply by the number of rows down (number of linebreaks in the text), test and tweak a little, and you should be able to get the position of each line in the text area. Then, use jquery to draw a colored div behind the text area for each line of text that is as wide as the textarea and as tall as the line of text. The textarea should be transparent as well.
With a little more work, you can probably even have the zebra striping logic be smart enough to detect if the line of text has wrapped, so that zebra stripe can be 2 or more lines tall.
Might work. Good luck!
One way to accomplish this would be to just use a background in the textarea.
<style type="text/css">
textarea { background-image: url(bg.png); }
</style>
That being said, you'd have to have to play around with the tiling and the line-height to get it just right, but it should be able to accomplish what you're looking for without the use of scripting.
If you wanted to make the actual text different colors, there's no way to do this using a pure <textarea>. You could use a rich text editor such as TinyMCE, but that would be way too overkill in my opinion.

Categories

Resources