2010-12-04 5 views
20

Есть ли способ автоматически оправдывать слова, используя интервалы между буквами, каждый в своей строке, до определенной ширины, используя CSS?Текст CSS оправдывается пробелом в письме

Например, «Что-то вроде этого» будет выглядеть, ну, что-то вроде этого:

"Something like this" would look something like this

Есть ли не-навязчивый способ применить такой стиль к моему тексту? Я считаю, что чистый CSS не имеет этой опции (по крайней мере, не с версиями CSS до 3, у CSS3, похоже, есть свойство text-justify, но оно пока не поддерживается), поэтому js-решения также будут прекрасны.

+0

Вы готовы использовать какую-либо конкретную библиотеку JS для достижения этой цели, или только ваниль JS? – 2010-12-06 00:10:06

+0

@David: jQuery будет предпочтительнее, но это довольно простая задача, поэтому его можно портировать между фреймворками без проблем IMO. – Groo 2010-12-07 11:33:47

ответ

8

Вот сценарий, который может это сделать. Это некрасиво, но, возможно, вы можете взломать его, чтобы удовлетворить ваши потребности. (Обновлено для обработки изменения размера)

<html> 
<head> 
<style> 
#character_justify { 
    position: relative; 
    width: 40%; 
    border: 1px solid red; 
    font-size: 32pt; 
    margin: 0; 
    padding: 0; 
} 
#character_justify * { 
    margin: 0; 
    padding: 0; 
    border: none; 
} 
</style> 
<script> 
function SplitText(node) 
{ 
    var text = node.nodeValue.replace(/^\s*|\s(?=\s)|\s*$/g, ""); 

    for(var i = 0; i < text.length; i++) 
    { 
     var letter = document.createElement("span"); 
     letter.style.display = "inline-block"; 
     letter.style.position = "absolute"; 
     letter.appendChild(document.createTextNode(text.charAt(i))); 
     node.parentNode.insertBefore(letter, node); 

     var positionRatio = i/(text.length - 1); 
     var textWidth = letter.clientWidth; 

     var indent = 100 * positionRatio; 
     var offset = -textWidth * positionRatio; 
     letter.style.left = indent + "%"; 
     letter.style.marginLeft = offset + "px"; 

     //console.log("Letter ", text[i], ", Index ", i, ", Width ", textWidth, ", Indent ", indent, ", Offset ", offset); 
    } 

    node.parentNode.removeChild(node); 
} 

function Justify() 
{ 
    var TEXT_NODE = 3; 
    var elem = document.getElementById("character_justify"); 
    elem = elem.firstChild; 

    while(elem) 
    { 
     var nextElem = elem.nextSibling; 

     if(elem.nodeType == TEXT_NODE) 
      SplitText(elem); 

     elem = nextElem; 
    } 
} 

</script> 
</head> 
<body onload="Justify()"> 
<p id="character_justify"> 
Something<br/> 
Like<br/> 
This 
</p> 
</body> 
+1

Спасибо, отлично работает. Для тех, кто заинтересован, этот скрипт находит div по его идентификатору, вставляет отдельный div для каждого символа в вычисленных отступов, а затем удаляет начальный div. – Groo 2010-12-04 23:38:48

+0

Существует также небольшая проблема, что символы позиционируются с регулярными интервалами, а не имеют фиксированный интервал между ними. Это выглядит странно, когда у вас есть символы различной ширины (например, «WiW»). Я задавался вопросом, могу ли я просто добавить пробелы между буквами и использовать обозреватель, так как каждый символ был словом, но они не оправдаются, если в конце есть `
`. У вас есть предложение? – Groo 2010-12-07 11:36:32

+0

Хорошо, забыли об этом, я приму это сейчас. Я не использовал его в конце, но он достаточно близко. – Groo 2010-12-20 13:27:16

-1

Что не так с text-align: justify? Думаю, я мог бы не понимать ваш вопрос.

+12

@CC: Это не оправдывает отдельные слова, увеличивая расстояние между буквами. – Groo 2010-12-05 19:08:08

+0

Кроме того, text-align поддерживается только IE на данный момент. – theannouncer 2015-02-07 22:50:53

4

Я знаю, что это старая тема, но я столкнулся с ней в ту ночь. И нашел подходящее решение с использованием таблиц.

Каждое письмо должно быть помещено в <td> </td>. Я знаю, что это выглядит утомительно, но если вы хотите сделать это, это будет слово или два, верно? Или вы всегда можете использовать JS, чтобы заполнить его, если это слишком много. Однако это только CSS и очень универсальное решение.

Используя буквенное расстояние, буквы распределяются правильно. Вы должны поиграть с ним, в зависимости от ширины таблицы.

#justify { 
    width: 300px; 
    letter-spacing: 0.5em; 
} 
<table id="justify"> 
    <tbody> 
    <tr> 
     <td>J</td> 
     <td>U</td> 
     <td>S</td> 
     <td>T</td> 
     <td>I</td> 
     <td>F</td> 
     <td>Y</td> 
    </tr> 
    </tbody> 
</table> 

See the example here

Crossbrowser безопасно, практически ничего не должны отличаться. Это просто CSS.

Я использовал его в My website, который находится на английском и испанском языках. Подзаголовок под моим именем на испанском языке имеет дополнительную букву, и она выйдет за пределы ширины. Используя приведенные выше таблицы, он автоматически распределяется по той же ширине. Размещая его вручную, я должен был определить целое условие для каждого языка, чтобы обойти это.

2

Вот другой Подход, используя фрагмент JQuery, который я написал для этого вопроса: Stretch text to fit width of div:

DEMO

HTML:

<div class="stretch">Something</div> 
<div class="stretch">Like</div> 
<div class="stretch">This</div> 

JQuery:

$.fn.strech_text = function() { 
    var elmt = $(this), 
     cont_width = elmt.width(), 
     txt = elmt.html(), 
     one_line = $('<span class="stretch_it">' + txt + '</span>'), 
     nb_char = elmt.text().length, 
     spacing = cont_width/nb_char, 
     txt_width; 

    elmt.html(one_line); 
    txt_width = one_line.width(); 

    if (txt_width < cont_width) { 
     var char_width = txt_width/nb_char, 
      ltr_spacing = spacing - char_width + (spacing - char_width)/nb_char; 

     one_line.css({ 
      'letter-spacing': ltr_spacing 
     }); 
    } else { 
     one_line.contents().unwrap(); 
     elmt.addClass('justify'); 
    } 
}; 


$(document).ready(function() { 
    $('.stretch').each(function() { 
     $(this).strech_text(); 
    }); 
}); 
0

Опять же, я знаю, что это ДЕЙСТВИТЕЛЬНО старый, но почему бы просто не поместить пробел между каждой буквой, а затем выравнивать текст: оправдать?Тогда каждая буква будет считаться «словом» и соответствующим образом определена.

2

Это тоже нужно, поэтому я включил предложенную технику в простой в использовании jquery-plugin, который вы можете найти здесь: .

Он использует ту же самую процедуру в своем ядре и добавляет некоторые опции для настройки. Комментарии приветствуются.

0

Альтернативный способ справиться с этим может заключаться в использовании блока калибровки «vw». Этот тип устройства можно использовать в свойствах размера шрифта и представляет собой процент ширины окна.

Отказ от ответственности: Это не то, что вы ищете, но не требует скриптов. Он корректирует размер текста, но также масштабируется до ширины вашей страницы.

Например,

.heading { 
    font-size: 4vw; 
} 

сделает ширину одного символа в текущем шрифте 4% от ширины окна.

Затем вы можете использовать медиа-запросы, если хотите заблокировать размер шрифта до минимального размера в зависимости от ширины окна.

@media only screen and (max-width: 768px) { 
    font-size: 2rem; 
} 

Используйте инспектор браузера, чтобы играть со свойством размера шрифта и настроить значение, что имеет смысл для вашего приложения.

Блок «vw» работает в IE9 +, iOS 8.3+ и Android 4.4+ и всех других основных браузерах. Я бы не стал беспокоиться о мобильной поддержке слишком много, так как вы можете использовать медиа-запросы, чтобы поместить правильный размер для этих устройств, как описано выше.

http://caniuse.com/#feat=viewport-units

https://css-tricks.com/viewport-sized-typography/

Viewport единицы представляют собой мощный способ масштабирования много различных аспектов вашего сайта с небольшим количеством кода.

0

Я только что создал сценарий JQuery из подхода Tony B таблицы. Вот JSFiddle https://jsfiddle.net/7tvuzkg3/7/

Этот скрипт создает таблицу с каждым символом в строке. Это работает с полным предложением. Я не уверен, что это полностью оптимизировано.

justifyLetterSpacing("sentence"); 
 

 
function justifyLetterSpacing(divId) { 
 

 
\t // target element 
 
\t domWrapper = $('#' + divId).clone().html(''); 
 
\t // construct <td> 
 
\t $('#' + divId).contents().each(function(index){ 
 
     // store div id to td child elements class 
 
\t var tdClass = divId ; 
 
     // split text 
 
\t $textArray = $(this).text().split(''); 
 
     // insert each letters in a <td> 
 
\t for (var i = 0; i < $textArray.length; i++) { 
 
     // if it's a 'space', replace him by an 'html space' 
 
     if($textArray[i] == " ") { 
 
      $('<td>') 
 
       .addClass(tdClass) 
 
       .html("&nbsp;&nbsp;") 
 
       .appendTo(domWrapper); 
 
     }// if it's a char, add it 
 
     else{ 
 
      $('<td>') 
 
       .addClass(tdClass) 
 
       .text($textArray[i]) 
 
       .appendTo(domWrapper); 
 
     } 
 
\t } 
 
\t }); 
 
    // create table 
 
    table = 
 
    $("<table id='"+divId+"'/>").append( 
 
     $("<tbody>").append( 
 
      $("<tr>").append( 
 
       (domWrapper).children('td') 
 
      ) 
 
     ) 
 
    ); 
 
    // replace original div 
 
\t $('#' + divId).replaceWith(table); 
 
} \t
#sentence { 
 
    width : 100%; 
 
    background-color : #000; 
 
    color : #fff; 
 
    padding : 1rem; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="sentence">LOREM IPSUM DOLOR</div>

3

устанавливаемыми сотовыми единственным решением является text-justify: distributehttps://www.w3.org/TR/css-text-3/#text-justify но поддержка по-прежнему очень бедных.

Небольшой эксперимент с использованием text-align-last: justify и добавление пробелов между буквами.

div{ 
 
\t display:inline-block; 
 
\t text-align: justify; 
 
\t text-align-last: justify; 
 
\t letter-spacing: -0.1em; 
 
}
<div> 
 
S o m e t h i n g<br> 
 
l i k e<br> 
 
t h i s 
 
</div>