사용자가 입력 한 텍스트를 고정 크기 div로 표시해야합니다. 내가 원하는 것은 텍스트가 가능한 한 상자를 채우도록 글꼴 크기를 자동으로 조정하는 것입니다.
따라서-div가 400px x 300px 인 경우. 누군가가 ABC를 입력하면 정말 큰 글꼴입니다. 문단을 입력하면 작은 글꼴이됩니다.
아마도 최대 글꼴 크기로 시작하고 싶을 것입니다-아마도 32px이며 텍스트가 너무 커서 컨테이너에 맞지 않을 때까지 글꼴 크기를 줄이십시오.
사용자가 입력 한 텍스트를 고정 크기 div로 표시해야합니다. 내가 원하는 것은 텍스트가 가능한 한 상자를 채우도록 글꼴 크기를 자동으로 조정하는 것입니다.
따라서-div가 400px x 300px 인 경우. 누군가가 ABC를 입력하면 정말 큰 글꼴입니다. 문단을 입력하면 작은 글꼴이됩니다.
아마도 최대 글꼴 크기로 시작하고 싶을 것입니다-아마도 32px이며 텍스트가 너무 커서 컨테이너에 맞지 않을 때까지 글꼴 크기를 줄이십시오.
답변:
감사 공격 . jQuery를 사용하고 싶었습니다.
당신은 나를 올바른 방향으로 지적했고, 이것이 내가 끝낸 것입니다.
다음은 플러그인에 대한 링크입니다 : https://plugins.jquery.com/textfill/
그리고 소스에 대한 링크 : http://jquery-textfill.github.io/
;(function($) {
$.fn.textfill = function(options) {
var fontSize = options.maxFontPixels;
var ourText = $('span:visible:first', this);
var maxHeight = $(this).height();
var maxWidth = $(this).width();
var textHeight;
var textWidth;
do {
ourText.css('font-size', fontSize);
textHeight = ourText.height();
textWidth = ourText.width();
fontSize = fontSize - 1;
} while ((textHeight > maxHeight || textWidth > maxWidth) && fontSize > 3);
return this;
}
})(jQuery);
$(document).ready(function() {
$('.jtextfill').textfill({ maxFontPixels: 36 });
});
내 HTML은 이와 같습니다
<div class='jtextfill' style='width:100px;height:50px;'>
<span>My Text Here</span>
</div>
이것은 첫 번째 jquery 플러그인이므로 아마도 좋지 않을 것입니다. 포인터는 확실히 환영합니다.
404
.
이전 솔루션 중 성능이 좋지 않아 충분히 적합한 솔루션을 찾지 못했기 때문에 루핑 대신 간단한 수학을 사용하는 솔루션을 만들었습니다. 모든 브라우저에서도 잘 작동합니다.
이 성능 테스트 사례 에 따르면 여기에있는 다른 솔루션보다 훨씬 빠릅니다.
(function($) {
$.fn.textfill = function(maxFontSize) {
maxFontSize = parseInt(maxFontSize, 10);
return this.each(function(){
var ourText = $("span", this),
parent = ourText.parent(),
maxHeight = parent.height(),
maxWidth = parent.width(),
fontSize = parseInt(ourText.css("fontSize"), 10),
multiplier = maxWidth/ourText.width(),
newSize = (fontSize*(multiplier-0.1));
ourText.css(
"fontSize",
(maxFontSize > 0 && newSize > maxFontSize) ?
maxFontSize :
newSize
);
});
};
})(jQuery);
당신이 기여하고 싶다면 이것을 이것을 Gist에 추가 했습니다 .
.css("font-size")
루프를 호출하지 않습니다 . 어디서 구했습니까? 플러그인에 추가 한 멋진 기능이 없으므로 내 솔루션이 더 빠릅니다. jsperf에 플러그인을 추가 할 수 있으며 어떤 플러그인이 가장 빠른지 알 수 있습니다.)
내가이 답변에 대해 가끔씩 공감하는 것을 좋아하는만큼 (감사합니다!), 이것은 실제로이 문제에 대한 가장 큰 접근법은 아닙니다. 다른 멋진 답변, 특히 반복하지 않고 솔루션을 찾은 답변을 확인하십시오.
아직도, 참고로 여기에 내 원래의 대답이 있습니다 .
<html>
<head>
<style type="text/css">
#dynamicDiv
{
background: #CCCCCC;
width: 300px;
height: 100px;
font-size: 64px;
overflow: hidden;
}
</style>
<script type="text/javascript">
function shrink()
{
var textSpan = document.getElementById("dynamicSpan");
var textDiv = document.getElementById("dynamicDiv");
textSpan.style.fontSize = 64;
while(textSpan.offsetHeight > textDiv.offsetHeight)
{
textSpan.style.fontSize = parseInt(textSpan.style.fontSize) - 1;
}
}
</script>
</head>
<body onload="shrink()">
<div id="dynamicDiv"><span id="dynamicSpan">DYNAMIC FONT</span></div>
</body>
</html>
다음은 클래스 가있는 버전입니다 .
<html>
<head>
<style type="text/css">
.dynamicDiv
{
background: #CCCCCC;
width: 300px;
height: 100px;
font-size: 64px;
overflow: hidden;
}
</style>
<script type="text/javascript">
function shrink()
{
var textDivs = document.getElementsByClassName("dynamicDiv");
var textDivsLength = textDivs.length;
// Loop through all of the dynamic divs on the page
for(var i=0; i<textDivsLength; i++) {
var textDiv = textDivs[i];
// Loop through all of the dynamic spans within the div
var textSpan = textDiv.getElementsByClassName("dynamicSpan")[0];
// Use the same looping logic as before
textSpan.style.fontSize = 64;
while(textSpan.offsetHeight > textDiv.offsetHeight)
{
textSpan.style.fontSize = parseInt(textSpan.style.fontSize) - 1;
}
}
}
</script>
</head>
<body onload="shrink()">
<div class="dynamicDiv"><span class="dynamicSpan">DYNAMIC FONT</span></div>
<div class="dynamicDiv"><span class="dynamicSpan">ANOTHER DYNAMIC FONT</span></div>
<div class="dynamicDiv"><span class="dynamicSpan">AND YET ANOTHER DYNAMIC FONT</span></div>
</body>
</html>
offsetWidth
, 나는 또한 픽셀 추가 한 후 크기에 대한 변수를 생성했다textSpan.style.fontSize = size+"px";
다른 답변의 대부분은 div에 맞을 때까지 글꼴 크기를 줄이기 위해 루프를 사용합니다. 글꼴 크기가 변경 될 때마다 페이지가 요소를 다시 렌더링해야하기 때문에 매우 느립니다. 결국 사용자 브라우저를 멈추지 않고 주기적으로 내용을 업데이트 할 수있는 방식으로 자체 알고리즘을 작성해야했습니다. 다른 기능 (텍스트 회전, 패딩 추가)을 추가하고 jQuery 플러그인으로 패키지하면 다음에서 얻을 수 있습니다.
https://github.com/DanielHoffmann/jquery-bigtext
단순히 전화
$("#text").bigText();
컨테이너에 잘 맞습니다.
여기에서 실제로보십시오 :
http://danielhoffmann.github.io/jquery-bigtext/
현재로서는 몇 가지 제한 사항이 있으므로 div의 높이와 너비는 고정되어 있어야하며 여러 줄로 텍스트 줄 바꿈을 지원하지 않습니다.
최대 글꼴 크기를 설정하는 옵션을 얻는 중입니다.
편집 : 플러그인에 더 많은 문제가 있음을 발견했습니다. 표준 모델 이외의 다른 상자 모델을 처리하지 않으며 div에 여백이나 테두리를 가질 수 없습니다. 나는 그것을 할 것입니다.
Edit2 : 나는 이제 이러한 문제와 한계를 수정하고 더 많은 옵션을 추가했습니다. 최대 글꼴 크기를 설정할 수 있으며 너비, 높이 또는 둘 다를 사용하여 글꼴 크기를 제한하도록 선택할 수도 있습니다. 래퍼 요소에서 최대 너비 및 최대 높이 값을 허용하도록 노력하겠습니다.
Edit3 : 플러그인을 버전 1.2.0으로 업데이트했습니다. 코드 및 새로운 옵션 (verticalAlign, horizontalAlign, textAlign)에 대한 주요 정리 및 span 태그 내부의 내부 요소 지원 (줄 바꿈 또는 멋진 아이콘)
이것은 GeekyMonkey가 위에 게시 한 내용을 기반으로하며 약간 수정되었습니다.
; (function($) {
/**
* Resize inner element to fit the outer element
* @author Some modifications by Sandstrom
* @author Code based on earlier works by Russ Painter (WebDesign@GeekyMonkey.com)
* @version 0.2
*/
$.fn.textfill = function(options) {
options = jQuery.extend({
maxFontSize: null,
minFontSize: 8,
step: 1
}, options);
return this.each(function() {
var innerElements = $(this).children(':visible'),
fontSize = options.maxFontSize || innerElements.css("font-size"), // use current font-size by default
maxHeight = $(this).height(),
maxWidth = $(this).width(),
innerHeight,
innerWidth;
do {
innerElements.css('font-size', fontSize);
// use the combined height of all children, eg. multiple <p> elements.
innerHeight = $.map(innerElements, function(e) {
return $(e).outerHeight();
}).reduce(function(p, c) {
return p + c;
}, 0);
innerWidth = innerElements.outerWidth(); // assumes that all inner elements have the same width
fontSize = fontSize - options.step;
} while ((innerHeight > maxHeight || innerWidth > maxWidth) && fontSize > options.minFontSize);
});
};
})(jQuery);
다음은 이진 검색을 사용하여 가능한 가장 작은 단계에서 부모에 맞는 가장 큰 크기를 찾는 향상된 루핑 방법입니다 (고정 된 글꼴 크기로 스테핑하는 것보다 빠르고 정확합니다). 코드는 성능을 위해 여러 가지 방법으로 최적화됩니다.
기본적으로 10 개의 이진 검색 단계가 수행되며 최적 크기의 0.1 % 이내가됩니다. 대신 numIter를 값 N으로 설정하여 최적 크기의 1 / 2 ^ N 이내로 만들 수 있습니다.
CSS 선택기로 호출하십시오. 예 : fitToParent('.title-span');
/**
* Fit all elements matching a given CSS selector to their parent elements'
* width and height, by adjusting the font-size attribute to be as large as
* possible. Uses binary search.
*/
var fitToParent = function(selector) {
var numIter = 10; // Number of binary search iterations
var regexp = /\d+(\.\d+)?/;
var fontSize = function(elem) {
var match = elem.css('font-size').match(regexp);
var size = match == null ? 16 : parseFloat(match[0]);
return isNaN(size) ? 16 : size;
}
$(selector).each(function() {
var elem = $(this);
var parentWidth = elem.parent().width();
var parentHeight = elem.parent().height();
if (elem.width() > parentWidth || elem.height() > parentHeight) {
var maxSize = fontSize(elem), minSize = 0.1;
for (var i = 0; i < numIter; i++) {
var currSize = (minSize + maxSize) / 2;
elem.css('font-size', currSize);
if (elem.width() > parentWidth || elem.height() > parentHeight) {
maxSize = currSize;
} else {
minSize = currSize;
}
}
elem.css('font-size', minSize);
}
});
};
vAlign
및에 대한 매개 변수를 추가하도록 수정했습니다 padding
. vAlign == true
선택한 요소의 선 높이를 부모 높이의 선 높이로 설정합니다. 패딩은 전달 된 값만큼 최종 크기를 줄입니다. 기본값은 5입니다. 정말 멋지다고 생각합니다.
AngularJS에 대한 지시문을 만들었습니다 .GeekyMonkey의 답변에서 영감을 얻었지만 jQuery 종속성은 없습니다.
데모 : http://plnkr.co/edit/8tPCZIjvO3VSApSeTtYr?p=preview
마크 업
<div class="fittext" max-font-size="50" text="Your text goes here..."></div>
지령
app.directive('fittext', function() {
return {
scope: {
minFontSize: '@',
maxFontSize: '@',
text: '='
},
restrict: 'C',
transclude: true,
template: '<div ng-transclude class="textContainer" ng-bind="text"></div>',
controller: function($scope, $element, $attrs) {
var fontSize = $scope.maxFontSize || 50;
var minFontSize = $scope.minFontSize || 8;
// text container
var textContainer = $element[0].querySelector('.textContainer');
angular.element(textContainer).css('word-wrap', 'break-word');
// max dimensions for text container
var maxHeight = $element[0].offsetHeight;
var maxWidth = $element[0].offsetWidth;
var textContainerHeight;
var textContainerWidth;
var resizeText = function(){
do {
// set new font size and determine resulting dimensions
textContainer.style.fontSize = fontSize + 'px';
textContainerHeight = textContainer.offsetHeight;
textContainerWidth = textContainer.offsetWidth;
// shrink font size
var ratioHeight = Math.floor(textContainerHeight / maxHeight);
var ratioWidth = Math.floor(textContainerWidth / maxWidth);
var shrinkFactor = ratioHeight > ratioWidth ? ratioHeight : ratioWidth;
fontSize -= shrinkFactor;
} while ((textContainerHeight > maxHeight || textContainerWidth > maxWidth) && fontSize > minFontSize);
};
// watch for changes to text
$scope.$watch('text', function(newText, oldText){
if(newText === undefined) return;
// text was deleted
if(oldText !== undefined && newText.length < oldText.length){
fontSize = $scope.maxFontSize;
}
resizeText();
});
}
};
});
resizeText
는 ng-bind
실제로 텍스트를 요소에 할당 하기 전에 호출 되어 현재 텍스트가 아닌 이전 텍스트를 기준으로 크기가 조정 되는 것 같습니다 . 위의 데모에서는 사용자가 입력 할 때 반복적으로 호출되는 것이 나쁘지 않지만 null에서 실제 값으로 (한쪽 바인딩과 같이) 한 번 호출되면 최대 크기로 유지됩니다.
위의 스크립트를 Marcus Ekwall ( https://gist.github.com/3945316) 에서 가져 와서 내 환경 설정으로 조정하여 창 크기를 조정하면 자식이 컨테이너에 항상 맞도록 실행됩니다. 아래 스크립트를 참조 용으로 붙여 넣었습니다.
(function($) {
$.fn.textfill = function(maxFontSize) {
maxFontSize = parseInt(maxFontSize, 10);
return this.each(function(){
var ourText = $("span", this);
function resizefont(){
var parent = ourText.parent(),
maxHeight = parent.height(),
maxWidth = parent.width(),
fontSize = parseInt(ourText.css("fontSize"), 10),
multiplier = maxWidth/ourText.width(),
newSize = (fontSize*(multiplier));
ourText.css("fontSize", maxFontSize > 0 && newSize > maxFontSize ? maxFontSize : newSize );
}
$(window).resize(function(){
resizefont();
});
resizefont();
});
};
})(jQuery);
다음은 OP의 답변을 수정 한 것입니다.
요컨대, 이것을 최적화하려고 시도한 많은 사람들이 루프가 사용되고 있다고 불평했습니다. 예, 루프가 느릴 수 있지만 다른 접근 방식은 정확하지 않을 수 있습니다.
따라서 필자의 접근 방식은 이진 검색 을 사용 하여 최상의 글꼴 크기를 찾습니다.
$.fn.textfill = function()
{
var self = $(this);
var parent = self.parent();
var attr = self.attr('max-font-size');
var maxFontSize = parseInt(attr, 10);
var unit = attr.replace(maxFontSize, "");
var minFontSize = parseInt(self.attr('min-font-size').replace(unit, ""));
var fontSize = (maxFontSize + minFontSize) / 2;
var maxHeight = parent.height();
var maxWidth = parent.width();
var textHeight;
var textWidth;
do
{
self.css('font-size', fontSize + unit);
textHeight = self.height();
textWidth = self.width();
if(textHeight > maxHeight || textWidth > maxWidth)
{
maxFontSize = fontSize;
fontSize = Math.floor((fontSize + minFontSize) / 2);
}
else if(textHeight < maxHeight || textWidth < maxWidth)
{
minFontSize = fontSize;
fontSize = Math.floor((fontSize + maxFontSize) / 2);
}
else
break;
}
while(maxFontSize - minFontSize > 1 && maxFontSize > minFontSize);
self.css('font-size', fontSize + unit);
return this;
}
function resizeText()
{
$(".textfill").textfill();
}
$(document).ready(resizeText);
$(window).resize(resizeText);
또한 요소가 최소 및 최대 글꼴을 지정할 수 있습니다.
<div class="container">
<div class="textfill" min-font-size="10px" max-font-size="72px">
Text that will fill the container, to the best of its abilities, and it will <i>never</i> have overflow.
</div>
</div>
또한이 알고리즘은 단위가 없습니다. 당신은 지정할 수 있습니다 em
, rem
, %
, 등 및 그것의 최종 결과에 대한 것을 사용합니다.
여기는 바이올린입니다 : https://jsfiddle.net/fkhqhnqe/1/
내 웹 사이트와 정확히 같은 문제가있었습니다. 프로젝터, 벽, 큰 화면에 표시되는 페이지가 있습니다.
내 글꼴의 최대 크기를 모르므로 @GeekMonkey 위의 플러그인을 재사용했지만 fontsize를 늘리십시오.
$.fn.textfill = function(options) {
var defaults = { innerTag: 'span', padding: '10' };
var Opts = jQuery.extend(defaults, options);
return this.each(function() {
var ourText = $(Opts.innerTag + ':visible:first', this);
var fontSize = parseFloat(ourText.css('font-size'),10);
var doNotTrepass = $(this).height()-2*Opts.padding ;
var textHeight;
do {
ourText.css('font-size', fontSize);
textHeight = ourText.height();
fontSize = fontSize + 2;
} while (textHeight < doNotTrepass );
});
};
다음은 minFontSize 매개 변수를 사용할 수있는 허용되는 답변 버전입니다.
(function($) {
/**
* Resizes an inner element's font so that the inner element completely fills the outer element.
* @author Russ Painter WebDesign@GeekyMonkey.com
* @author Blake Robertson
* @version 0.2 -- Modified it so a min font parameter can be specified.
*
* @param {Object} Options which are maxFontPixels (default=40), innerTag (default='span')
* @return All outer elements processed
* @example <div class='mybigdiv filltext'><span>My Text To Resize</span></div>
*/
$.fn.textfill = function(options) {
var defaults = {
maxFontPixels: 40,
minFontPixels: 10,
innerTag: 'span'
};
var Opts = jQuery.extend(defaults, options);
return this.each(function() {
var fontSize = Opts.maxFontPixels;
var ourText = $(Opts.innerTag + ':visible:first', this);
var maxHeight = $(this).height();
var maxWidth = $(this).width();
var textHeight;
var textWidth;
do {
ourText.css('font-size', fontSize);
textHeight = ourText.height();
textWidth = ourText.width();
fontSize = fontSize - 1;
} while ((textHeight > maxHeight || textWidth > maxWidth) && fontSize > Opts.minFontPixels);
});
};
})(jQuery);
FitText.js ( github page )를 사용 하여이 문제를 해결할 수 있습니다. TextFill에 비해 실제로 작고 효율적입니다. TextFill은 비싼 while 루프를 사용하지만 FitText는 사용하지 않습니다.
또한 FitText는보다 유연합니다 (매우 특별한 요구 사항이있는 proyect에서 사용하고 챔피언처럼 작동합니다!).
HTML :
<div class="container">
<h1 id="responsive_headline">Your fancy title</h1>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="jquery.fittext.js"></script>
<script>
jQuery("#responsive_headline").fitText();
</script>
옵션을 설정할 수도 있습니다.
<script>
jQuery("#responsive_headline").fitText(1, { minFontSize: '30px', maxFontSize: '90px'});
</script>
CSS :
#responsive_headline {
width: 100%;
display: block;
}
편집 :이 코드는 HTML5 비디오 위에 메모를 표시하는 데 사용되었습니다. 비디오 크기가 조정되면 (브라우저 창의 크기가 조정될 때) 글꼴 크기가 즉석에서 변경됩니다. 노트가 비디오에 연결된 경우 (YouTube의 노트와 마찬가지로) 코드에서 DOM 핸들 대신 인스턴스를 사용하는 이유 직접.
요청에 따라 이것을 달성하는 데 사용한 코드를 던져 보겠습니다. (HTML5 비디오 위에 텍스트 상자가 있습니다.) 코드는 오래 전에 작성되었으며 솔직히 말해서 꽤 지저분하다고 생각합니다. 질문에 이미 답변되어 있고 오래 전에 이미 답변이 수락되었으므로 이것을 다시 쓰지 않아도됩니다. 그러나 누군가 이것을 조금 단순화하고 싶다면 환영합니다.
// Figure out the text size:
var text = val['text'];
var letters = text.length;
var findMultiplier = function(x) { // g(x)
/* By analysing some functions with regression, the resulting function that
gives the best font size with respect to the number of letters and the size
of the note is:
g(x) = 8.3 - 2.75x^0.15 [1 < x < 255]
f(x) = g(letters) * (x / 1000)^0.5
Font size = f(size)
*/
return 8.3 - 2.75 * Math.pow(x, 0.15);
};
var findFontSize = function(x) { // f(x)
return findMultiplier(letters) * Math.pow(x / 1000, 0.5);
};
val.setFontSizeListener = function() {
p.style.fontSize = '1px'; // So the text should not overflow the box when measuring.
var noteStyle = window.getComputedStyle(table);
var width = noteStyle.getPropertyValue('width');
var height = noteStyle.getPropertyValue('height');
var size = width.substring(0, width.length - 2) * height.substring(0, height.length - 2);
p.style.fontSize = findFontSize(size) + 'px';
};
window.addEventListener('resize', val.setFontSizeListener);
이 숫자들을 font-family에서 font-family로 조정해야 할 것입니다. 이를 수행하는 좋은 방법은 GeoGebra라는 무료 그래프 시각화 도구를 다운로드하는 것입니다. 텍스트 길이와 상자 크기를 변경하십시오. 그런 다음 크기를 수동으로 설정하십시오. 수동 결과를 좌표계에 플로팅합니다. 그런 다음 여기에 게시 한 두 방정식을 입력하고 "my"그래프가 직접 플롯 한 점에 맞을 때까지 숫자를 조정합니다.
제안 된 반복 솔루션은 두 가지 측면에서 극적으로 향상 될 수 있습니다.
1) 글꼴 크기에 1을 더하거나 빼지 않고 상수를 곱하십시오.
2) 먼저 코스 상수를 사용하면 0, 즉 각 루프의 크기를 두 배로 늘립니다. 그런 다음 어디에서 시작해야하는지 대략적인 생각으로 1.1을 곱한 것과 같은 미세 조정으로 동일한 작업을 수행하십시오. 완벽 주의자는 이상적인 글꼴의 정확한 정수 픽셀 크기를 원하지만 대부분의 관찰자는 100과 110 픽셀의 차이를 인식하지 못합니다. 완벽 주의자라면 더 세밀하게 조정하여 세 번 반복하십시오.
정확한 질문에 대답하는 특정 루틴이나 플러그인을 작성하는 대신 기본 아이디어에 의존하고 코드의 변형을 작성하여 텍스트, div, span, 이미지 등 모든 종류의 레이아웃 문제를 처리합니다. .. 너비, 높이, 면적, 컨테이너 내에서 다른 요소와 일치합니다 ....
예를 들면 다음과 같습니다.
var nWindowH_px = jQuery(window).height();
var nWas = 0;
var nTry = 5;
do{
nWas = nTry;
nTry *= 2;
jQuery('#divTitle').css('font-size' ,nTry +'px');
}while( jQuery('#divTitle').height() < nWindowH_px );
nTry = nWas;
do{
nWas = nTry;
nTry = Math.floor( nTry * 1.1 );
jQuery('#divTitle').css('font-size' ,nTry +'px');
}while( nWas != nTry && jQuery('#divTitle').height() < nWindowH_px );
jQuery('#divTitle').css('font-size' ,nWas +'px');
이것은 내가 만든 가장 우아한 솔루션입니다. 이진 검색을 사용하여 10 회 반복합니다. 순진한 방법은 while 루프를 수행하고 요소가 오버플로되기 시작할 때까지 글꼴 크기를 1 씩 늘리는 것입니다. element.offsetHeight 및 element.scrollHeight를 사용하여 요소가 오버플로되기 시작하는시기를 결정할 수 있습니다 . scrollHeight가 offsetHeight보다 큰 경우 글꼴 크기가 너무 큽니다.
이진 검색이 훨씬 더 나은 알고리즘입니다. 또한 수행하려는 반복 횟수에 의해 제한됩니다. flexFont를 호출하고 div id를 삽입하면 글꼴 크기가 8px ~ 96px 사이에서 조정됩니다 .
나는이 주제를 연구하고 다른 라이브러리를 시도하는 데 시간을 보냈지 만 궁극적으로 이것이 실제로 작동하는 가장 쉽고 간단한 솔루션이라고 생각합니다.
당신은 당신이 사용하는 변경하려는 경우 참고 offsetWidth
하고 scrollWidth
, 또는이 기능을 모두 추가 할 수 있습니다.
// Set the font size using overflow property and div height
function flexFont(divId) {
var content = document.getElementById(divId);
content.style.fontSize = determineMaxFontSize(content, 8, 96, 10, 0) + "px";
};
// Use binary search to determine font size
function determineMaxFontSize(content, min, max, iterations, lastSizeNotTooBig) {
if (iterations === 0) {
return lastSizeNotTooBig;
}
var obj = fontSizeTooBig(content, min, lastSizeNotTooBig);
// if `min` too big {....min.....max.....}
// search between (avg(min, lastSizeTooSmall)), min)
// if `min` too small, search between (avg(min,max), max)
// keep track of iterations, and the last font size that was not too big
if (obj.tooBig) {
(lastSizeTooSmall === -1) ?
determineMaxFontSize(content, min / 2, min, iterations - 1, obj.lastSizeNotTooBig, lastSizeTooSmall) :
determineMaxFontSize(content, (min + lastSizeTooSmall) / 2, min, iterations - 1, obj.lastSizeNotTooBig, lastSizeTooSmall);
} else {
determineMaxFontSize(content, (min + max) / 2, max, iterations - 1, obj.lastSizeNotTooBig, min);
}
}
// determine if fontSize is too big based on scrollHeight and offsetHeight,
// keep track of last value that did not overflow
function fontSizeTooBig(content, fontSize, lastSizeNotTooBig) {
content.style.fontSize = fontSize + "px";
var tooBig = content.scrollHeight > content.offsetHeight;
return {
tooBig: tooBig,
lastSizeNotTooBig: tooBig ? lastSizeNotTooBig : fontSize
};
}
ReferenceError: lastSizeTooSmall is not defined
. 어딘가에 정의해야할까요?
나는 같은 문제를 겪었고 해결책은 기본적으로 자바 스크립트를 사용하여 글꼴 크기를 제어하는 것입니다. 코드 펜에서이 예제를 확인하십시오.
https://codepen.io/ThePostModernPlatonic/pen/BZKzVR
이 예는 높이에 대한 예일 것입니다.
크기를 조정하십시오
<!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>
contenteditables에 내 버전을 추가하고 싶었습니다.
$.fn.fitInText = function() {
this.each(function() {
let textbox = $(this);
let textboxNode = this;
let mutationCallback = function(mutationsList, observer) {
if (observer) {
observer.disconnect();
}
textbox.css('font-size', 0);
let desiredHeight = textbox.css('height');
for (i = 12; i < 50; i++) {
textbox.css('font-size', i);
if (textbox.css('height') > desiredHeight) {
textbox.css('font-size', i - 1);
break;
}
}
var config = {
attributes: true,
childList: true,
subtree: true,
characterData: true
};
let newobserver = new MutationObserver(mutationCallback);
newobserver.observe(textboxNode, config);
};
mutationCallback();
});
}
$('#inner').fitInText();
#outer {
display: table;
width: 100%;
}
#inner {
border: 1px solid black;
height: 170px;
text-align: center;
display: table-cell;
vertical-align: middle;
word-break: break-all;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="outer">
<div id="inner" contenteditable=true>
TEST
</div>
</div>
텍스트를 축소하기 위해 루프를 사용하지 못하게하는 방법을 찾았습니다. 컨테이너 너비와 내용 너비 사이의 비율에 글꼴 크기를 곱하여 글꼴 크기를 조정합니다. 따라서 컨테이너의 너비가 내용의 1/3이면 글꼴 크기가 1/3 줄어들고 컨테이너의 너비가 줄어 듭니다. 스케일 업하기 위해 컨텐츠가 컨테이너보다 클 때까지 while 루프를 사용했습니다.
function fitText(outputSelector){
// max font size in pixels
const maxFontSize = 50;
// get the DOM output element by its selector
let outputDiv = document.getElementById(outputSelector);
// get element's width
let width = outputDiv.clientWidth;
// get content's width
let contentWidth = outputDiv.scrollWidth;
// get fontSize
let fontSize = parseInt(window.getComputedStyle(outputDiv, null).getPropertyValue('font-size'),10);
// if content's width is bigger than elements width - overflow
if (contentWidth > width){
fontSize = Math.ceil(fontSize * width/contentWidth,10);
fontSize = fontSize > maxFontSize ? fontSize = maxFontSize : fontSize - 1;
outputDiv.style.fontSize = fontSize+'px';
}else{
// content is smaller than width... let's resize in 1 px until it fits
while (contentWidth === width && fontSize < maxFontSize){
fontSize = Math.ceil(fontSize) + 1;
fontSize = fontSize > maxFontSize ? fontSize = maxFontSize : fontSize;
outputDiv.style.fontSize = fontSize+'px';
// update widths
width = outputDiv.clientWidth;
contentWidth = outputDiv.scrollWidth;
if (contentWidth > width){
outputDiv.style.fontSize = fontSize-1+'px';
}
}
}
}
이 코드는 내가 Github에 업로드 한 테스트의 일부입니다 https://github.com/ricardobrg/fitText/
geekMonkey 솔루션을 사용했지만 너무 느립니다. 그가하는 일은 글꼴 크기를 최대 (maxFontPixels)로 조정 한 다음 컨테이너 내부에 맞는지 확인하는 것입니다. 그렇지 않으면 글꼴 크기를 1px 줄이고 다시 확인합니다. 왜 이전 컨테이너의 높이를 확인하고 그 값을 제출하지 않습니까? (예, 이유를 알고 있지만 이제는 높이에서만 작동하고 최소 / 최대 옵션이있는 솔루션을 만들었습니다)
훨씬 빠른 해결책은 다음과 같습니다.
var index_letters_resize;
(index_letters_resize = function() {
$(".textfill").each(function() {
var
$this = $(this),
height = Math.min( Math.max( parseInt( $this.height() ), 40 ), 150 );
$this.find(".size-adjust").css({
fontSize: height
});
});
}).call();
$(window).on('resize', function() {
index_letters_resize();
);
그리고 이것은 HTML이 될 것입니다 :
<div class="textfill">
<span class="size-adjust">adjusted element</span>
other variable stuff that defines the container size
</div>
다시 :이 솔루션은 컨테이너의 높이 만 확인합니다. 그렇기 때문에 요소가 내부에 맞는 경우이 기능을 확인하지 않아도됩니다. 그러나 최소 / 최대 값 (40min, 150max)도 구현 했으므로 완벽하게 작동하며 창 크기 조정에서도 작동합니다.
이 솔루션의 다른 버전은 다음과 같습니다.
shrinkTextInElement : function(el, minFontSizePx) {
if(!minFontSizePx) {
minFontSizePx = 5;
}
while(el.offsetWidth > el.parentNode.offsetWidth || el.offsetHeight > el.parentNode.offsetHeight) {
var newFontSize = (parseInt(el.style.fontSize, 10) - 3);
if(newFontSize <= minFontSizePx) {
break;
}
el.style.fontSize = newFontSize + "px";
}
}