2017-04-22 310 views
2

請注意,我並不是要求根據視口的大小縮放字體 - 我的問題是不同的。根據內容(CSS或JS)縮放字體大小

我的HTML/CSS/JS應用程序基本上向用戶呈現一個狀態圖。屏幕上顯示一些消息,並帶有多個按鈕。按下每個按鈕會導致不同的屏幕 - 如此等等 - 確實是非常簡單的概念。

作爲每個按鈕的每個屏幕的文本來自數據庫。

設計是這樣的,按鈕尺寸是固定的(我沒有任何控制它)。它們足夠大以適應應用程序可能遇到的任何事情 - 使用英語。

最近,我需要添加斯瓦希里語支持 - 突然之間有2個單詞,15個英語字符變成了5個單詞,並且在斯瓦希里語中有近50個字符 - 並且它不適合按鈕。這是相當糟糕的 - 但只有少數這樣長的按鈕標籤。不幸的是,由於它們是動態的(來自數據庫),我無法預測它會是什麼。

我可以做的事情是減少字體大小以適應按鈕內的文本。使用vw,vh等單位不會工作,因爲無論視口大小如何,都應將文本縮放爲固定大小的按鈕。

我想不出任何純CSS的解決方案。我可以考慮一些解決這個問題的JS(例如放置文本,然後繼續縮小它直到它適合 - 雖然我不太確定如何確定它適合)。

我只是不能完全弄清楚這一點。有任何想法嗎?我對CSS3和HTML5感到滿意,只需要它就可以在最新版本的Chrome和Safari中使用。

+0

,如果你可以把文本轉換成SVG元素 - https://css-tricks.com/svg-text-typographic-designs/ – Aprillion

+0

@ 4億美元嗯,有趣的想法。不幸的是,SVG不支持自動換行。現在按鈕允許最多3行文本,自動換行,垂直居中和水平居中。 –

+0

你是否適合使用虛擬元素進行計算? (如果你是我可能有一個解決方案) – treyhakanson

回答

0

看看這個jsbin:http://jsbin.com/sunamej/1/edit?html,css,js,output

文本根據對虛擬文本容器進行與white-space: nowrap的計算比例。這樣可以將文本的總寬度與按鈕的寬度進行比較,並按比例縮小。請記住,由於沒有考慮單詞將包裹的位置,因此存在一些錯誤。這在很大程度上可以通過包含錯誤因素來緩解,但可能需要針對您的應用程序進行微調。實際上計算出一些東西來完全考慮文字包裝的位置會很困難,而且只用幾個字/行就不能爲這樣的應用程序工作。這裏是全倉代碼以及:

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)); 
}); 
+0

謝謝,我來看看。我懷疑它會需要很多微調,因爲幾乎所有的長文本都是由寬度稍大於半寬的文字組成的,這就強制了額外的換行符。如果我只根據字符和行的寬度來分割文本,我會得到兩行,但有適當的換行符,我會得到四行。 –

0

通過Adjust size of an SVG-element to its content的啓發,它需要更精細的調整和將長文本分割爲適當數量的行的方法,可能會使用01進行包裝如果您可以從文本長度中猜測寬度/高度...但這裏是一個可能的開始:

[...document.getElementsByTagName("svg")].forEach(svg => { 
 
    const bbox = svg.getBBox(); 
 
    svg.setAttribute("viewBox", [bbox.x, bbox.y, bbox.width, bbox.height].join(" ")); 
 
})
button { 
 
    width: 100px; 
 
    height: 50px; 
 
    padding: 0; 
 
} 
 

 
svg { 
 
    width: 100%; 
 
    height: 100%; 
 
}
<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>