注意,我不是要求根据视口大小缩放字体 - 我的问题不同。
我的HTML / CSS / JS应用程序基本上向用户呈现状态图。屏幕上有一条带有多个按钮的消息。按下每个按钮会导致不同的屏幕 - 依此类推 - 非常简单的概念,的确如此。
每个按钮来自数据库的每个屏幕的文本。
设计是这样的,按钮尺寸是固定的(我不能控制它)。它们的大小足以容纳应用程序可以遇到的任何东西 - 用英语。
最近,我需要添加斯瓦希里语支持 - 突然之间有2个单词,15个英文字符变成5个单词,在斯瓦希里语中有近50个字符 - 而且它不适合按钮。这是相当糟糕的 - 但只有少数这样的长按钮标签。不幸的是,由于它们是动态的(来自数据库),我在预测它将会做什么方面做得不够。
我可以做的是减小字体大小以适应按钮内的文本。使用vw
,vh
等单位无法正常工作,因为无论视口大小如何,文本都应缩放到固定大小的按钮。
我无法想到任何仅限CSS的解决方案。我可以想一下这个问题的几个JS解决方案(例如放置文本,然后继续缩小它直到它适合 - 虽然我不太确定如何确定它适合)。
我不能完全理解这一点。有任何想法吗?我对CSS3和HTML5感到满意,只需要在最新版本的Chrome和Safari中使用它。
答案 0 :(得分:0)
查看此jsbin:http://jsbin.com/sunamej/1/edit?html,css,js,output
文本根据在white-space: nowrap
的虚拟文本容器上进行的计算进行缩放。这允许将文本的总宽度与按钮的宽度进行比较,并按比例缩小。请记住,由于未考虑单词的换行位置存在一些错误。这在很大程度上可以通过包含的误差因子来缓解,但可能需要针对您的应用进行微调。实际上计算一些东西以完全考虑到自动换行的位置将是艰巨的,并且不适合这样的应用程序只有几个单词/行的时间。以下是bin中的代码:
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<button class="btn">
<span class="dummy-text">
Testing with some large text that should scale
</span>
<span class="text">
Testing with some large text that should scale
</span>
</button>
<button class="btn">
<span class="dummy-text">
Testing with some
</span>
<span class="text">
Testing with some
</span>
</button>
<button class="btn">
<span class="dummy-text">
Testing with some large text
</span>
<span class="text">
Testing with some large text
</span>
</button>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</body>
</html>
CSS:
.btn {
/* hardcoded dimens */
height: 35px;
width: 75px;
}
.dummy-text {
/* hide dummy, don't wrap */
display: none;
white-space: nowrap;
}
使用Javascript:
console.clear();
// NOTE: use of jQuery is arbitrary; all functions
// are available in vanilla js
function scaleText(btn) {
// select the dummy text
var dtxt = btn.find('.dummy-text');
// select the real text
var txt = btn.find('.text');
// get te with of the button and the dummy
var tw = dtxt.width();
var bw = btn.width();
// number of lines of text the button allows
var lines = 2;
// factoring in error caused by wrapping; this
// may need fine tuning for your application
var err = 0.85;
// get the fonts scale
var scale = (bw * lines * err)/tw;
// get the current font size
var sz = parseInt(dtxt.css('font-size').replace('px', ''));
// scale appropiately
txt.css('font-size', sz * scale + 'px');
}
// apply to each button
var btns = $('.btn');
btns.each(function(i, btn) {
scaleText($(btn));
});
答案 1 :(得分:0)
受Adjust size of an SVG-element to its content启发,它需要更多微调和一种方法将长文本拆分为适当数量的行,如果您可以从文本长度猜测宽度/高度,可以用foreignObject
换行......但这是一个可能的开始:
[...document.getElementsByTagName("svg")].forEach(svg => {
const bbox = svg.getBBox();
svg.setAttribute("viewBox", [bbox.x, bbox.y, bbox.width, bbox.height].join(" "));
})
&#13;
button {
width: 100px;
height: 50px;
padding: 0;
}
svg {
width: 100%;
height: 100%;
}
&#13;
<button>
<svg>
<text>Short</text>
</svg>
</button>
<button>
<svg>
<text>Longer text</text>
<text y='1em'>split externally</text>
<text y='2em'>to balanced lines</text>
</svg>
</button>
&#13;