可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I apologise in advance as I know this question has come up many times before but I just can't seem to find the right solution (and believe me I've tried a few!)
Basically it's the old "Fit text perfectly inside a div without affecting the size of the div". And unless I'm a complete numpty, I believe CSS has no way of doing this. So what I mean basically is rather than doing something like:
#someDiv {
font-size: 12px;
}
or...
#someDiv {
font-size: 1em;
}
...I want to be able to do something like this:
#someDiv {
font-size: fluid;
}
...meaning that whatever text this div contains, scale it to fit perfectly from left to right and top to bottom with no overflow or whitespace.
After trawling through countless websites looking for this CSS solution, I've now accepted that CSS isn't capable of this ...so, enter jQuery.
I've found several jQuery solutions online but they will only scale the text to fit the width, but I want it to scale to the height as well. So effectively I want to say to jQuery:
"jQuery, find $(this) div and whatever text is inside it I want you to scale it so that it fills the entire height and width of the div as tightly as possible".
In case I haven't explained myself very well, I've attached a graphic explaining the problem I'm facing and the solution I'm looking for.
Any help would be much appreciated. Thank you.
回答1:
Here's the same answer, but in Javascript
var autoSizeText;
autoSizeText = function() {
var el, elements, _i, _len, _results;
elements = $('.resize');
console.log(elements);
if (elements.length < 0) {
return;
}
_results = [];
for (_i = 0, _len = elements.length; _i < _len; _i++) {
el = elements[_i];
_results.push((function(el) {
var resizeText, _results1;
resizeText = function() {
var elNewFontSize;
elNewFontSize = (parseInt($(el).css('font-size').slice(0, -2)) - 1) + 'px';
return $(el).css('font-size', elNewFontSize);
};
_results1 = [];
while (el.scrollHeight > el.offsetHeight) {
_results1.push(resizeText());
}
return _results1;
})(el));
}
return _results;
};
$(document).ready(function() {
return autoSizeText();
});
By the way...if you ever need to convert coffeescript to javascript, just go to js2coffee.org
回答2:
I was wanting something similar myself recently:
<div class='container'>
<div class='no-resize'>This text won't be resized and will go out of the div.</div>
<div class='resize'>This text will be resized and wont go out of the div.</div>
</div>
And
.no-resize, .resize {
width: 100px;
height: 50px;
border: 1px solid #000;
color: #000;
float: left;
margin-left: 10px;
font-size: 15px
}
Fiddler at jsfiddle.net/mn4rr/1/.
回答3:
I don't have enough reputation to comment on the accepted answer so I made an answer. If height
has a css3 transition on it the autoSizeText()
and $.resizeText
answers above have issues. I made a short jquery plugin to fix this.
$.fn.resizeText = function (options) {
var settings = $.extend({ maxfont: 40, minfont: 4 }, options);
var style = $('<style>').html('.nodelays ' +
'{ ' +
'-moz-transition: none !important; ' +
'-webkit-transition: none !important;' +
'-o-transition: none !important; ' +
'transition: none !important;' +
'}');
function shrink(el, fontsize, minfontsize)
{
if (fontsize < minfontsize) return;
el.style.fontSize = fontsize + 'px';
if (el.scrollHeight > el.offsetHeight) shrink(el, fontsize - 1, minfontsize);
}
$('head').append(style);
$(this).each(function(index, el)
{
var element = $(el);
element.addClass('nodelays');
shrink(el, settings.maxfont, settings.minfont);
element.removeClass('nodelays');
});
style.remove();
}
To use this plugin you only need to call
$(selector).resizeText();
I hope this saves someone else some time troubleshooting. I wasted a good 20 minutes scratching my head wondering why the code above was causing an infinite loop on my page.
回答4:
I solved this by making a jQuery plugin, it's here: http://jsfiddle.net/c9YNz/2/ (Updated to deal with resizing windows)
The code for the plugin just shrinks the text down to 0.01em size and then grows it to fit, here's the plugin code:
$.fn.resizeText = function () {
var width = $(this).innerWidth();
var height = $(this).innerHeight();
var html = $(this).html();
var newElem = $("<div>", {
html: html,
style: "display: inline-block;overflow:hidden;font-size:0.1em;padding:0;margin:0;border:0;outline:0"
});
$(this).html(newElem);
$.resizeText.increaseSize(10, 0.1, newElem, width, height);
$(window).resize(function () {
if ($.resizeText.interval)
clearTimeout($.resizeText.interval)
$.resizeText.interval = setTimeout(function () {
elem.html(elem.find("div.createdResizeObject").first().html());
elem.resizeText();
}, 300);
});
}
$.resizeText = {
increaseSize: function (increment, start, newElem, width, height) {
var fontSize = start;
while (newElem.outerWidth() <= width && newElem.outerHeight() <= height) {
fontSize += increment;
newElem.css("font-size", fontSize + "em");
}
if (newElem.outerWidth() > width || newElem.outerHeight() > height) {
fontSize -= increment;
newElem.css("font-size", fontSize + "em");
if (increment > 0.1) {
$.resizeText.increaseSize(increment / 10, fontSize, newElem, width, height);
}
}
}
};
Then if you have this html:
<div class="resizeText" style="width:1200px;height:400px;">
Insert text from slipsum here.
</div>
You call it just like this:
$(document).ready(function () {
$(".resizeText").resizeText();
});
It's not the best way to do it, but it's enough for you to be going on with, I would imagine (plus it works).
回答5:
Here's a slightly modified version of the given answers.
Requirements :
- The class containing text has the "resize" class.
- it contains height and width (%, px, whatever...)
What changes in this version ?
- I added resizing ( by binding the event resize to the function) autoSizeText. This is far from ideal, but if we don't resize a lot, it should be ok.
- In previous versions, text is only getting smaller. Now it tries to find the biggest font without going outside the div.
Note:
I don't claim the code is production ready. But if you find something you can enhance, please share it with the community.
var autoSizeText = function () {
var el, elements, _i, _len;
elements = $('.resize');
if (elements.length < 0) {
return;
}
for (_i = 0, _len = elements.length; _i < _len; _i++) {
el = elements[_i];
dichoFit = function (el) {
diminishText = function () {
var elNewFontSize;
elNewFontSize = (parseInt($(el).css('font-size').slice(0, -2)) - 1) + 'px';
return $(el).css('font-size', elNewFontSize);
};
augmentText = function () {
var elNewFontSize;
elNewFontSize = (parseInt($(el).css('font-size').slice(0, -2)) + 1) + 'px';
return $(el).css('font-size', elNewFontSize);
};
diminishText();
while (el.scrollHeight < el.offsetHeight) {
augmentText();
}
augmentText();
while (el.scrollHeight > el.offsetHeight) {
diminishText();
}
}
dichoFit(el);
}
};
$(document).ready(function () {
autoSizeText();
$(window).resize(function resizeText(){
autoSizeText()
})
});
.sizable{
width: 50vw;
height: 50vh;
border: 2px solid darkred;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='sizable resize'>
I am a sizable div and I have explicit width and height.
</div>
回答6:
Sorry late answer but can saves time of many,
I write this code which works perfectly during resize of window.
function fitTextInDiv(){
if($this.find('.text-wrapper').height() > $this.find('.aligned-text').height() ){
while( $this.find('.text-wrapper').height() > $this.find('.aligned-text').height() ) {
$this.find('.aligned-text').css('font-size', (parseFloat($this.find('.aligned-text').css('font-size')) + 0.1) + "px" );
}
}
else if($this.find('.text-wrapper').height() < $this.find('.aligned-text').height() ){
while( $this.find('.text-wrapper').height() < $this.find('.aligned-text').height() ) {
$this.find('.aligned-text').css('font-size', (parseFloat($this.find('.aligned-text').css('font-size')) - 0.1) + "px" );
}
}
}
Where text-wrapper is parent and aligned-text is child div. You must specify height and width of parent element. In resize you can set height and width of parent element by using jquery then call this function.
I write this code because I tried my many plugins but they don't support resizing window.
回答7:
I got the same problem and the solution is basically use javascript to control font-size.
Check this example on codepen:
https://codepen.io/ThePostModernPlatonic/pen/BZKzVR
try to resize it
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Documento sem título</title>
<style>
</style>
</head>
<body>
<div style="height:100vh;background-color: tomato;" id="wrap">
<h1 class="quote" id="quotee" style="padding-top: 56px">Because too much "light" doesn't <em>illuminate</em> our paths and warm us, it only blinds and burns us.</h1>
</div>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
var multiplexador = 3;
initial_div_height = document.getElementById ("wrap").scrollHeight;
setInterval(function(){
var div = document.getElementById ("wrap");
var frase = document.getElementById ("quotee");
var message = "WIDTH div " + div.scrollWidth + "px. "+ frase.scrollWidth+"px. frase \n";
message += "HEIGHT div " + initial_div_height + "px. "+ frase.scrollHeight+"px. frase \n";
if (frase.scrollHeight < initial_div_height - 30){
multiplexador += 1;
$("#quotee").css("font-size", multiplexador);
}
console.log(message);
}, 10);
</script>
</html>
回答8:
Here's my version. This is build with ES6 on a React project.
export function autoSizeText(container, attempts=30) {
let setChildrenToInheritFontSize = ( el ) => {
el.style.fontSize = 'inherit';
_.each( el.children, (child) => {
setChildrenToInheritFontSize( child );
});
};
let resizeText = (el) => {
attempts--;
let elNewFontSize;
if( el.style.fontSize === "" || el.style.fontSize === "inherit" || el.style.fontSize === "NaN" ){
elNewFontSize = '32px'; // largest font to start with
} else {
elNewFontSize = (parseInt(el.style.fontSize.slice(0, -2)) - 1) + 'px';
}
el.style.fontSize = elNewFontSize;
// this function can crash the app, so we need to limit it
if( attempts <= 0 ) {
return;
}
if ( (el.scrollWidth > el.offsetWidth) || (el.scrollHeight > el.offsetHeight)) {
resizeText(el);
}
};
setChildrenToInheritFontSize( container );
resizeText(container);
}