Динамическое изменение размера шрифта на 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'});) на нужный идентификатор или класс.

Комментарии (25)

  1. vladfrandom
    5 июня 2009 г. в 14:26

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

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

    1. Надо будет проверить, что из себя представляют эти единицы изменения. Вообще с ними незнаком. Спасибо за инфу.

    2. Что-то я не понял, как этими единицами пользоваться и каким образом они соприкасаются с темой. Примеры какие-нибудь можете показать?

      1. gordi
        5 июня 2009 г. в 19:22 / ответ на коммент Dimox

        Что-то я не понял…

        Аналогично :(
        Сижу разбираюсь, не клеется что-то :)

  2. gordi
    5 июня 2009 г. в 16:52

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

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

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

  3. 5 июня 2009 г. в 17:36

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

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

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

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

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

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

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

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

    1. gordi
      5 июня 2009 г. в 17:57 / ответ на коммент Dimox

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

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

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

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

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

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

      1. 5 июня 2009 г. в 18:28 / ответ на коммент gordi

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

        1. gordi
          5 июня 2009 г. в 18:36 / ответ на коммент Dimox

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

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

  4. 11 июня 2009 г. в 19:42

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

  5. gordi
    11 июня 2009 г. в 20:59

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

  6. 23 июня 2009 г. в 05:43
    /*========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 калькулятор

    1. 23 июня 2009 г. в 09:10 / ответ на коммент Jman

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

  7. 23 июня 2009 г. в 06:16

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

  8. 23 июня 2009 г. в 11:19

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

  9. gordi
    23 июня 2009 г. в 13:06

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

    1. 23 июня 2009 г. в 13:29 / ответ на коммент gordi

      Ну вот, видишь как здорово получилось, всего 4 строки JavaScript и без всяких jQuery =) Все гораздо проще, чем кажется.

      1. gordi
        23 июня 2009 г. в 13:38 / ответ на коммент Dimox

        Дим, начиналось-то все, с твоего поста :)
        А так конечно.
        Будем доводить до ума – проценты, em – все перепробуем :)

    2. Борис
      9 июля 2009 г. в 08:40 / ответ на коммент gordi

      в лисе-2 неработает – режет боковые колонки:(

  10. Борис
    16 июля 2009 г. в 00:04

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

  11. alovi
    21 апреля 2010 г. в 08:07

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

    1. Юрий
      11 января 2011 г. в 18:12 / ответ на коммент alovi

      Супер! Спасибо за статью. Очень пригодилась.
      А можно установить максимальный размер шрифта больше которого текст увеличиваться не должен?

      1. 12 января 2011 г. в 11:20 / ответ на коммент Юрий

        Перед этой строкой:

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

        добавьте следующие:

        var fontSize2 = 13; // максимальный размер шрифта
        if (fontSize >= fontSize2) fontSize = fontSize2;
  12. Владимир
    1 апреля 2012 г. в 00:19

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

  13. Ы
    2 апреля 2012 г. в 21:24

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

    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

Ваш комментарий

Жирный текст

Ссылка

Цитата

Внутристрочный код

CSS-код

HTML-код

JavaScript-код

PHP-код