Чистый CSS, чтобы сделать размер шрифта отзывчивым на основе динамического количества символов

207

Я знаю, что это можно довольно легко решить с помощью Javascript, но меня интересует только чистое решение CSS.

Мне нужен способ динамического изменения размера текста, чтобы он всегда вписывался в фиксированный div. Вот пример разметки:

<div style="width: 200px; height: 1em; overflow: hidden;">
  <p>Some sample dynamic amount of text here</p>
</div>

Я думал, что, возможно, это возможно, указав ширину контейнера в ems и получив размер шрифта для наследования этого значения?

  • 1
    Вау, подожди. Указание width в em происходит наоборот. Это width которая зависит от font-size . @JosephSilber Это именно то, что я думал.
  • 1
    Мне интересно этот вопрос. Каков привод использовать чистое решение CSS вместо написания простой функции JavaScript?
Показать ещё 3 комментария
Теги:

7 ответов

372
Лучший ответ

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

p {
    font-size: 30px;
    font-size: 3.5vw;
}

http://css-tricks.com/viewport-sized-typography/ а также https://medium.com/design-ux/66bddb327bb1

  • 30
    Даст 2 взлёта за это. CSS решения для победы!
  • 7
    О, я скучал по этим! Так что теперь у нас есть em, ex, ch, rem, vh, vh, vmin, vmax, px, mm, cm, in, pt и pc! Mozilla Doc
Показать ещё 16 комментариев
92

CSS3 поддерживает новые измерения, относящиеся к виду порта. Но это не работает в android < 4.4

  • 3.2vw = 3.2% ширины окна просмотра
  • 3.2vh = 3.2% высоты окна просмотра
  • 3.2vmin = Меньше 3.2vw или 3.2vh
  • 3.2vmax = Больше 3.2vw или 3.2vh

    body
    {
        font-size: 3.2vw;
    }
    

см. css-tricks.com/...., а также посмотрите caniuse.com/....

или

Используйте медиа-запрос. Самый простой способ - использовать измерения в% или em. Просто измените размер базового шрифта, все изменится.

@media (max-width: @screen-xs) {
    body{font-size: 10px;}
}

@media (max-width: @screen-sm) {
    body{font-size: 14px;}
}


h5{
    font-size: 1.4em;
}

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

см. kyleschaeffer.com/.... для получения дополнительной информации о em, px и%

  • 0
    Теперь, похоже, работает на Android тоже! :-)
  • 0
    @werner спасибо обновлено
Показать ещё 2 комментария
12

Единственный способ, вероятно, состоит в том, чтобы устанавливать разные ширины для разных размеров экрана, но этот подход довольно неуверен, и вы должны использовать js-решение.

h1 {
    font-size: 20px;
}

@media all and (max-device-width: 720px){
    h1 {
        font-size: 18px;
    }
}

@media all and (max-device-width: 640px){
    h1 {
        font-size: 16px;
    }
}

@media all and (max-device-width: 320px){
    h1 {
        font-size: 12px;
    }
}
10

Я знаю, что у меня возник вопрос с длинными мертвыми, но у меня был тот же вопрос, и я хотел что-то добавить. Пожалуйста, не запрещайте мне это, я чувствовал, что это достаточно важно, чтобы оправдать этот ответ, я удалю, если потребуется. @Joseph Silber ошибается, кодирование всех возможностей на самом деле является жизнеспособным способом сделать это. Причина в том, что на самом деле нет бесконечных возможностей. Ну, технически есть, но 99% ваших посетителей будут использовать стандартное разрешение. Это вдвойне верно для мобильных устройств (основная причина для гибкого веб-дизайна), поскольку большинство мобильных ОС запускают приложения на весь экран без изменения размера окна.

Кроме того, высота довольно неуместна из-за полосы прокрутки (до точки я сразу же покинул бы веб-страницу длиной более 4 или 5 футов, но в основном это верно), поэтому вам нужно только беспокоиться о ширина. И действительно, единственной шириной, которую вам нужно кодировать, являются следующие: 240, 320, 480 (для старых iThings), 640, 800, 1024, 1280, 1440, 1600, 1920, 2048, 2560. Даже не потрудитесь 4k, он слишком сильно раздувает ваши изображения, а размер 2560, растянутый до 100%, будет отлично смотреться на мониторе 4k (я протестировал это). Кроме того, не беспокойтесь о 720 (720x480), как предлагал предыдущий плакат. Его разрешение используется почти исключительно цифровыми камерами, и даже тогда очень редко.

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

  • 1
    А теперь 375 и 414 для iPhone 6/6 +: - /
  • 0
    Потенциально еще проще, если использовать SASS или Compass и войти в функции. Функция может сделать всю эту работу CSS за вас; однократной записи потребительной много.
Показать ещё 1 комментарий
5

Вас может заинтересовать подход calc:

font-size: calc(4vw + 4vh + 2vmin);

сделано. Значение Tweak соответствует вашему вкусу.

Источник: https://codepen.io/CrocoDillon/pen/fBJxu

  • 1
    Вы спасли мой день, приятель. Спасибо. +1 для вас :)
1

Как упоминалось в комментариях к сообщению @DMTinter, OP спрашивал о количестве ( "сумме" ) символов. Он также спрашивал о CSS, но, как отметил @Alexander, "это невозможно с помощью только CSS". Насколько я могу судить, это кажется правдой в это время, поэтому также кажется логичным, что люди захотят узнать следующее лучшее.

Я не особенно горжусь этим, но он действительно работает. Похоже на чрезмерное количество кода для его выполнения. Это ядро:

function fitText(el){
  var text = el.text();
  var fsize = parseInt(el.css('font-size'));
  var measured = measureText(text, fsize);

  if (measured.width > el.width()){
    console.log('reducing');
    while(true){
      fsize = parseInt(el.css('font-size'));
      var m = measureText(text, fsize );
      if(m.width > el.width()){
        el.css('font-size', --fsize + 'px');
      }
      else{
        break;
      }
    }
  }
  else if (measured.width < el.width()){
    console.log('increasing');
    while(true){
      fsize = parseInt(el.css('font-size'));
      var m = measureText(text, fsize);
      if(m.width < el.width()-4){ // not sure why -4 is needed (often)
        el.css('font-size', ++fsize + 'px');
      }
      else{
        break;
      }
    }
  }
}

Здесь JS Bin: http://jsbin.com/pidavon/edit?html,css,js,console,output
Пожалуйста, предложите возможные улучшения в этом (мне не очень интересно использовать холст для измерения текста... кажется слишком много служебных (?)).

Благодаря функции @Pete для функции measureText: https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript

0

Это решение также может помочь:

$(document).ready(function () {
    $(window).resize(function() {
        if ($(window).width() < 600) {
            $('body').css('font-size', '2.8vw' );
        } else if ($(window).width() >= 600 && $(window).width() < 750) {
            $('body').css('font-size', '2.4vw');
        } 
         // and so on... (according to our needs)
        } else if ($(window).width() >= 1200) {
            $('body').css('font-size', '1.2vw');
        }
    }); 
  });

Это сработало для меня хорошо!

  • 0
    Как это учитывает перенос слов?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню