JavaScript scale text for installation in a fixed Div

In JavaScript / jQuery, how can I scale a line of text with a variable length of text in a fixed-width Div so that one line always goes inside the Div (like one line)?

Thank.

+53
javascript jquery html text
Nov 12 2018-10-12
source share
22 answers

It's a bit of a hack, but it will do what you want.

<div id="hidden-resizer" style="visibility: hidden"></div> 

Place this at the bottom of the page where it will not move other elements on the page.

Then do the following:

 var size; var desired_width = 50; var resizer = $("#hidden-resizer"); resizer.html("This is the text I want to resize."); while(resizer.width() > desired_width) { size = parseInt(resizer.css("font-size"), 10); resizer.css("font-size", size - 1); } $("#target-location").css("font-size", size).html(resizer.html()); 
+69
Nov 12 2018-10-12
source share

HTML:

 <div class="box" style="width:700px">This is a sentence</div> <div class="box" style="width:600px">This is a sentence</div> <div class="box" style="width:500px">This is a sentence</div> <div class="box" style="width:400px">This is a sentence</div> 

JavaScript:

 $( '.box' ).each(function ( i, box ) { var width = $( box ).width(), html = '<span style="white-space:nowrap"></span>', line = $( box ).wrapInner( html ).children()[ 0 ], n = 100; $( box ).css( 'font-size', n ); while ( $( line ).width() > width ) { $( box ).css( 'font-size', --n ); } $( box ).text( $( line ).text() ); }); 

Live demo: http://jsfiddle.net/e8B9j/2/show/

Remove "/ show /" from the URL to view the code.

+30
Nov 12 '10 at 15:37
source share

I wrote a jQuery plugin for this:

http://michikono.github.com/boxfit

The plugin will scale the text both horizontally and vertically to the maximum possible size inside the box, and then center it.

The only thing you need to do is define a div with text inside it:

 <div id="scale">some text</div> 

And then call:

 $('#scale').boxfit() 

The method will take some arguments to disable / enable text wrapping and centered alignment.

+13
May 15 '12 at 22:01
source share

For new browsers you can use Inline-SVG. It can be scaled as an image using CSS ..!

 .smallerVersion{ max-width: 50% } 
 <html> <body> <h2>Default version:</h2> <svg viewBox="0 0 240 80" xmlns="http://www.w3.org/2000/svg"> <style> .small { font: italic 13px sans-serif; } .heavy { font: bold 30px sans-serif; } /* Note that the color of the text is set with the * * fill property, the color property is for HTML only */ .Rrrrr { font: italic 40px serif; fill: red; } </style> <text x="20" y="35" class="small">My</text> <text x="40" y="35" class="heavy">cat</text> <text x="55" y="55" class="small">is</text> <text x="65" y="55" class="Rrrrr">Grumpy!</text> </svg> <h2>Scaled version:</h2> <svg class="smallerVersion" viewBox="0 0 240 80" xmlns="http://www.w3.org/2000/svg"> <style> .small { font: italic 13px sans-serif; } .heavy { font: bold 30px sans-serif; } /* Note that the color of the text is set with the * * fill property, the color property is for HTML only */ .Rrrrr { font: italic 40px serif; fill: red; } </style> <text x="20" y="35" class="small">My</text> <text x="40" y="35" class="heavy">cat</text> <text x="55" y="55" class="small">is</text> <text x="65" y="55" class="Rrrrr">Grumpy!</text> </svg> </body> </html 

( width: 100%; )

+7
Nov 29 '13 at 9:20
source share

Most of the other answers use a loop to reduce the font size until it is suitable for the div, it is VERY slow since the page has to re-render the element every time the font size changes. In the end, I had to write my own algorithm so that it would run in such a way that I could periodically update its contents without freezing the user browser. I added some other functions (rotating text, adding additions) and packaged it as a jQuery plugin, you can get it at:

https://github.com/DanielHoffmann/jquery-bigtext

just call

 $("#text").bigText(); 

And it will fit well in your container.

See here:

http://danielhoffmann.imtqy.com/jquery-bigtext/

Now that it has some limitations, the div should have a fixed height and width and does not support wrapping text over multiple lines.

Edit2: I fixed these problems and limitations and added additional parameters. You can set the maximum font size, and you can also limit the font size using width, height, or both (both defaults). I will work with accepting the max-width and max-height values ​​in the wrapper element.

+5
Jul 01 '13 at 16:21
source share

I don't know for sure, but here's an approximation:

 var factor = 1/3; // approximate width-to-height ratio var div = $('#mydiv'); div.css('font-size', div.width() / (div.text().length * factor) + 'px'); 

You will need to adjust factor based on the font you are using. 1/3 seems to work fine for Times New Roman.

+3
Nov 12 2018-10-12
source share

Inside your div, enter text in a space that is not indented. Then the span will be the length of the text.
Unused code to find the correct font size to use:

 var objSpan = $('.spanThatHoldsText'); var intDivWidth = $('.divThatHasAFixedWidth').width(); var intResultSize; for (var intFontSize = 1; intFontSize < 100; intFontSize++) objSpan.css('font-size', intFontSize); if (objSpan.width() > intDivWidth) { intResultSize = intFontSize - 1; break; } } objSpan.css('font-size', intResultSize); 
+2
Nov 12 '10 at 15:21
source share
+2
Jul 22 2018-11-22T00:
source share

Here is the coffeescript solution I came across. I clone the element that needs to be resized, and then delete it at the end of the calculation. To improve performance, I have code that only performs calculations after resizing has stopped for 200 ms.

Tag elements with class autofont so that this is done unobtrusively.

 # # Automagically resize fonts to fit the width of the # container they are in as much as possible. # fixfonts = -> scaler = 1.2 for element in $('.autofont') size = 1 element = $(element) desired_width = $(element).width() resizer = $(element.clone()) resizer.css 'font-size': "#{size}em" 'max-width': desired_width 'display': 'inline' 'width': 'auto' resizer.insertAfter(element) while resizer.width() < desired_width size = size * scaler resizer.css 'font-size': "#{size}em" $(element).css 'font-size': "#{size / scaler }em" resizer.remove() $(document).ready => fixfonts() timeout = 0 doresize = -> timeout-- if timeout == 0 fixfonts() $(window).resize -> timeout++ window.setTimeout doresize, 200 
+2
Mar 01 2018-12-01T00:
source share

Modified version of @sworoc with target class support

 function resizeText(text, size, target) { var fontSize = 0; var resizer = $('<span>'); resizer.html(text).hide(); resizer.attr('class', target.attr('class')); $('body').append(resizer); while(resizer.width() < size) { fontSize++ resizer.css("font-size", fontSize); } target.css('font-size', fontSize).html(text); resizer.remove(); } 

Using

 resizeText("@arunoda", 350, $('#username')); 
+2
May 4, '13 at 1:10
source share

I couldn't figure out how to add this to the sworoc post, but I thought I would share anyway: Lonesomeday's solution is confused if you use any kind of AJAX navigation. I changed it a bit:

 if ($('#hidden-resizer').length == 0){ $('<div />', {id: 'hidden-resizer'}).hide().appendTo(document.body); } 
+1
Nov 29 '11 at 20:39
source share

I had a similar problem that made me write my own plugin for this. One solution is to use a fit shrink approach as described above. However, if you need to fit a few elements or have to deal with performance, for example when resizing a window, look at jquery-quickfit .

It measures and calculates the size-dependent message size for each letter of the text that matches, and uses it to calculate the next best font size that matches the text in the container.

The calculations are cached, which makes it very fast (there is practically no performance when changing the size ahead for the second time) when working with several texts or, if necessary, having the text several times, for example, when changing the window size.

Production example, installation text 14x16x2

+1
Apr 07 '12 at 9:10
source share

Here is my modification of @teambob's suggestion (in the above comments ), which also takes into account the height of the container:

 <div class="box" style="width:700px; height:200px">This is a sentence</div> <div class="box" style="width:600px; height:100px">This is a sentence</div> <div class="box" style="width:500px; height:50px">This is a sentence</div> <div class="box" style="width:400px; height:20px">This is a sentence</div> 

And then..

 $('.box').each(function(i, box) { var width = $(box).width(), height = $(box).height(), html = '<span style="white-space:nowrap">', line = $(box).wrapInner(html).children()[0], maxSizePX = 2000; $(box).css('font-size', maxSizePX); var widthFontSize = Math.floor(width/$(line).width()*maxSizePX), heightFontSize = Math.floor(height/$(line).height()*maxSizePX), maximalFontSize = Math.min(widthFontSize, heightFontSize, maxSizePX); $(box).css('font-size', maximalFontSize); $(box).text($(line).text()); }); 

See Fiddle

+1
Jul 25 '14 at 20:33
source share

I made (yet) another plugin to solve this problem:

https://github.com/jeremiahrose/perfectFit.js

It generates SVG, so it is very fast - it just starts once when the page loads. Able to automatically wrap and scale individual words to exactly match the div.

+1
Jul 18 '18 at 13:48
source share

you can do several things, for example

 overflow:hidden 

this shortens the extra line

overflow:auto // this shows the scroll bar

see this

http://www.w3schools.com/Css/pr_pos_overflow.asp

try to do this // check the length of the text

 if($('#idfortext').length>sometthing) { var fontsize=10; } $('#yourid').css('font-size',fontsize) 
0
Nov 12 '10 at 15:00
source share

I'm not sure if there is any exact way to measure the width of the text in pixels (this is what you are really looking for at the root of your problem), since each browser can display fonts differently. You might want to try using this CSS code, in addition to resizing "Fuzzy" based on the number of letters in the sentence. You can try using a fixed-width font (or style) to display text so that each character occupies the same space. That way you can make the best guess, and CSS will at least give you a good "..." before trimming the text if necessary.

 .truncate { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } 
0
Nov 12 2018-10-12
source share

I worked out a few posts here and made a jQuery plugin out of it. I found that starting from the bottom and rising, it was not very impressive, so I make the assumption that the current font size is close, and worked from there.

  $.fn.fitTextToWidth = function(desiredWidth) { // In this method, we want to start at the current width and grow from there, assuming that we are close to the desired size already. var $el = $(this); var resizer = $('<'+$el.get(0).tagName+' />').css({'vsibility':'hidden','position':'absolute','left':'-9999px','display':'inline'}).html($el.html()); resizer.appendTo(document.body); var size = parseInt($el.css('font-size')); resizer.css('font-size',size+'px'); var growing = desiredWidth > resizer.width() ? true : false; var adder = growing ? 1 : -1; do { size += adder; resizer.css('font-size',size+'px'); } while(((growing && resizer.width()<desiredWidth) || (!growing && resizer.width()>desiredWidth)) && size>10 && size<100); if (growing) size -= 2; //we never want to go over resizer.remove(); $el.css('font-size',size+'px'); } // Example use: $('#main h1').fitTextToWidth(350); 

The only result is that it assumes that the CSS for the element is global and applies only to the element type. In other words, it creates a tag with the same name and assumes that it will have the same CSS attributes as the element we want to change. If this is not true for you, just change the line in which the resizer is created.

0
Feb 16 2018-12-16T00:
source share

to match the width and height of the container

http://blissitec.imtqy.com/scaletextjs/

0
Mar 17 '14 at 16:00
source share

Here is my solution: I measure the text in a new div in the provided div, so the style should be inherited. Then I insert the text into the div at intervals to set the font size. It will be maximized to the default font size, but will decrease.

It does not loop: it only draws the text once in the throwing meta before drawing directly into the provided div. See @Hoffmann's answer - I just didn't like the whole “plugin” to answer the question.

jquery required.

 var txt = txt || {} txt.pad_factor = 1.1; txt.insertText_shrinkToFit = function(div,text) { var d = txt.cache || $('<div></div>'); txt.cache = d; d.css('white-space','nowrap'); d.css('position','absolute'); d.css('top','-10000px'); d.css('font-size','1000px'); var p = $(div); var max_w = parseInt(p.css('max-width')) || p.width(); var max_h = parseInt(p.css('font-size')); p.append(d); d.html(text); var w = d.width() * txt.pad_factor; d.remove(); var h = Math.floor(max_w*1000/w); var s = ( max_h < h ? max_h : h ) + "px"; p.html('<SPAN style="font-size:' + s + '">' + text + '</SPAN>'); } 

For example:

 <html><head><script src=http://code.jquery.com/jquery-latest.min.js></script> <script>/*insert code, from above, here.*/</script></head><body> <div id=mysmalldiv style="max-width:300px;font-size:50px"></div> <script> txt.insertText_shrinkToFit("#mysmalldiv","My super long text for this div."); </script> </body></html> 

For testing: so I found that I need 1.1 pad_factor; which you can customize to your needs.

 <div id=mytestdiv style="max-width:300px;font-size:50px"></div> <script> var t = "my text "; var i = 0; var f = function() { t += i + " "; txt.insertText_shrinkToFit("#mytestdiv",t); i++; if(i < 100) setTimeout(f,1000); } f(); </script> 

Note: It is assumed that the font size is px. I have not tested with em or pt.

0
Sep 29 '14 at 4:25
source share

There is a great way to do this for single-line texts, such as headings, etc., in pure CSS:

 h1{ font-size: 4.5vw; margin: 0 0 0 0; line-height: 1em; height: 1em; } h1:after{ content:""; display: inline-block; width: 100%; } 

Make sure the font size is small enough to keep title bar 1. Using “vw” (viewport width) instead of “px” makes it very easy to do this and scale at the same time. the width of the viewport tends to deteriorate when you make your browser window very large, many sites use this to keep the site under a certain width on really wide screens:

 body{ max-width: 820px; margin: 0 auto; } 

To make sure your font does not depend on how large the viewport window is when the rest of your site stops scaling, use this:

 @media(min-width:820px){ h1{ font-size: 30px; } } 
0
Oct 15 '14 at 2:12
source share

This is what I found today:

  • Set a really large fake font size (f) in the target text
  • measure the width (w) height (h) of the text container and divide by font size (f):

    • iw = w/f
    • ih = h/f
  • Divide the width of the main container (W) by iw and the height of the main container (H) by ih:

    • kw = W/iw
    • kh = H/ih
  • Choose the smallest value between kw and kh: this is the desired FontSize.

https://jsfiddle.net/pinkynrg/44ua56dv/

 function maximizeFontSize($target) { var testingFont = 1000; $target.find(".text-wrapper").css("font-size", testingFont+"px"); var textWidth = $(".text-wrapper").width()/1000; var textHeight = $(".text-wrapper").height()/1000; var width = $(".container").width(); var height = $(".container").height(); var kWidth = width/textWidth; var kHeight = height/textHeight; var fontSize = kWidth < kHeight ? kWidth : kHeight; // finally $(".text-wrapper") .css("font-size", fontSize+"px") .css("line-height", height+"px"); } 
0
Jul 28 '17 at 4:00
source share

This is impossible to do. I thought about it a bit and examined it. The problem is that there are so many variables. Look at the same site on safari / firefox / IE. See how the font size looks a little different? Now take a look at it on Linux / mac / iphone ........

If you find a solution, post it here!

Solution found, I see ... this is great !!

-2
Nov 12 2018-10-12
source share



All Articles