Подтвердить что ты не робот

Как центрировать абзац текста на конкретное слово в HTML, CSS или JavaScript?

У меня есть проход, который сосредоточен на странице, например:

 _________________________
|                         |
| Once upon a time, there |
|   lived a squirrel who  |
|  lived in the middle of |
|       the forest.       |
|_________________________|

Мне нужно настроить центрирование таким образом, чтобы специально выделенное слово было горизонтально центрировано на странице. В этом примере слово "кто" центрировано:

 _________________________
|                         |
|        Once upon        |
|  a time, there lived a  |
|  squirrel who lived in  |
|    the middle of the    |
|         forest.         |
|_________________________|
  • Слово, помеченное в HTML тегом <div>, т.е. <center>Once upon a time, there lived a squirrel <div style="centered">who</div> lived in the middle of the forest.</center>.
  • HTML появляется в приложении, в котором у меня мало контроля над редактированием самого HTML (текст уже отмечен тегами стиля CSS), но может изменять таблицу стилей или добавлять код, например JavaScript, в заголовок для изменения как этот стиль визуализируется.

Как я могу центрировать прохождение определенного слова в HTML, CSS или JavaScript?

4b9b3361

Ответ 1

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

Вы можете добиться грубого центрирования, используя довольно простой JavaScript. Все, что он делает - это сканирование по разметке, преобразует первый найденный TextNode в "слова", завернутый в <span> s, а затем испытания и ошибки, вставляя разрывы строк, пока не найдет тот, который получит целевое слово, ближайшее к центр.

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

На всякий случай люди не знают, что это иллюстрация того, что может быть достигнуто, и отнюдь не совершенна — ни один код не существует, потому что он всегда может быть улучшен и должен быть.

скрипка

http://jsfiddle.net/s8XgJ/2/

обновленная скрипта, которая показывает поведение со случайным целевым словом:

http://jsfiddle.net/s8XgJ/3/

Разметка

<center>
  Once upon a time, there was a squirrel who lived in the 
  <span class="centered">middle</span> of the forest. I 
  say middle, but without knowing where the edges were, 
  the squirrel had no idea where the center was.
</center>

Я сохранил вашу надбавку примерно, однако, как утверждают другие, вам следует избегать использования центральной метки. Я также преобразовал внутренний div в диапазон, чтобы сохранить интерлайн-интервал. Если это невозможно для вас, вы все равно можете использовать div, вам просто придется переопределить его нормальный дисплей display: inline-block;

JavaScript/jQuery

jQuery.fn.findYourCenter = function( target ){
  base = $(this); target = base.children(target);
  base.contents().eq(0).each(function(){
    var i = -1, word, words, found, dif,
      last = Infinity,
      node = $(this), 
      text = node.text().split(/\s+/),
      cwidth = Math.round(target.width() * 0.5),
      bwidth = Math.round(base.width() * 0.5),
      breaks = 2 // code will try to insert 2 line breaks
    ;
    node.replaceWith(
      '<span class="word">'+text.join(' </span><span class="word">')+' </span>'
    );
    words = base.find('.word');
    do {
      while ( ++i < words.length ){
        word && word.removeClass('clear');
        word = words.eq(i).addClass('clear');
        dif = Math.round(Math.abs((target.position().left + cwidth) - bwidth));
        if ( dif < last ) { last = dif; found = i; }
      }
      word.removeClass('clear');
      if ( found ) {
        words.eq(found).addClass('clear');
        i = found; found = word = null;
      }
      else {
        break;
      }
    } while ( i < words.length && --breaks );
  });
};

Я использовал jQuery для краткости.

CSS

Вам понадобится этот элемент CSS:

.clear:after {
  content: '';
  display: block;
  clear: both;
}

и, возможно, следующее, если ваш .centered элемент <div>:

.centered {
  display: inline-block;
}

Тогда все, что вам нужно выполнить, это:

jQuery(function($){
  $('center').findYourCenter('.centered');
});


проблемы

Чтобы получить точные данные, вам нужно будет что-то компенсировать -— из-за того, что в зависимости от длины (и размещения) слов вы не всегда можете достичь идеального центра для абзаца, строки и целевого слова одновременно. Вышеприведенный код по-прежнему удерживает линию по центру, за счет смещения целевого слова. Вы могли бы улучшить приведенное выше, чтобы внести изменения в маржу в строку, которая содержит целевой диапазон, если вы хотите центрировать слово за счет стоимости линии.

В настоящее время, если целевое слово появляется в первом слове пять слов, центрирование вряд ли будет достигнуто, в основном потому, что этот метод основан на переносе слов и разрыве строк. Если ни одно из них не может быть использовано из-за того, что слово находится в начале абзаца, тогда ничего не может быть сделано — за исключением ввода полей, отступов или текстового отступа.

Этот код основан на том, что он правильно считывает положение элементов <span>. Старые браузеры, например. IE6 и ранние версии Safari/Opera имели проблемы с этим.

Еще одно замечание. Этот код основывается на том, что браузер мгновенно вычисляет внутренние измерения в одном и том же синхронном цикле выполнения. Большинство современных браузеров, похоже, делают это & ​​mdash; в большинстве случаев; однако вы можете обнаружить, что вам нужно выполнить задержки setTimeout(func, 0) или setImmediate, чтобы это работало на старых системах.


... и, наконец,

Это скорее вопрос о бонкерах, для чего он нужен?:)

Ответ 2

[EDIT] Добавлена ​​скрипка. Убрал какой-то код. Обновленный фрагмент ниже. Добавлены комментарии.

http://jsfiddle.net/2Hgur/

[ОРИГИНАЛ] Я не верю, что это возможно с помощью css. Однако я решил, что с помощью JavaScript возможно решение. Итак, я попробовал, и это сработало! Хотя это может и не быть окончательным решением, рассмотрите следующее:

<div class="jsCenterOnPhrase">

The quick brown fox jumped over the lazy dog.
The quick brown fox jumped over the <div class="jsCenteredPhrase">lazy dog.</div>
The quick brown fox jumped over the lazy dog.
The quick brown fox jumped over the lazy dog.
The quick brown fox jumped over the lazy dog.

</div>

Затем сломайте его и перестройте, возможно, вот так:

jQuery(function ($) {

var $divParents = $('.jsCenterOnPhrase'); // all instances
var sMarker = '##'; // marker for phrase position

// for each instance
$divParents.each(function () {

    // closures
    var $parent = $(this);
    var $phrase = $parent.find('div.jsCenteredPhrase');

    // if there is only one phrase
    if ($phrase.size() == 1) {

        // more closures
        var iParentWidth = $parent.innerWidth();
        var sPhrase = $phrase.text();
        var iPhraseWidth = $phrase.outerWidth();
        $phrase.replaceWith(sMarker);
        var sFullText = $parent.text().replace(/\s+/g, ' ');
        // add html structure to container
        $parent.html(
            '<span class="jsLeftWrap"></span>' +
            '<span class="jsCenterWrap">' +
            '<span class="jsCenterPrefix"></span>' +
            '<span class="jsCenterPhrase"></span>' +
            '<span class="jsCenterSuffix"></span>' +
            '</span>' +
            '<span class="jsRightWrap"></span>');
        // more closures
        var $LeftWrap = $parent.find('.jsLeftWrap');
        var $CenterWrap = $parent.find('.jsCenterWrap');
        var $CenterPrefix = $parent.find('.jsCenterPrefix');
        var $CenterPhrase = $parent.find('.jsCenterPhrase');
        var $CenterSuffix = $parent.find('.jsCenterSuffix');
        var $RightWrap = $parent.find('.jsRightWrap');

        // get all the words left and right into arrays
        var iLeftStart = 0;
        var iLeftEnd = sFullText.indexOf(sMarker);
        var iRightStart = iLeftEnd + sMarker.length;
        var iRightEnd = sFullText.length - 1;
        var sFullLeft = sFullText.substring(iLeftStart, iLeftEnd);
        var sFullRight = sFullText.substring(iRightStart, iRightEnd);
        var aFullLeft = sFullLeft.split(' ');
        var aFullRight = sFullRight.split(' ');

        // build out each word as a node
        for (var i = 0; i < aFullLeft.length; i++) {
            var sVal = aFullLeft[i];
            if (sVal != '') {
                $('<span> ' + sVal + ' </span>').appendTo($LeftWrap);
            }
        }
        for (var i = 0; i < aFullRight.length; i++) {
            var sVal = aFullRight[i];
            if (sVal != '') {
                $('<span> ' + sVal + ' </span>').appendTo($RightWrap);
            }
        }

        // reset text as full html words
        sFullLeft = $LeftWrap.html();
        sFullRight = $RightWrap.html();

        var fResize = function () {
            // reset closures for dynamic sizing
            $LeftWrap.html(sFullLeft);
            $CenterPrefix.html('').css('padding-left', 0);
            $CenterPhrase.html('&nbsp;' + sPhrase + '&nbsp;');
            $CenterSuffix.html('').css('padding-right', 0);
            $RightWrap.html(sFullRight);
            iParentWidth = $parent.innerWidth();

            // private variables
            var $leftWords = $LeftWrap.find('span');
            var $rightWords = $RightWrap.find('span');
            var iMaxWidthRemaining = (iParentWidth - $CenterPhrase.outerWidth());
            var iMaxSideWidth = Math.floor(iMaxWidthRemaining / 2);
            var iLeftRemaining = iMaxSideWidth;
            var iRightRemaining = iMaxSideWidth;
            var iCurrentWidth = iPhraseWidth;
            var iLeftIndex = $leftWords.size() - 1; // work backwards
            var iRightIndex = 0; // work forwards
            var iKerningTollerance = 2; // wraps too much sometimes

            // loop trackers
            var bKeepGoing = true;
            var bKeepGoingRight = true;
            var bKeepGoingLeft = true;

            // loop while there is still room for the next word
            while (bKeepGoing) {

                // check the left side
                if (bKeepGoingLeft) {
                    // get the next left word
                    var $nextLeft = $leftWords.eq(iLeftIndex);
                    var iLeftWordWidth = $nextLeft.outerWidth();
                    if (iLeftWordWidth < iLeftRemaining) {
                        // there enough room.  add it.
                        $nextLeft.prependTo($CenterPrefix);
                        iLeftRemaining = iMaxSideWidth - $CenterPrefix.outerWidth();
                        iLeftIndex--;
                    } else {
                        // not enough room.  add remaining room as padding
                        bKeepGoingLeft = false;
                        $CenterPrefix.css('padding-left', (iLeftRemaining - iKerningTollerance));
                        iLeftRemaining = 0;
                    }
                }

                // check the right side
                if (bKeepGoingRight) {
                    // get the next right word
                    var $nextRight = $rightWords.eq(iRightIndex);
                    var iRightWordWidth = $nextRight.outerWidth();
                    if (iRightWordWidth < iRightRemaining) {
                        // there enough room.  add it.
                        $nextRight.appendTo($CenterSuffix);
                        iRightRemaining = iMaxSideWidth - $CenterSuffix.outerWidth();
                        iRightIndex++;
                    } else {
                        // not enough room.  add remaining room as padding
                        bKeepGoingRight = false;
                        $CenterSuffix.css('padding-right', (iRightRemaining - iKerningTollerance));
                        iRightRemaining = 0;
                    }
                }

                // is there room left on either side?
                bKeepGoing = bKeepGoingLeft || bKeepGoingRight;
            }

            // calculate where to put the breaks.
            var iTempWidth = iParentWidth;
            while (iLeftIndex > 0) {
                var $word = $leftWords.eq(iLeftIndex);
                iTempWidth = iTempWidth - $word.outerWidth();
                // account for kerning inconsistencies
                if (iTempWidth <= (2 * iKerningTollerance)) {
                    $('<br />').insertAfter($word);
                    iTempWidth = iParentWidth;
                } else {
                    iLeftIndex--;
                }
            }

        };

        // initial state
        fResize();

        $(window).resize(fResize);
    }
});

});

[ОБНОВЛЕНО ДЛЯ ТРЕБУЕМОЙ КОНВЕНЦИИ НАИМЕНОВАНИЕ... style = "centered":)]

Ответ 3

Ответ, к сожалению, вы не можете делать с HTML/CSS.

Для этого вам нужно либо установить некоторые ширины, чтобы заставить текст сломаться до следующей строки, либо (желательно) вставить тег <BR>, где вы хотите разбить строку. HTML и/или CSS не могут сделать это за вас. Как отмечает Андерсон ниже, вы сможете найти способ сделать это с JS, если это необходимо.

Ответ 4

Без разрыва слова вы не можете быть уверены, что искомое слово центрируется так же, как и строка.

Вот другой текст, первая версия - слово "кто", а строка не, вторая - противоположная:

 _________________________
|                         |
|        Once upon        |
|  a time, there lived a  |
|  squirrel who lived     |
|    somewhere else but   |
|      in the forest      |
|_________________________|
 _________________________
|                         |
|        Once upon        |
|  a time, there lived a  |
|    squirrel who lived   |
|    somewhere else but   |
|      in the forest      |
|_________________________|

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

В связи с этим существует четыре решения:

  • Поместите только нужное слово в эту строку, а затем попытайтесь убедиться, что theres точно столько же строк, как и после. (Возможно только в том случае, если слово не является первым или не последним, или это единственное слово в тексте, и если слово не находится примерно в середине текста, вы можете в конечном итоге иметь действительно arkward формы.)

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

  • Реализуйте функцию разрыва слова на языке текста и вычислите все комбинации возможных разрывов слов и строк, чтобы найти один (если есть), где ваше искомое слово центрировано.

  • Hardcode это сам, есть вещи, которые могут быть решены гораздо более эффективно человеком, чем простая программа (пока). В конце концов, мы хорошо разбираемся в суперкомпьютерах.

Ответ 5

Это действительно классный способ сделать это, используя javascript, который я сделал именно для вас! haha вот скрипка http://jsfiddle.net/7Ykzp/2/

var words = text.split(" ");

мы разделим его на слова, а затем постараемся поместить их на линию, которую мы помещаем в центр между двумя центрами, содержащими предыдущий и следующий текст

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

изменить: обновить, чтобы правильно разместить на основе длины слова
edit2: обновленный, теперь корректно обратный текст над надстрочным словом! проверьте это!

Ответ 6

Как было указано, его невозможно сделать через html/Css, который я тоже согласен, но вы можете сделать какое-то центрирование на основе строки (предложения), а не слова. Надеюсь, это поможет вам!

CSS

.centered  { display:inline-block; text-align:center;}
div {  width:100%; text-align:center; }

HTML:

 <div>  <div class="centered"> Once upon a time, </div> there lived a  <div class="centered"> squirrel who lived  in </div>  the middle of the forest.  </div>

Скриншот

Обновление: Как указано @disule, я удалил устаревший центральный тег.

Ответ 7

Единственный ответ на то, что вы хотите достичь: Это невозможно!

И я также сомневаюсь, что это будет иметь смысл. Чтобы центрировать слово в уже центрированной строке в центре текста - что это должно быть хорошо для??

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

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

Если вы действительно хотите, чтобы такое "отклонение" проходило и создавало изображение "на лету". В изображении вы можете достичь своей цели. С HTML, CSS и JS вы не будете.

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

Ответ 8

Самый простой способ - просто вставить разрыв строки <br> после каждой строки:

Вот пример jsfiddle

HTML:

<div class="container">
   <p>
     Once upon<br>
     a time, there lived a<br>  
     squirrel who lived in<br>
     the middle of<br>
     the forest.
   </p>
 </div>

CSS

.container {
    border: 1px solid #666;
    padding: 1em;
    width: auto;
    text-align: center
}

Ответ 9

Центральный тег устарел и не поддерживается в HTML5, поэтому не используйте его. Вместо этого дайте вашему классу .centered некоторые правила CSS, например:

.centered { 
    clear: both;
    display: block;
    text-align: center;
}

Однако это даст свою собственную линию. Если вы все еще хотите, чтобы текст вокруг него обертывался, вам придется систематически выбирать разрывы строк - нет текущего способа обернуть текст вокруг центрированного node, а float: center не существует...

Ответ 10

<div>
<p class ="center"> Once upon </p>
<p class ="center">a time, there lived a</p><p class = "center">squirrel who  
 lived in</p><p class = "center"> the middle of </p>
<p class = "center">
   the forest. 
</p>
</div>


  Try This with css code:

  .center{
    text-align:center;
    letter-spacing:2px;

   }

Ответ 11

Хотя я согласен с тем, что структура html имеет проблемы, вы говорите, что у вас есть "небольшой контроль", поэтому я предлагаю этот ответ исключительно с HTML как есть. Не касаясь HTML, единственный способ получить это с помощью чистого CSS - позволить центрированному контенту существовать в отдельной строке. Так что это работает (см. Скрипку):

center {
    text-align: center;
}
center div {
    width: 100%; /* really, the div should default to this, but just in case */
}

Ответ 12

Используйте CSS более конкретно в родительских элементах, чтобы настроить выравнивание слов. Например, если есть параграф (p), а затем после него они являются двумя divs (div), то используйте определенное свойство родительского css, как это.

p div div {text-align:center; display:inline-block;} 

что он и он сделает для вас работу. Аналогичным образом вы можете настроить целевой пример с помощью

center div {text-align:center; display:inline-block;}

Ответ 13

У вас есть связанный файл CSS? Если вы это сделаете, я бы рекомендовал изменить тег div на

<div class="who">who</div>

В файле CSS вы должны иметь

.who { 
  text-align: center; 
}

Также возможно, что вы заставляете html включать пробелы со следующим кодом: & nbsp (Включите точку с запятой в конце, это не позволит мне это сделать). Поэтому вместо того, чтобы иметь одно пространство, вы можете иметь несколько неразрывных пробелов.

Ответ 14

Является ли ваш div фиксированной шириной или переменной шириной? Если это фиксированная ширина (указанная вами демо-ширина), добавьте предыдущее и следующее слово в div и добавьте
до и после.

Когда-то существовала белка
, которая жила
посреди леса.

а затем выравнивание по центру абзаца.

.centered {text-align: center}

Если div является переменной шириной, вы можете попробовать функцию JavaScript, которая принимает размер div и размер шрифта в качестве аргументов, и это решит, сколько слов (как до, так и после) должно быть добавлено.

Это обходное решение, которое в основном пытается вставить как можно больше слов в строку. Поскольку после "центра" добавляется слово для каждого слова, добавленного до "центра", ваше слово должно оставаться посередине.

Ответ 15

Метод дровосека - это теги <br/>

HTML:

<div class="center">
    <p>Once upon<br>
    a time, there lived a<br>  
    squirrel who lived in<br> 
    the middle of<br>
    the forest.</p>
</div>

CSS

.center {
    width: auto;
    text-align: center;
}

Ответ 16

Вы можете просто сделать это таким образом.

Скриншот Демо

код:

<div style="position:absolute; left:50%; margin-left:-108px;">
 <pre>
 _________________________
|                         |
| Once upon a time, there |
|   lived a squirrel who  |
|  lived in the middle of |
|       the forest.       |
|_________________________|
    </pre>
    </div>