摘要:在日常工作需求中,設(shè)計師丟給你一個,發(fā)現(xiàn)里面的文本是兩端對齊的,然后發(fā)現(xiàn)實(shí)際開發(fā)中,兩端對齊這種操作根本是不行的,它會拉開單詞空格的距離,十分難看。那么怎么解決呢控制字間距啊祭出這個神器聽說報紙排版也是微調(diào)字間距實(shí)現(xiàn)豆腐塊式的排版的。
因?yàn)橹按a寫得太亂了。最近在重寫,忘了開分支。有興趣查看之前代碼的朋友可以重置回c8034eb這個commit之前的代碼看。重寫完成后會重寫一篇文章,抱歉啦。
前言話不多說,先上圖。后者紅框里是瀏覽器默認(rèn)的文本排版,右側(cè)會有鋸齒(至于難不難看就見仁見智啦哈哈)。前者是使用自己開發(fā)的hyphenjs后的文本排版,整齊得像一塊豆腐塊!對于一個處女座來說,簡直舒心了很多。去看看這個神奇的hyphenjs
應(yīng)用場景不會無緣無故的造輪子。在日常工作需求中,設(shè)計師丟給你一個PSD,發(fā)現(xiàn)里面的文本是兩端對齊的,然后發(fā)現(xiàn)實(shí)際開發(fā)中,兩端對齊text-align:justify;這種操作根本是不行的,它會拉開單詞空格的距離,十分難看。PSD里之所以好看,是因?yàn)樵O(shè)計師里進(jìn)行了字號或者斷行的微調(diào)。當(dāng)然大家都知道,在實(shí)際開發(fā)中根本行不通的。作為一個還蠻有追求的前端開發(fā),在社區(qū)里找不到滿意的工具庫后,果斷開始自己動手,創(chuàng)造幸福。
技術(shù)分析簡單來說,開發(fā)hyphenjs中(hyphenjs只考慮西文,也就是英文、印尼文等),遇到的三個難點(diǎn):
斷行的時機(jī),哪個字符適合斷行?
在每行的末位適不適合加連接符-呢?
如何讓其每行長度一致,排版精致風(fēng)騷呢?
第一點(diǎn),本來就是為了實(shí)現(xiàn)兩端對齊,所以,每行的長度要接近文本盒子的寬度才能達(dá)到目的。問題來了,盒子的寬度輕輕松松的可以獲?。?b>(getComputedStyle(target))["width"],那么行長度如何控制呢?請看以下代碼:
var span = document.createElement("span"), width = 0; span.style.fontSize = 18; span.innerText = "R"; target.appendChild(span); width= (span.getBoundingClientRect())["width"];
通過這個方法的思想,也就獲取了每個字符的真實(shí)寬度,需要注意的幾個方面,fontSize需要從文本盒子獲知,這里只是假設(shè)一個字號而已。同時,span只有插入到文本盒子(或者說DOM樹)中,才能真正生效,去獲取它的所有真實(shí)的屬性(同時也會繼承父級的相關(guān)樣式,比如font-family等我們關(guān)心的屬性)。
因此,最后我們可以獲取文本盒子里的所有出現(xiàn)過的字符的寬度,把它們的charCode和寬度用hashMap記錄下來,方便復(fù)用。
怎樣計算每行的累積寬度呢?請看下面的函數(shù):
// 計算n到m字符間的累計寬度 function getAccWidth(textData, charArray, from, to) { return charArray.slice(from, to).reduce(function(acc, cur) { if (!cur) return acc + 0; return acc + textData[PREFIX + cur.charCodeAt()].width; }, 0); }
上面計算到的hashMap終于派上用場了,逐個訪問文本里的每個字符的charCode,通過hashMap(也就是函數(shù)的形參textData)得到了該字符的寬度,累積算出從n到m的總寬度,和盒子寬度作為比較,若盒子寬度介于當(dāng)前字符與當(dāng)前的下一個字符各自的累積寬度,即應(yīng)當(dāng)為適合斷行的時機(jī)。舉個栗子,比如第一行,那么from為0, to假如到第21個字符,誒喲剛好大于盒子寬度咯,那么20~21就是剛好適合斷行的時機(jī)。
那么第一個問題得到解決!緊接著來~雖然粗糙的斷行了,怎樣精致風(fēng)騷斷行?斷行適不適合加連接符?我特意去谷歌搜了幾張英語報紙觀摩了一下,發(fā)現(xiàn)幾個特點(diǎn):
單詞如果被腰斬了,那么要加!但是最多從第二個字符開始~
特殊字符如"":;,.?()[]{}<>~!@#$%^&*-+=/|1234567890不需要加,為蝦米?看著不舒服啊~
逗號句號等標(biāo)點(diǎn)符號不會呆在每行的開頭。
那么在斷行的時機(jī)里加上以上的判斷,就可以實(shí)現(xiàn)風(fēng)騷斷行了!
然鵝問題來了,當(dāng)我風(fēng)騷地把成品發(fā)給公司的前輩看的時候,前輩輕輕的飄來一句,還是沒有對齊啊···內(nèi)心受到了暴擊,的確,因?yàn)橹暗娜齻€條件導(dǎo)致斷行發(fā)生了一些小小的飄移,所以的確也不能完好對齊了。那么怎么解決呢?控制字間距?。〖莱?b>letter-spacing這個神器?。犝f報紙排版也是微調(diào)字間距實(shí)現(xiàn)豆腐塊式的排版的)。
公式也很輕而易舉就想出來了:合理字間距 = (盒子寬度 - 行寬度)/ 該行字符數(shù)
將字間距應(yīng)用到每一行的行內(nèi)樣式即可。Duang!完成啦哈哈哈~~
最后稍微提幾點(diǎn)有趣的地方和注意的地方:
空格的寬度怎么獲?。恐苯犹砑拥紻OM里是被忽略的,哭···這個糾結(jié)了一段時間,后來發(fā)現(xiàn)x x減掉xx就可以了
多次對同一個文本應(yīng)用hyphenjs怎么辦?這個一開始沒考慮到,后來將文本保存到全局對象中window.hyphen_cached,需要使用的時候隨時提取~
hyphenjs目前只應(yīng)用于純文本~比如說
hyphenjs is absolutely helpful.
里面的strong標(biāo)簽就會忽略,因?yàn)閔yphenjs獲取的是innerText~這是我第一次寫博客,然后自己也是剛畢業(yè)兩個月的小白,寫得不好的地方還請大家多多見諒~當(dāng)然最重要的是,如果這個hyphenjs對你的工作產(chǎn)生了幫助,還請不吝給個star哦,或者發(fā)現(xiàn)了什么問題,也可以提個issue哦~
有個前輩和我說,“凡事都要遵循樸素的實(shí)用主義嘛”,感觸很深,開發(fā)出的任何東西基本上都需要實(shí)用,這樣才能應(yīng)用到實(shí)際開發(fā)中,才能對自己的工作和成長帶來幫助。畫風(fēng)一轉(zhuǎn),嘿嘿嘿···狠狠戳這里hyphenjs
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/112474.html
摘要:在日常工作需求中,設(shè)計師丟給你一個,發(fā)現(xiàn)里面的文本是兩端對齊的,然后發(fā)現(xiàn)實(shí)際開發(fā)中,兩端對齊這種操作根本是不行的,它會拉開單詞空格的距離,十分難看。那么怎么解決呢控制字間距啊祭出這個神器聽說報紙排版也是微調(diào)字間距實(shí)現(xiàn)豆腐塊式的排版的。 因?yàn)橹按a寫得太亂了。最近在重寫,忘了開分支。有興趣查看之前代碼的朋友可以重置回c8034eb這個commit之前的代碼看。重寫完成后會重寫一篇文章,...
摘要:在日常工作需求中,設(shè)計師丟給你一個,發(fā)現(xiàn)里面的文本是兩端對齊的,然后發(fā)現(xiàn)實(shí)際開發(fā)中,兩端對齊這種操作根本是不行的,它會拉開單詞空格的距離,十分難看。那么怎么解決呢控制字間距啊祭出這個神器聽說報紙排版也是微調(diào)字間距實(shí)現(xiàn)豆腐塊式的排版的。 因?yàn)橹按a寫得太亂了。最近在重寫,忘了開分支。有興趣查看之前代碼的朋友可以重置回c8034eb這個commit之前的代碼看。重寫完成后會重寫一篇文章,...
摘要:今天在做項目的時候碰到這個問題右側(cè)紅線內(nèi)的小標(biāo)題單行兩端對齊。兩端對齊的屬性我們知道是,但是這個屬性有它的局限性只能為或多行文字才能實(shí)現(xiàn)兩端對齊。也就是說,在現(xiàn)在的情況下,小標(biāo)題的單行文字僅僅使用是實(shí)現(xiàn)不了兩端對齊的。 今天在做項目的時候碰到這個問題:右側(cè)紅線內(nèi)的小標(biāo)題單行兩端對齊。 showImg(https://segmentfault.com/img/bVQv1a?w=319&h...
摘要:下載安裝的瀏覽器等也沒有問題。但是用安卓手機(jī)再帶的瀏覽器,問題就出現(xiàn)了。經(jīng)過查詢找到一個問題。于是給每個文字之間添加了一個空格,成功解決了各瀏覽器不兼容手機(jī)端不兼容的問題。 今天需要切一個響應(yīng)式網(wǎng)頁,有一行文字,需要實(shí)現(xiàn)兩端對齊。 代碼如下: .h_text{ text-align: justify; width: 200px; } 這一行要兩端對齊 根據(jù)經(jīng)驗(yàn)找到t...
閱讀 2122·2021-10-11 10:59
閱讀 953·2021-09-23 11:21
閱讀 3631·2021-09-06 15:02
閱讀 1649·2021-08-19 10:25
閱讀 3413·2021-07-30 11:59
閱讀 2397·2019-08-30 11:27
閱讀 2609·2019-08-30 11:20
閱讀 3003·2019-08-29 13:15