Reputation: 1275
I have a background image with a div
. I want to write some text, but this text should change the font size through the div
.
Upvotes: 23
Views: 91834
Reputation: 20230
I understand your question this way, you would like to fit some text into a given div with a fixed dimension, and if the div is too small to show all the text, the font size should be shrinked until the text fits into the div. If that's the point, here is my solution.
Here is an example with a jQuery implementaion: http://jsfiddle.net/MYSVL/2/
Here is a div
<div id="fitin">
<div>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</div>
</div>
With a fixed size
#fitin {
width: 300px;
height: 100px;
border: 1px solid black;
overflow: hidden;
font-size: 1em;
}
This JavaScript will do the job.
$(function() {
while( $('#fitin div').height() > $('#fitin').height() ) {
$('#fitin div').css('font-size', (parseInt($('#fitin div').css('font-size')) - 1) + "px" );
}
});
Upvotes: 55
Reputation: 1892
Check out this example here http://codepen.io/LukeXF/pen/yOQWNb, you can use a simple function on page load and page resize to make the magic happen.
function resize() {
$('.resize').each(function(i, obj) {
$(this).css('font-size', '8em');
while ($(this).width() > $(this).parent().width()) {
$(this).css('font-size', (parseInt($(this).css('font-size')) - 1) + "px");
}
});
}
Upvotes: 0
Reputation: 181
I have made better version of @DanielB code, maybe it save someone time :)
(Just add class RESIZABLE to div you want to be changed)
$(document).ready(function() {
$(window).resize(function() {
$('.RESIZABLE').each(function(i, obj) {
$(this).css('font-size', '8em');
while ($(this).width() > $(this).parent().width()) {
$(this).css('font-size', (parseInt($(this).css('font-size')) - 1) + "px");
}
});
});
});
Upvotes: 0
Reputation: 3846
I extend DanielB solution in the case when you have a complex HTML inside the div and you want to maintains ratio between different elements:
$(function() {
$(window).on('resize', function() {
$('#fitin').css('font-size', '1em');
var count = 0;
while( count< 30 && $('#fitin').height() > $('#fitin div').height() ) {
$('#fitin *').each(function( index ) {
$(this).css('font-size',(parseInt($(this).css('font-size')) + 1) + "px");
});
count++;
}
count = 0;
while( count< 30 && $('#fitin div').height() > $('#fitin').height()-20 ) {
$('#fitin *').each(function( index ) {
$(this).css('font-size',(parseInt($(this).css('font-size')) - 1) + "px");
})
count++;
}
});
$(window).trigger('resize');
});
Upvotes: 0
Reputation: 1385
The question has been answered since long, but I'd like to add some notes.
Since, an extra jQuery plugin has been added to the universe: FlowType.js
https://github.com/simplefocus/FlowType.JS
I tried my hand at the given solutions and plugins (including FlowType.JS), in the end I wrote my own. I just like to include it here as 'inspiration'. I use a different approach: I calculate the ratio that the size of the text is larger then it's parent. I don't know if it makes sense, but for me it works nicely.
/* shrinkText jQuery Plugin */
(function( $ ){
$.fn.shrinkText = function() {
var $_me = this;
var $_parent = $_me.parent();
var int_my_width = $_me.width();
var int_parent_width = $_parent.width();
if ( int_my_width > int_parent_width ){
rl_ratio = int_parent_width / int_my_width;
var int_my_fontSize = $_me.css("font-size").replace(/[^-\d\.]/g, '');
int_my_fontSize = Math.floor(int_my_fontSize * rl_ratio);
$_me.css("font-size", int_my_fontSize + "px");
}
};
})( jQuery );
It assumes a inline-element within a block-level element, it shrinks the inline element by recalculating the font-size.
HTML:
<h1 style="white-space:nowrap;">
<a href="#" >Macrobenthos of the North Sea - Miscellaneous worms</a>
</h1>
JavaScript:
if( jQuery().shrinkText ){
$("#title a").shrinkText();
}
Upvotes: 1
Reputation: 4395
FlowType.js will do just that: resize the font to match the bounding element, be it a div or another element type.
An example of implementing FlowType:
Set up your style
body {
font-size: 18px;
line-height: 26px;
}
Download FlowType from GitHub and include a reference to it in your head element
flowtype.jQuery.js
Call FlowType
$('body').flowtype();
(optional) Update default settings
$('body').flowtype({
minimum : 500,
maximum : 1200,
minFont : 12,
maxFont : 40,
fontRatio : 30,
lineRatio : 1.45
});
Check out their homepage for an interactive demo
Upvotes: 7
Reputation: 2580
Here is a global function with JQuery and HTML5 Data annotations to define the block size take a look:
Don't ask me why I need the table :-) , the width function works best with tables... on Jquery 1.7 .. Getting no width for Divs
Usage :
<table>
<tr>
<td class="caa" data-text-max-width="500" data-text-max-height="80">
The Text is Here
</td>
</tr>
</table>
Function to add:
$(function () {
var textConsts = {
MIN_SIZE_OF_A_TEXT: 9
};
$('*[data-text-max-width]').each(function () {
var textMaxWidth = $(this).data("text-max-width");
var textMaxHeight = $(this).data("text-max-height");
var minSizeOfaText = $(this).data("text-min-size");
$(this).css('font-size', '9em');
if (minSizeOfaText == null || !($(this).hasData("text-min-size")))
minSizeOfaText = textConsts.MIN_SIZE_OF_A_TEXT;
if (textMaxWidth == null || !($(this).hasData("text-max-width")))
textMaxWidth = $(this).parent().width();
if (textMaxHeight == null || !($(this).hasData("text-max-height")))
textMaxHeight = $(this).parent().height();
var curentWidth = $(this).width();
var curentFontSize = 0;
var numberOfRounds = 0;
var currentHeigth = $(this).height();
curentFontSize = parseInt($(this).css('font-size'));
var lineHeigth = parseInt($(this).css('line-height'));
if (currentHeigth > (curentFontSize * lineHeigth)) {
curentWidth += curentFontSize * lineHeigth;
}
while (curentWidth > textMaxWidth || currentHeigth > textMaxHeight) {
curentFontSize = parseInt($(this).css('font-size'));
curentFontSize -= 1;
$(this).css('font-size', curentFontSize + "px");
curentWidth = $(this).width();
currentHeigth = $(this).height();
if (currentHeigth > (curentFontSize * 1.5))
curentWidth += curentFontSize * 1.5;
numberOfRounds += 1;
if (numberOfRounds > 1000)
break;
if (curentFontSize <= minSizeOfaText)
break;
}
$(this).css('height', textMaxHeight + "px");
$(this).css('width', textMaxWidth + "px");
});
});
Upvotes: 0
Reputation: 105081
I'm not completely sure I understand your question but I think what you're asking is how to fit text in a particular container of predefined size. I'll try to answer this question.
When you want to do this on demand on the client you will have to run Javascript. The idea is to:
generate an invisible div
and set its style to:
position: absolute;
top: 0;
left: 0;
width: auto;
height: auto;
display: block;
visibility: hidden;
font-family: /* as per your original DIV */
font-size: /* as per your original DIV */
white-space: /* as per your original DIV */
copy your text to it
check whether DIV's width exceeded the size of your original DIV.
adjust font-size
value by not simply incrementing/decrementing but rather by calculating width difference between your invisible and original DIV. This will deviate to correct size much faster.
go to step 3.
There is no reliable way of setting font size on the server so it will fit your client rendered container. Unfortunately you can only approximate sizes on pretested empirical data.
Upvotes: 1
Reputation: 38170
You have to preload the image to get the width and height of the image.
As soon as you got the dimensions you can "try" different fontsizes:
$("<img/>").appendTo(document.body).attr('src','myBackground.png').load(function(){
var width = $(this).width(), height = $(this).height(),
$div = $("#myDivId"),
font = 30;
do{
font--;
$div.css('font-size',font);
}while($div.width()>width || $div.height()>height || font == 0);
$div.width(width);
$div.height(height);
});
Upvotes: 0