Динамическое изменение размера шрифта на jQuery

Публикация статьи «Умные динамические колонки с применением CSS и jQuery» стала поводом для написания сегодняшнего поста. Суть очень схожа и речь здесь пойдет про размер шрифта.

Задача — реализовать динамическое изменение размера шрифта сайта в зависимости от разрешения экрана, т.е. размера окна браузера.

Прежде чем приступить к описанию решения, хочу обозначить два момента:

  1. Лично для меня полезность данной штуки весьма сомнительна, и я скорее бы рассматривал такую возможность просто в качестве ознакомления. А вот Сергей, например, эту технику давно хотел применить на практике и видит в ней смысл. Поэтому, возможно, кому-нибудь еще эта информация также пригодится.
  2. Решение довольно простое, работает на моем любимом jQuery, но использование этого фреймворка только ради осуществления данной задачи — не очень разумно, поскольку один лишь фреймворк «весит» под 60 Кб, а сам скрипт при этом состоит из всего лишь 10 строк. Я полагаю, что на нативном JavaScript скрипт, реализующий то же самое, будет значительно меньшего размера.

Итак, приступим.

Сначала я подробно опишу работу jQuery-скрипта, а затем объясню, как его применить к той или иной части веб-сайта.

jQuery

За точку отсчета я взял ширину в 1000 пикселей. Как правило, это минимальная ширина, под которую верстаются сайты. Заносим этот показатель в переменную:

var width = 1000;

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

var fontSize = 12;

Далее считываем ширину хтмл-документа, которую также заносим в переменную:

var bodyWidth = $('html').width();

Определяем коэффициент, на который будет умножаться базовый (минимальный) размер шрифта в зависимости от размера окна браузера. Цифру получаем путем деления ширины хтмл-документа на базовую (минимальную) ширину. Т.е., к примеру, если ширина окна браузера составляет 1600 пикселей, то получим коэффициент 1,6.

var multiplier = bodyWidth / width;

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

if ($('html').width() >= width) fontSize = Math.floor(fontSize * multiplier);

Теперь полученный скорректированный размер шрифта применяем к тегу <body>:

$('body').css({fontSize: fontSize+'px'});

Все вышеописанные строки помещаем в функцию function fontSize() {}, затем запускаем эту функцию после загрузки хтмл-документа, а также после изменения размера окна браузера:

$(function() { fontSize(); });
$(window).resize(function() { fontSize(); });

Вот целиком код jQuery-скрипта, который получился у нас в итоге:

function fontSize() {
	var width = 1000; // ширина, от которой идет отсчет
	var fontSize = 12; // минимальный размер шрифта
	var bodyWidth = $('html').width();
	var multiplier = bodyWidth / width;
	if ($('html').width() >= width) fontSize = Math.floor(fontSize * multiplier);
	$('body').css({fontSize: fontSize+'px'});
}
$(function() { fontSize(); });
$(window).resize(function() { fontSize(); });

HTML

Рассмотрим применение вышеуказанного скрипта на примере 3-колоночного макета страницы, имеющего следующую структуру HTML-кода:

<div id="wrapper">
	<div id="header"></div>
	<div id="middle">
		<div id="container">
			<div id="content"></div>
		</div><!-- #container-->
		<div id="left"></div>
		<div id="right"></div>
	</div><!-- #middle-->
	<div id="footer"></div>
</div><!-- #wrapper -->

CSS

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

Все очень просто.

Во-первых, правой колонке мы просто-напросто устанавливаем свой фиксированный размер шрифта и высоту строки, и скрипт его не затронет:

#right {
 font-size: 12px;
 line-height: 18px;
}

Во-вторых, левой колонке ставим чуть меньший размер шрифта:

#left {
 font-size: 0.9em;
}

В-третьих, нужно либо у тега <body>, либо у соответствующего блока указать высоту строки в em, чтобы она тоже изменялась динамически.

Вот, в принципе, и все.

Пример динамического изменения размера шрифта на jQuery

Если вы хотите менять размер шрифта только у конкретного блока, допустим, у #content, тогда будет логичнее в скрипте поменять body (в строке $('body').css({fontSize: fontSize+'px'});) на нужный идентификатор или класс.

Комментарии (26)
  1. 1
    vladfrandom
    @

    Если уж так приспичило использовать разный размер шрифта при разных размерах экрана для удобства чтения текста, то можно ведь воспользоваться абсолютными единицами измерения. Absolute length units

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

  2. 5
    @

    Спасибо, Дима за подробную статью и пример.
    Он, как раз наглядно показывает, что при разрешении 1600*900 и выше читать текст в колонке, где не происходит динамической подстройки размера шрифта, практически невозможно :)
    Понятно, что предложенное решение далеко от идеала, но мне кажется, это правильный путь.

    Ведь не даром и у тебя и у многих других, есть возможность выбора размера шрифта не только средствами браузера.
    К тому же, если размер указан в px, то в IE не работает.

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

  3. 6

    Он, как раз наглядно показывает, что при разрешении 1600*900 и выше читать текст в колонке, где не происходит динамической подстройки размера шрифта, практически невозможно :)

    Абсолютно не соглашусь. Если говорить о данном конкретном примере, мне гораздо удобнее читать текст именно в этой колонке (независимо от разрешения экрана), чем в тех, где размер меняется.

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

    Да, недаром. Но здесь предоставляется ВЫБОР. А ты хочешь автоматизировать, лишая пользователя права выбора.

    Думаю, простому пользователю, будет гораздо удобнее, если автомат есть

    А у меня противоположное мнение =)))

    Да и скрипт нужен с более плавными регулировками и дополнительными настройками

    Вот с этим согласен. В таком виде, как сейчас, сложно говорить о практичности скрипта.

    • 7
      @

      …мне гораздо удобнее читать текст именно в этой колонке…

      Дима, то, что нравится тебе или мне, никому не важно :)
      Главное, чтобы было удобно пользователю, без лишних действий с его стороны, вот за это он скажет, только спасибо.
      Ленивые мы все, нам автомат подавай :)
      К тому же не у всех 100% зрение.

      Но здесь предоставляется ВЫБОР.

      Тут, то же можно поспорить :)
      По жизни, часто выбора нет, никто от этого не умер, если все будет сделано грамотно и разумно, выбор по сути будет не нужен. Ты же не даешь пользователю возможности сменить начертание и гарнитуру шрифта, может ему больше «verdana» нравится и «italic» с «bold» в придачу:)
      Часто только кажется, что мы кому-то даем право выбора, на самом деле это не совсем так :)

      В таком виде, как сейчас…

      Думаем, делаем, решаем :)

      • 8

        В общем, пока не будет решения поинтереснее этого, спорить дальше не вижу смысла =) Желаю удачи в поисках.

        • 9
          @

          …спорить дальше не вижу смысла…

          Какой спор, Дима :)
          Мысли вслух, не более.
          Никто не говорит, что это надо сделать обязательным для всех.
          Альтернатива и компромисс.
          Как всегда и везде :)

  4. 10

    Нашел пример на чистом JavaScript — http://www.tinnedfruit.com/sandbox/textzoom.html

  5. 11
    @

    Спасибо, Дима.
    Сейчас болею, потом внимательно посмотрю.

  6. 12
    @
    /*========CSS============*/
    html {font-size:100.01%}/*Для оперы*/
    body {font-size:62.5% } /*устанавливаем базовый шрифт в 10px, для простоты расчётов в относительных велечинах*/
    
    function fontSize() {
    	var width = 1000; // ширина, от которой идет отсчет
    	var fontSize = 62.5; // минимальный размер шрифта
    	var bodyWidth = document.documentElement.clientWidth;
    	var multiplier = bodyWidth / width; // проверку убрал, пусть шрифт уменьшается если разрешение меньше 1000
    	fontSize = Math.floor(fontSize * multiplier);
    	document.body.style.fontSize = fontSize+'%';
    }
    window.onload = fontSize; 
    window.onresize = fontSize; // так добавлять обработчики не тру, но для наглядности покатит
    

    Кстати офигенная тема, если большинство размеров указывать в относительных еденицах (em) не только размер шрифта но и ширину колонок и отступы, то получается псевдо резиновый макет. Вроде размерами всё зафиксировано, но если изменять базовый шрифт за счёт ресайза то и ширина колонок будет менятся.

    P.S. для тех кто не втеме — у боди выставляется font-size в 62.5% для простоты расчётов, так как 62.5% = 10px, то становится легчк расчитывать размеры например 200px = 20em 12px = 1.2em. Только важно помнить что em относительно рдительского блока, т.е. если вы поменяли блоку размер шрифта то надо уже считать от нового базового размера, но для этих целей есть полезная штука — em калькулятор

    • 13

      Спасибо за решение! Не зря я говорил, что на чистом JavaScript то же самое будет значительно меньшего размера. Здесь количество кода такое же, как в моем скрипте, но за вычетом веса целого фреймворка =)

  7. 14
    @

    http://www.tinnedfruit.com/ — многа букафф в коде. Лучше написать 10 строчек (хотя если написать правильную функцию для назначения обработчика события, строчек будет больше, спасибо MSIE), под конкретный проэкт чем юзать готовый универсальный скрипт, в котором создаётся обьект в 2-3 раза больше чем малнеькая функция.

  8. 15

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

  9. 16
    @

    Закрутился и забыл :)
    Вот линк, на ветку форума, где эта проблема нашла решение без библиотеки jQuery.
    Примеры соотвествующие там есть.

  10. 21
    Борис
    @

    увы, ничего не изменилось :(
    так же режет бока

  11. 22
    alovi

    если на сайте всего 1 скрипт для шрифта, то конечно можно искать решение с наименьшими затратами, но если используешь jQuery не только для динамического шрифта, а для еще всяких украшательств и то это решение просто супер.

  12. 25
    Владимир
    @

    Подскажите скрипт для динамического изменения зависимости величины em от ширины окна браузера?

  13. 26
    Ы

    решение одной строчкой

    onload = onresize = function() { document.body.style.fontSize = parseInt(document.body.offsetWidth/80) + ‘px’ }

    http://forum.htmlbook.ru/index.php?s=10086d83503058ea0313941acbec4891&showtopic=14800&view=findpost&p=103593