• Равномерный фон под текстом

    Одно из модных направлений веб-дизайна последних лет — оформление заголовков контрастным фоном. Например, вот так:

    example

    Простая, на первый взгляд, задача решается не так уж и просто: первая же мысль «добавить padding» натыкается на то, что отступ добавляется исключительно в начале и в конце текста, игнорируя переносы:

    padding

    Ближе всех к решению задачи когда-то подошёл akella, добавив border у родительского элемента. Но проблема не решена на 100%: в конце первой строки (место, где переносятся слова) всё равно нет отступа. Решения остальных ребят, которые присылались мне в твиттер, грешили одной и той же проблемой: нужно точно указать место разрыва строк.

    В простейшем случае, когда нужно добавить небольшой отступ, решение оказалось до боли простым. Есть одно «паразитное» CSS-свойство, от которого кодеры обычно избавляются — это свойство outline. Его особенность заключается в том, что во всех браузерах (по крайней мере в тех, в которых я проверял: Safari 4, Firefox 3.5, Opera 10, IE8) контур outline точно повторяет границы текстового элемента. Соответственно, эта строчка кода полностью решает нашу проблему:

    span.uniform-bg {
    	outline: red solid 0.3em;
    }
    

    Не обошлось без ложки дёгтя: в данном случае «плохим мальчиком» оказался Firefox. Во-первых, он иногда рисует контур с небольшим отступом от границ текста, а во-вторых — прочерчивает его между строками, перекрывая текст:

    firefox

    Первая проблема решается довольно просто: достаточно немного «втянуть» контур с помощью CSS-свойства outline-offset (либо -moz-outline-offset, эксклюзивно для Firefox), вторая — добавлением ещё одной обёртки с position:relative, чтобы поднять текст над контуром.

    Итоговое решение выглядит так:

    <style type="text/css">
    	.uniform-bg {
    		background:red;
    		position:relative;
    		outline: red solid 0.3em;
    		-moz-outline-offset:-0.04em;
    	}
    
    	.uniform-bg span {
    		position:relative;
    	}
    </style>
    <h2><span class="uniform-bg"><span>Hello everyone</span></span></h2>
    

    Оно не работает в IE6—7, в них не поддерживается свойство outline. Но, так как это исключительно декоративная задача, можно объединить её с решением от akella и получить почти идеальное решение.

    UPD: читатель Roman указал на баг в отрисовке фона в месте переноса строк в IE6—7. Немножко доработать напильником — и получится вполне приличное решение (обновил пример).

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

    Второй способ (upd)

    Тот же читатель Roman предложил ещё один способ решения задачи. Он основан на смещении трех слоёв относительно друг друга: например, если отступ равен x, то второй слой смещается на 2x вправо, а третий на –x, влево:

    method2

    Его можно немного упростить, убрав один слой и добавив левый border у контейнера. Способ более гибкий, чем с outline (который, как выяснилось, не очень дружит с Opera). На основе него я хотел сделать решение с фоновой картинкой, но столкнулся проблемой: вместе с переносом строк переносится и фон, то есть во второй строке фон начинается там же, где заканчивается в первой:

    bg-problem

    Метки: , , ,
  • CSS-свойство content: копировать или нет?

    Решил я для очередного своего проекта воспользоваться модным CSS-свойством content, чтобы немного облегчить страницу и сделать настройку внешнего вида более гибкой. Так как проект ориентирован на веб-разработчиков, об обратной совместимости со старыми браузерами (IE6—7) можно было не беспокоится. Но, к сожалению, меня ожидало большое разочарование от использования этого свойства. Нет, всё отображалось правильно, но конечному пользователю было бы неудобно пользоваться результатом.

    Что такое CSS-свойство content

    Кому ещё не удалось познакомиться с этим замечательным свойством, кратко расскажу о нём. Само название этого свойства говорит о том, что оно управляет неким содержимым. Согласно спецификации CSS2 это свойство применяется только к псевдо-элементам :before и :after, а с версии CSS3 станет доступно и для обычных элементов (небольшой реверанс в сторону Opera, которая это уже поддерживает).

    С помощью свойства content мы можем через CSS задавать текстовое содержимое для (псевдо-)элементов. Классический пример применения этого свойства — вывод содержимого ссылки рядом с элементом в версии сайта для печати:

    <style type="text/css">
    	a:after {
    		content: ' (' attr(href) ')';
    	}
    </style>
    <p>В нашем <a href="/catalog/">каталоге</a> вы найдёте много чего интересного.</p>
    

    С помощью псевдо-элемента :after мы задали некое содержимое после тэга <a>. Этим содержимым является результат конкатенации строк и функции attr(), которая выводит содержимое атрибута контекстного элемента. Браузер, полностью поддерживающий CSS2, изобразит этот код примерно так:

    content-example

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

    Проблема

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

    Проект, который я сейчас делаю, является инструментом для удобной работы с XML-документами. Для вывода раскрашенного дерева элементов я и решил воспользоваться вышеозначенным свойством:

    <style type="text/css">
    	.tag:before {
    		content:'<';
    	}
    
    	.tag:after {
    		content:'>';
    	}
    
    	.attr-value {
    		quotes:'"' '"';
    	}
    
    	.attr-value:before {
    		content:open-quote;
    	}
    
    	.attr-value:after {
    		content:close-quote;
    	}
    </style>
    <div class="tag">div <span class="attr-name">class</span>=<q class="attr-value">demo</q></div>
    

    Плюсы такого подхода: потребуется гораздо меньше элементов для раскраски тэгов (через псевдо-элементы :before и :after я могу задать произвольный цвет у угловых скобок). Для значений атрибутов я воспользовался тэгом <q> и CSS-свойством quotes, через которое определяются открывающие и закрывающие кавычки. Кому-то нравится использовать двойные кавычки в коде, кому-то — ординарные, при таком подходе их можно на лету поменять у всего документа. Как оказалось, выбор этого тэга и CSS-свойства стал важной частью эксперимента.

    В браузерах этот код выглядит замечательно:

    content-example2

    Но XML-документ должен не только красиво выглядеть, но и правильно работать: пользователь имеет право без проблем выделить и скопировать фрагмента документа, чтобы воспользоваться им, например, в своём любимом редакторе. И тут меня ожидало полное разочарование от использования свойства content. Я проверил результат копирования в своих браузерах — Safari 4, Opera 10, Firefox 3.5, IE8 — и получил вот такой результат:

    • Safari: div class=demo
    • Opera: <div class="demo">
    • Firefox: div class="demo"
    • IE8: <div class="demo">

    Как видите, все скопировали текст по-разному: Safari не скопировал content-данные в принципе, Opera и IE8 скопировали всё, а Firefox скопировал только кавычки вокруг атрибута.

    Затем я решил вместо вместо элемента <q> написать обычный <span>, и получил вот такой результат:

    • Safari: div class=demo
    • Opera: <div class="demo">
    • Firefox: div class=demo
    • IE8: <div class="demo">

    Всё то же самое, но Firefox уже не скопировал кавычки.

    Выводы

    Из этого небольшого эксперимента я сделал для себя следующие выводы:

    • Safari в принципе не понимает CSS-свойство quotes. То, что браузер отобразил кавычки вокруг <q> элемента — исключительно стандартная реакция на него. Кавычки нельзя будет поменять через свойство quotes, например, на ординарные — они так и останутся двойными. А если элемент переименовать в <span>, то и вовсе пропадут.
    • Firefox при копировании текста обращает внимание на название элемента: если это <q> — кавычки скопируются, для другого элемента получите пустоту.
    • Firefox всегда копирует двойные кавычки для тэга <q>, даже если вы измените их на что-нибудь другое (на «ёлочки», например). То есть сделать трюк с управлением копирования символов у вас не получится. Либо двойные кавычки, либо ничего.
    • IE8 при копировании обращает внимание на тип элемента: например, если прописать тэгу display: list-item, то скопируется буллит (хотя на странице он не будет отображаться).

    В общем, выводы далеко не самые приятные. С помощью свойства content я не смогу сделать кроссбраузерное решение: и когда нужно копировать эти данные, и когда не нужно (например, нумерация строк в листинге кода). Как это часто бывает, радостные вопли неискушённых кодеров и красивые демонстрации маркетологов ломаются в момент «боевого» применения, когда нужно вкладывать смысл в свою работу, а не просто следовать модным тенденциям. Поэтому до сих пор приходится делать всё по-старинке.

  • Ищу помощника

    Мне в компанию очень нужен помощник или помощница.

    UPD: ваканся закрыта, но скоро мне ещё понадобятся сотрудники. Если интересно — пишите.

    Исходные данные

    Есть проект Аймобилко, где я являюсь техдиректором и лицом, всячески заинтересованным в повышении количества продаж и качества предоставляемых услуг. Сайт написан на Java (этим занимается отдельный человек), использует связку XML/XSL для генерации результата. На сайте много JS-скриптов (исходники весят около 1,5 МБ, без учёта подпроектов).

    Моя основная цель — сделать удобный проект для продажи цифрового контента. Именно поэтому там нет мудацкой регистрации с капчей или обязательным подтверждением по электронной почте, а любую покупку можно совершить буквально в два клика без регистрации. Это как бы намекает, что мы не перекладываем программерские проблемы (вроде большого количества «левых» регистраций) на пользователя, а сами их успешно решаем, но на это требуется больше времени и сил.

    В работе используются инструменты по следующим ключевым словам: Eclipse, Ant, XSL, XML, HTML, CSS, JavaScript, Python, SVN, Redmine, Mylyn.

    Что требуется

    Нужен человек на полный рабочий день, который будет верстать новые и дорабатывать старые макеты, делать из них XSL-шаблоны и прикручивать к сайту. Знание XSL очень желательно, но не обязательно; если надо — научу. Это минимум.

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

    Что делать

    Если вам интересна эта вакансия, напишите мне на serge.che@gmail.com письмо с кратким рассказом о себе, а также 3—4 ссылки на свои самые интересные работы. Хочу сразу предупредить, что:

    • меня тянет блевать от словосочетаний вроде «валидная семантичная вёрстка», «пора переходить на html5» и прочих задротских умопомешательств;
    • за слова «это сделать невозможно» буду сразу бить по башке;
    • я до сих пор поддерживаю IE6 на необходимом минимуме: главное, чтобы всё работало и выглядело прилично, но можно без тенюшек и скруглённых уголков;
    • нужен человек, который будет участвовать в жизни проекта, а не делать работу за зарплату (которая по результатам собеседования).

    Офис находится в районе м. Павелецкая.

    Метки:
  • Вёрстка растягивающихся сайтов

    В этой статье я поделюсь способом вёрстки растягивающихся сайтов (а других, как оказалось, я верстать не умею), которым пользуюсь последние 2—3 года. Этот способ применяется для сложных модульных сеток; он лёгок в применении, но сложен в понимании и у него есть ряд недостатков. В целом, представленная здесь информация пригодится и веб-дизайнерам, так как сам макет сайта должен быть правильно подготовлен.

    Начнём с простого. Предположим, у нас есть вот такой макет растягивающегося сайт:

    01

    На первый взгляд всё довольно просто: типовая трёхколоночная сетка (ширина колонки — 25%), одна колонка — меню, две колонки — контент, и всё это располагается по центру. Типовая вёрсткой такого макета может быть следующей: заключаем оба блока в контейнер шириной 75%; меню в этом случае будет шириной 33%, контент — 67%. Саму обёртку выравниваем по центру с помощью margin: 0 auto, либо просто смещаем влево. Первый способ предпочтительнее, так как ведёт себя адекватно, если мы ограничим минимальную ширину обёртки. Визуализация этого решения:

    02

    Проблема

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

    03

    Причём дизайнер хочет, чтобы левая граница этого блока пиксель-в-пиксель совпадала с левой границей меню (оставим в стороне дебаты «кому это нужно» и «никто не заметит, если на пару пикселей…» в стороне, мы решаем конкретную задачу).

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

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

    Но вернёмся к нашей задачке: как же расположить оранжевый блок так, чтобы его левая граница совпадала с левой границей меню? Мы уже решили, что этот блок должен быть частью контента, а не модульной сетки. Тем более, что блок контекстный (то есть привязан к какому-то определённому фрагменту текста, а не просто болтается где-то слева).

    Ширина контента — 67%, меню — 33%. Чтобы блок встал ровно, его нужно сместить на 49.25% (33 / 67 * 100 ≈ 49.25). Во-первых, наш результат получился приблизительным, во-вторых, все браузеры (кроме Firefox 3) довольно своеобразно работают с дробными процентами (да и с процентами вообще), а некоторые вообще их не воспринимают. В итоге получается, что у нас нет кросс-браузерного способа совместить эти блоки при выбранной разметке.

    Поиск решения

    Решением этой проблемы, как вы уже догадались, будет выбор другого способа разметки модульной сетки, который позволит нам вытворят такие (и не только) трюки. Посмотрим внимательнее на сам макет:

    01

    Внимательный читатель обратит внимание на то, что ширина меню ровно в 2 раза меньше ширины контента (50 / 25 = 2). Деление получается целочисленным (нет дробей), а значит мы можем создать кросс-браузерное и — самое главное — точное решение проблемы.

    Поступим следующим образом. Завернём оба блока в контейнер, ширина которого будет не 75%, как раньше, а 50% (то есть равна ширине контента). Сам контент будет шириной 100%, а меню — 50%, при этом смещено влево на свою ширину.

    04

    Приблизительный код этого примера:

    <style type="text/css">
    	#page {
    		position:relative;
    		margin:0 auto;
    		width:50%;
    		left:10%;
    	}
    
    	#menu {
    		width:50%;
    		margin-right:-50%; /* чтобы правильно в IE работало */
    		position:relative;
    		left:-50%;
    		float:left;
    	}
    
    	#content {
    		width:100%;
    		float:left; /* Новый контекст форматирования */
    	}
    </style>
    <div id="page">
    	<div id="menu"></div>
    	<div id="content"></div>
    </div>
    

    С помощью такой разметки мы можем легко решить нашу задачу с выносным блоком: делаем его шириной 50% и на эту же величину смещаем влево. Более того, с помощью такой разметки можно сделать более интересную вёрстку с выравниванием по основным трём колонкам:

    05

    Этот очень простой пример должен обратить внимание два ключевых момента такого способа вёрстки: выбор размера базовой колонки и выбор размера контейнера (точка отсчёта). Рассмотрим эти параметры чуть подробнее.

    Усложняем задачу

    Чтобы лучше раскрыть потенциал этого способа, попробуем сверстать шестиколоночный макет:

    06

    Проблема в том, что 100 не делится на 6 без остатка (100 / 6 ≈ 16.66666), а дизайнер по-прежнему хочет выравнивать контентные блоки по границам основных колонок.

    Одним из решений этой проблемы может быть следующее: сделаем размер контейнера равным ширине двух колонок. Размер внутреннего блока в этом случае будет равен 50%, что соответствует размеру основной колонки. А указав этому блоку margin-right:-50% мы уберём его влияние на поток по горизонтали: это позволит нам создать сколько угодно блоков в контейнере, каждый из которых будет влиять на его высоту, но не на ширину.

    07

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

    Проблема с расчётом процентных значений

    Если в предыдущем примере поиграться с размером окна браузера, то можно заметить, что во всех браузерах, кроме Firefox 3, появляются однопиксельные зазоры между некоторыми блоками:

    screenshot

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

    Проценты — это относительная величина, которая пересчитывается в абсолютную — пиксели (ну хорошо, пиксели — это тоже относительная величина, которая зависит, например, от DPI экрана). То есть когда браузер видит, например, процентную ширину у блока, он должен рассчитать значение в пикселях относительно контейнера этого блока. Предположим, ширина контейнера равна 60 пикселям, а внутреннего блока — 50%. Ширина в пикселях этого блока будет равна: 60 × 0.5 = 30px. Значения красиво умножились/поделились. Но что будет, если ширина контейнера равна 61px? 61 × 0.5 = 30.5px — браузер не может отрисовать половину пикселя, поэтому он округляет это значение в меньшую или большую сторону.

    На самом деле алгоритм гораздо сложнее: например, 4 блока подряд шириной 25% в современном браузере должны занимать 100% ширины контейнера; какие-то блоки будут меньше, какие-то больше. Мы же рассматриваем самый простой случай.

    Итак, ширина блока получилась 30.5px, браузер для себя округляет её до 30px. Что будет, если в этот блок мы вложим ещё один, шириной 200%? По идее его ширина должна быть равна ширине контейнера, то есть 61px. Но так не получится, потому что абсолютная ширина промежуточного блока равна 30px, соответственно: 30 × 2 = 60px. Получили расхождение в 1 пиксель. Из всех современных браузеров правильное значение даст только Firefox 3: судя по всему, он где-то внутри хранит истинное значение ширины, от которого делает все расчёты.

    Но! Обратите внимание, что абсолютная ширина нашего нового внутреннего блока всегда будет чётной. Например, если ширина промежуточного блока будет рассчитана как 31px, то внутренний блок будет шириной 31 × 2 = 62px. А чётные числа, как известно, делятся на 2 без остатка.

    Соответственно, решением нашей проблемы с зазорами в шестиколоночном макете будет создание ещё одной обёртки, шириной в одну колонку, а внутренней обёртке задать ширину в 200%, чтобы получилась чётная абсолютная ширина у контейнера. Убеждаемся, что всё работает правильно.

    Выводы

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

    1. Определяем ширину колонки модульной сетки. Тут, конечно, многое зависит от дизайнера: если он будет лепить блоки как попало, то никакие стандартные способы не подойдут. Мне очень повезло, что в САЛ практически у всех дизайнеров есть голова на плечах. Перед тем, как что-то нарисовать, они разбивали макет на несколько колонок одинаковой ширины, по которым выравнивали блоки. Если же макет не укладывался в мою схему, я немного раздвигал блоки, выравнивая их по моим колонкам и показывал дизайнеру — он был не против. Важно понимать, что ширина вашей колонки не всегда будет равна ширине дизайнерской колонки. Это можно увидеть в самом первом примере, где ширина свёрстанной колонки равна двум дизайнерским. Обычно, когда я получаю макет от дизайнера, я использую его гайды исключительно для того, чтобы увидеть принципы выравнивания блоков, после чего я создаю свою разбивку на колонки.
    2. Определяем ширину основного контейнера. Этот контейнер я называю точкой отсчёта (хоть это и не точка вовсе). Важно, чтобы ширина точки отсчёта позволяла создавать ширину колонки, которая делит 100 без остатка: 100%, 50%, 20%, 10%, 5%. Создав колонки такого размера, можно точно позиционировать и раздвигать выносные блоки внутри контента.
    3. Добавляем ещё обёртку для точного округления процентов. Это если вам необходимо точное выравнивание по блокам с видимыми границами. В примере я показал, как создать блок, ширина которого всегда кратна 2. Точно так же можно создавать обёртки, ширина которых кратна, например, 4 (25%/400%).

    Самое сложное в этом способе — определить правильный размер колонки и точки отсчёта. Чтобы нагляднее продемонстрировать преимущества этого способа, покажу несколько примеров его применения:

    1. Фотогалерея Imperia Private Banking. Блок с галереей растягивается точно (±1 пискель) по размерам общего контейнера, при этом сам контентный блок занимает половину ширины и располагается по центру контейнера. Галерей на странице может быть сколько угодно (как и контента между ними), при этом они будут находится в нормальном потоке документа. На этом же сайте можно увидеть ещё несколько примеров того, как контентные выносные блоки выравниваются по колонкам макета.
    2. Банк AB.LV. Сайт довольно большой, содержит много разного контента и едва заметных декораций (однопиксельная тень вокруг основного блока, например). На странице «О банке» можно увидеть, как четвёртая колонка в контенте выравнивается точно по основному меню (это чистой воды дрочерство, но дизайнер был доволен, да и мне было не сложно такое сделать).
    3. (примеров, на самом деле, много, но не могу вспомнить самые выразительные).

    Недостатки

    Куда же без них. Самый главный — способ совершенно не подходит для макетов, которые должны растягиваться на всю ширину окна браузера. Из-за тех самых округлений процентных значений есть большой риск того, что какой-нибудь блок выйдет на 1px за пределы окна, создав тем самым горизонтальный скролл. Ещё кому-то может может показаться недостатком то, что размеры блоков меняются с шагом, больше одного пикселя. Ну и не забываем, что дизайнер тоже должен включить мозг перед тем, как что-то нарисовать. Хотя, конечно, если постараться, то можно сверстать и совсем экзотические варианты, выбрав размер колонки по-меньше (например, 10%).

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

    Метки: , ,
  • Zen Coding для textarea

    Представляю первую бета-версию плагина, который позволяет использовать мощь Zen Coding у себя на сайте без всяких плясок с бубном: Zen Coding for <textarea>. Название говорит само за себя: ZC работает прямо в <textarea>. Для работы достаточно подключить всего один JS-файл к себе на сайт.

    Как это работает

    Плагин использует технику под названием event delegation: вешаются события по отлову нажатий клавиш на родительский документ; когда пользователь пытается вызвать какую-нибудь команду (например, Expand Abbreviation), плагин проверяет, какой элемент является источником. Если это <textarea> — отрабатываем команду, если нет — просто пропускаем событие. Таким образом, никакой дополнительной настройки для работы плагина не требуется: подключаем файл и радуемся жизни.

    Испытать плагин можно прямо на это странице в форме добавления комментария. Чтобы узнать допустимые сочетания клавиш достаточно кликнуть на иконке «Powered by Zen Coding» рядом с полем ввода.

    Плюшки

    Помимо основных возможностей Zen Coding плагин позволяет сделать написание кода в <textarea> гораздо более приятным занятием. Во-первых, можно задействовать клавишу Tab для разворачивания аббревиатур. Если аббревиатуру не получается развернуть, то добавляется символ табуляции (то есть просто делается отступ, как в обычных редакторах). Во-вторых, можно включить форматирование кода при добавлении переводов строк (нажатие на Enter). Новая строка будет добавлена вместе с отступом предыдущей строки, а если каретка находилась как раз между открывающим и закрывающим тэгом — будет добавлено дополнительное форматирование.

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

    Настройка

    У плагина есть ряд базовых настроек, которые можно в любой момент перекрыть. Все эти настройки записаны в переменной default_options файла manager.js:

    • profile — профиль форматирования результата разворачивания аббревиатур. По умолчанию применяется 'xhtml', доступны также 'plain', 'html', 'xml'.
    • syntax — синтаксис языка, с которым работаем в поле. По умолчанию это 'html', доступно также 'css', 'xml', 'xsl'. Можно создавать свой синтаксис (см. zen_settings.js).
    • use_tab – использовать клавишу Tab для разворачивания аббревиатур/добавления отступов.
    • pretty_break — включить форматирование переноса строк.

    Изменить настройки можно как глобально (применяются ко всем полям ввода), так и локально (применяются к конкретному полю).

    Для глобального изменения настроек нужно вызвать функцию zen_textarea.setup(), передав ей параметры, которые нужно изменить. Например, для того, чтобы глобально включить использование клавиши Tab и форматирование переносов строк, нужно вызвать такой код:

    	zen_textarea.setup({
    		use_tab: true,
    		pretty_break: true
    	});
    

    Для того, чтобы указать локальные настройки для конкретного поля достаточно указать ему класс вида zc-{название параметра}-{значение}. Например, для того, чтобы указать, что в данном поле нужно использовать синтаксис XSL, а также включить форматирование переносов строк, пишем вот такие классы:

    	<textarea class="zc-syntax-xsl zc-pretty_break-true"></textarea>
    

    Также можно переназначить сочетания клавиш на более привычные, для этого есть методы zen_textarea.shortcut(keystroke, action_name) и zen_textarea.unbindShortcut(keystroke). В качестве аргумента keystroke отдаем текстовое описание сочетания клавиш, например Shift+Alt+D, в качестве аргумента action_name — название действия, которое нужно выполнить.

    Для создания шорткатов можно использовать клавишу Meta: на Маке это будет означать Command, на PC — Ctrl. Полный список доступных действий и их шорткаты:

    addShortcut('Meta+E', 'Expand Abbreviation');
    addShortcut('Tab', 'Expand Abbreviation');
    addShortcut('Meta+D', 'Balance Tag Outward');
    addShortcut('Shift+Meta+D', 'Balance Tag inward');
    addShortcut('Shift+Meta+A', 'Wrap with Abbreviation');
    addShortcut('Ctrl+Alt+RIGHT', 'Next Edit Point');
    addShortcut('Ctrl+Alt+LEFT', 'Previous Edit Point');
    addShortcut('Meta+L', 'Select Line');
    addShortcut('Enter', 'Format Line Break');
    
    Метки: , , , ,
  • Zen Coding v0.5

    Как, наверно, многие догадались по постам на Smashing Magazine, Ajaxian и Хабре, вышел Zen Coding v0.5. Видео, описывающие прелести нового ядра:

    Все видимые нововведения описаны на смашинге, посмотрим, что изменилось «под капотом»:

    • Новый формат описания аббревиатур. Никаких объектов, используются «человеческие» описания тэгов: 'img': '<img src="" alt=""/>'. Во время первого запуска парсер читает настройки и преобразовывает их в специальные объекты для быстрой работы. В данном случае важен синтаксис тэга: например, /> в конце определения означает, что тэг одиночный и не может содержать потомков.
    • Переменные. В настройках добавилась специальная секция variables, в которой определяются переменные, подставляемые в аббревиатуры. Переменные подставляются как ${variable}, но есть ряд предопределённых элементов, которые имеют особые значения: ${id}, ${class}, ${child}. Переменные нужны для того, чтобы можно было быстро менять некоторые стандарнтные значения в аббревиатурах и сниппетах (например, язык). В дальнейшем планируется задавать свои переменные для отдельных проектов.
    • Профили вывода. Можно настроить формат вывода генерируемого кода: выводить в HTML/XHTML диалекте, менять регистр тэгов и атрибутов, менять типы кавычек. Первые наброски документации: http://code.google.com/p/zen-coding/wiki/ZenCodingAPI
    • Сниппеты поддерживают атрибуты id и class. Это можно увидеть на видео в самом конце, в примере с Django блоком. В сниппете можно указать, куда должно подставляться значение атрибутов id и class — получаем, таким образом, легко расширяемые сниппеты.
    • Наследование. Аббревиатуры и сниппеты для конкретного языка могут наследоваться от других языков. Например, для XSL я указал, что его снипетты должны наследоваться от HTML — таким образом при редактировании XSL можно пользоваться стандартными HTML-аббревиатурами + добавлять специфичные для конкретного языка. Наследование задается через параметр extends, указывая через запятую языки:
      'xsl': {
      	'extends': 'css,html',
      	'abbreviations': {
      		...
      	}
      }
      
    • Улучшен API самой библиотеки. Из JS-версии удалил все зависимости от Eclipse, теперь код работает в любом стандартном JS окружении. Добавилось несколько вспомогательных функций для упрощения работы. Но API всё ещё очень далёк от идеала, буду его улучшать.
    • Все комментарии в коде переведены на английский язык.

    Буквально сегодня утром сделал объединил свою ветку разработки с транком, так что там теперь лежит последняя версия. Больше информации о Zen Coding (ну и на меня — красивого — посмотреть :)) можно увидеть в моём докладе на 404fest.

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

    Notepad++

    Все очень хотят поддержку этого редактора, но проблема в том, что у него нет возможности добавить расширения через скрипты. Единственный известный мне способ расширить NP++ — написать плагин на C++, используя API редактора. На сях я не пишу, приложения под винду никогда не создавал, поэтому нужна помощь человека, который в этом разбирается. В идеале: нужно написать мост WSH-C++, который позволит писать расширения на JavaScript для NP++. Как минимум: предоставить простой API на JavaScript специально для Zen Coding, который я буду дёргать и говорить, что нужно сделать (опять же, с помощью WSH).

    В TextMate не всё работает

    Да, в TextMate пока работает только разворачивание аббревиатур. Обёртывание аббревиатурами и выделение тэгов не работают — опять же, из-за ограничений API редактора. Но есть уже некоторые наброски решений этой проблемы (спасибо Антону Полещуку).

    Метки: , ,
  • Универсальный способ декорирования блоков

    В прошлой домашке я предложил читателям придумать способ вёрстки блоков со скругленными уголками и тенью. Если посмотреть на решения, то увидите, что большинство из них очень похожи друг на друга: 4 элемента, разбросанных по углам, одинаково «необычный» вид картинки, небольшие различия в наложении блоков. Давайте рассмотрим подробнее, за счет чего работают эти способы, а также почему эта статья не называется «Создание скруглённых блоков с тенью».

    Начать, в первую очередь, стоит с определения проблемы, которую нужно решить. Предположим, у нас есть блок со скруглёнными уголками и тенью:

    1

    Внутри блока есть контент неопределенной ширины и высоты, тень полупрозрачная; сам блок может иметь как заданную ширину (пиксели, проценты), так и автоматическую (width: auto). Наша задача: найти наиболее оптимальный способ вёрстки подобных блоков. Под оптимальностью я подразумеваю наименьшее количество элементов, наименьшее количество графических файлов, работа во всех современных браузерах, минимальное количество правок под конкретный браузер. Все эти принципы так или иначе влияют на производительность и надёжность нашего решения, особенно на крупных проектах.

    Справедливости ради стоит отметить, что мы будем рассматривать неопределенность габаритов контента в каком-то определенном диапазоне, например, 1000×1000 пикселей. То есть я буду рассказывать про какие-то небольшие контекстные всплывающие блоки, которыми сейчас переполнены различные сайты. Если вам нужно будет, например, сделать тень у блока, в котором содержится основной контент сайта, то лучше выбрать другой способ.

    Простой способ

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

    2

    • Первая область: растягивается по горизонтали и вертикали, background-position: top left;
    • Вторая область: ширина фиксированная, растягивается по вертикали, background-position: top right;
    • Третья область: растягивается по горизонтали, высота фиксированная, background-position: bottom left;
    • Четвертая область: ширина и высота фиксированная, background-position: bottom right.

    Реализовать такую конструкцию — проще простого, но есть один нюанс: блоки должны растягиваться не на всю ширину контейнера, а на ширину контейнера минус ширина бокового блока (в данном случае это 2 и 4). То же самое касается высоты. Решается эта задача довольно просто. Не каждый знает, что задавать размеры блокам можно не только с помощью CSS-свойств width и height , но и с помощью комбинаций left/right и top/bottom у абсолютно спозиционированных элементов. Примерный код может выглядеть так:

    <style type="text/css">
    	.shadowed {
    		position: relative;
    		left: 200px;
    		top:  100px;
    		padding: 10px;
    		width: 30%;
    		max-width: 450px;
    	}
    
    	.sh {
    		position: absolute;
    		background: url(./shadow.png) no-repeat;
    		z-index: -1;
    	}
    
    	.tl {
    		/* задаем высоту */
    		top: -6px;
    		bottom: 12px;
    
    		/* задаем ширину */
    		left: -11px;
    		right: 14px;
    	}
    
    	.tr {
    		width: 25px;
    		top: -6px;
    		bottom: 12px;
    		right: -11px;
    		background-position: top right;
    	}
    
    	.bl {
    		left: -11px;
    		right: 14px;
    		bottom: -16px;
    		height: 28px;
    		background-position: bottom left;
    	}
    
    	.br {
    		width: 25px;
    		height: 28px;
    		right: -11px;
    		bottom: -16px;
    		background-position: bottom right;
    	}
    </style>
    <div class="shadowed">
    	Hello world
    	<div class="sh tl"></div>
    	<div class="sh tr"></div>
    	<div class="sh bl"></div>
    	<div class="sh br"></div>
    </div>
    

    Если вы откроете пример в любом современном браузере, то увидите, что всё работает замечательно. Но ребята из Редмонда не могли пройти мимо такой халявы и решили усложнить нам жизнь своим продуктом под названием Internet Explorer 6, в котором:

    • не работает растягивание с помощью top/bottom и left/right;
    • свойства bottom и right работают не правильно (позиция элемента отсчитывается от чётной ширины/высоты контейнера);
    • полупрозрачный PNG нельзя наложить и позиционировать как обычный фон.

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

    Растягивание по горизонтали

    Начнем с того, что придумаем другой способ растягивания блока по горизонтали. Попробуем задать первому блоку ширину в 100%. Получим вполне ожидаемый результат: блок растягивается на всю ширину контейнера.

    3

    Если же этот блок сместить влево на ширину декорации справа, то мы как раз освободим место для блока номер 2. А если родителю указать overflow: hidden, то выпирающий слева кусок первого блока не будет виден. Это именно то, что нам нужно: при растягивании контейнера оба блока будут занимать всю доступную ширину и нормально стыковаться друг с другом:

    4

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

    5

    Решить эту проблему, опять же, довольно просто: обрамим первый и второй блок еще одним блоком, которому выставим width:100%; overflow: hidden и верхний и боковые паддинги по размеру тени. Так как мы задали ширину, то боковые паддинги увеличат размер блока до нужных значений и наша тень будет полностью отображаться. А overflow: hidden с основного контейнера можно убрать, и это даст нам дополнительное преимущество: мы сможем разместить внутренний элемент за границами контейнера (например, кнопку закрытия).

    Добавив padding у внутреннего контейнера, мы столкнёмся с тем, что первый блок будет меньшего размера, чем нам нужно. Но, опять же, так как у него задана ширина, мы можем «добить» ширину до нужного значения с помощью свойства padding-right:

    4_2

    Картинка

    Как вы знаете, полупрозрачные PNG в IE6 нельзя наложить в качестве фона, для этих целей используется фильтр AlphaImageLoader, который, к сожалению, нельзя позиционировать как фон. Но так совпали звёзды, что наше «необычное» растягивание блока из предыдущего шага поможет нам решить эту проблему. Первый блок мы сместили влево на ширину правой декорации, её же мы и отсекли. Соответственно, если мы перенесём правую декорацию в самое начало нашего спрайта, то мы сможем наложить одну и ту же картинку на оба блока:

    sprite-sample

    Правая декорация у первого блока будет скрыта overflow:hidden контейнера, а ширина второго блока равна ширине правой декорации и покажет только её. А если перенести вверх еще и нижнюю часть, то мы сможем наложить один и тот же спрайт на все 4 блока:

    sprite2

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

    Расположение блоков справа и снизу

    Как я уже отметил, в IE6 неправильно работают CSS-свойства right и bottom, и для нас это проблема, так как мы имеем дело с полупрозрачными элементами. Любая нестыковка блоков даже в 1 пиксель будет сразу бросаться в глаза.

    Свойство right исправить очень просто: достаточно вместо него воспользоваться margin-left:100% — это разместит блок ровно у правого края, а с помощью left можно подтянуть блок в нужное место. С bottom немного сложнее: я не знаю альтернативных путей, кроме как позволить самому контенту опустить этот блок до нужного уровня. На предыдущем шаге мы добавили обёртку с двумя блоками внутри, туда же мы добавим и контент. Под обёрткой разместим наши нижние блоки.

    Эта обёртка и будет определять, на какой высоте окажутся блоки 3 и 4. Согласно спецификации CSS, элемент с position: absolute, у которого не указаны позиционирующие свойства — top/right/bottom/left — должен размещаться в том месте потока документа, где размещался бы статический элемент. Это очень удобно, так как благодаря этому можно делать различные трюки в виде выносных блоков, привязанных к определённому слову в тексте (например, смотрите выноску про Hyatt Hotel на сайте Башни Федерации).

    У этой обёртки задан overflow: hidden, который выполняет 2 функции: скрывает ненужные куски внутренних декоративных блоков и задает контекст форматирования. Это значит, что никакие марджины внутри не будут выпирать наружу, что гарантирует нам точную позицию нижних блоков.

    Нижние блоки

    Если помните, мы убрали overflow: hidden у самого контейнера. Поэтому, чтобы растянуть блоки 3, 4 так же, как и 1, 2, нам, похоже, придется добавить еще одну обёртку. Однако есть одно CSS-свойство, о котором кодеры часто забывают — это свойство clip. С помощью него мы и скроем выпирающий левый край.

    Результат

    Надеюсь, вы поняли саму идею, за счет чего работает большинство решений, присланных пользователями. Кратко подведу итог: для верстки декорированных блоков понадобится 5 элементов и одна картинка. Элементы располагаются следующим образом: одна обёртка, в которой находятся левый верхний и правый верхний углы, а также контент. У этой обёртки выставлен overflow: hidden, который скрывает выпирающие части у декоративных блоков, а также задает контекст форматирования. Эта же обёртка определяет позицию двух нижних блоков по вертикали. Выпирающая левая часть у левого нижнего блока отрезана с помощью clip. Спрайт мы подогнали таким образом, чтобы нам не нужно было указывать background-position, который всё равно не сработает в IE6, так как там мы воспользуемся фильтрами. В этом спрайте мы как бы вывернули блок наизнанку, переместив нижнюю часть вверх, а правую — влево.

    А вот и моё решение. Как видно из примера, решение полностью кроссбраузерное, для IE6 понадобилось всего лишь добавить padding у некоторых блоков (это можно сделать и с помощью одноразового expression).

    С помощью этого способа можно декорировать любой блок, где надо равномерно покрыть все 4 стороны. Например, можно плоскую и скучную обложку книги превратить в объёмную, как это сделано на сайте Аймобилко (правда, там используется немного другой способ из-за технических особенностей сайта):

    imobilco

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

    Метки: , , ,
  • Домашка №2: результаты

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

    Результат домашки состоит из двух частей, вторую размещу завтра/послезавтра.

    Ante

    http://stanut.by/_/dz02/quad/ — 5 элементов, 1 спрайт, 1 expression для IE6

    Хорошее решение, однако без одного expression не обошлось. Хоть он и кэширующий, даже простое обращение к свойствам DOM-элемента обходится довольно дорого.

    Степан Резников

    http://stepan-reznikov.appspot.com/static/homework2-decor/index.html — 10 элементов, 1 спрайт

    Решение получилось совсем без хаков для IE6 (фильтр AlphaImageLoader не считается), но смущает количество декоративных элементов — целых 10 штук.

    daer

    http://chikuyonok.ru/u/hw2/daer/templates/round.html — 8 элементов, 2 спрайта, DD_belatedPNG для IE6, не зависит от высоты контента

    Чем-то похоже на решение Стёпы, только элементов 8, а не 10, и используется два спрайта вместо одного. Однако это решение не ограничено по высоте, что является плюсом. Очень некрасиво моргает при ресайзе в IE6, требует много времени на инициализацию из-за DD_belatedPNG.

    GreLI

    http://chikuyonok.ru/u/hw2/greli/homework2.html — 6 элементов, 1 спрайт, очень много исправлений для IE

    Решение, в целом, неплохое, но очень сильно смущает обилие исправлений для IE — то, чего изначально нужно было избежать. Поддерживать такой код довольно сложно и трудоёмко. Однако решение интересно прежде всего тем, что GreLI виртуозно воспользовался багом IE для достижения необходимого результата:

    В моём примере кстати вообще нет overflow. Для обрезания в IE6 используется то, что за пределами элемента с hasLayout отображаются только блоки с position:relative. Ну или абсолютно позиционированные. Декоративные же либо позиционируются абсолютно с клипингом, либо проставлен position:static. Такое вот полезное применение бага.

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

    kizu

    http://test.kizu.ru/crnrz/var-1001.html — 6 элементов, 1 спрайт, много исправлений для IE
    http://test.kizu.ru/crnrz/var-2002.html — 7 элементов, 1 спрайт, 1 expression для IE, много исправлений для IE, не зависит от высоты контента

    Скептически настроенный kizu прислал целых два очень неплохих варианта, один из которых не зависит от высоты контента, что обошлось ему в один дополнительный элемент и expression для IE. Ну а само решение грешит теми же проблемами, что и у GreLI: большое количество исправлений для IE.

    frozenbear

    http://epoint-group.ru/css-work/round-corners/ и http://epoint-group.ru/css-work/round-corners-v2/ — 4 элемента, 1 спрайт, очень тяжеловесное решение для IE6, проблемы в Opera 10

    Рекордсменом по экономии декоративных элементов стал frozenbear: его решение использует всего 4 элемента. Что вышло боком для IE6: мой бедный ослик сначала долго думал, открывать ли ему эту страницу, а после 2—3 минут раздумий таки очухался и показал решение во всей красе. А все из-за специального скрипта, который генерирует кучу блоков с фильтрами, тем самым сильно нагружая IE6. Кроме того, есть проблемы в браузере Opera с отображением инлайнового блока. Вывод: для Opera верстать сложнее, чем для IE6 :)

    Но больше всего мне понравился подход к созданию спрайта. В первом случае у части изображения отсутствовала тень, что позволило наложить друг на друга две половинки одной картинки без ненужных перехлёстов полупрозрачных областей. Но у такого подхода есть один недостаток — максимальный размер блока ограничен только половиной размера изображения. Этот недостаток был исправлен во втором примере тоже довольно необычным способом: прозрачность тени была увеличена в 2 раза. При наложении друг на друга двух половинок спрайта тень получалась именно такой, какой была в макете.

    Anton Poleshchuk

    http://chikuyonok.ru/u/hw2/ap/ — 6/5 элементов, 1 спрайт

    Очень хорошее решение: минимум исправлений для IE6 (вместо height: 1%; можно было бы написать zoom: 1 в основном CSS), нет expressions. Практически полностью повторяет моё решение :)

    Vii

    http://chikuyonok.ru/u/hw2/vii/ — 5 элементов, 1 спрайт

    Решение очень хорошее, особенно понравилось то, что декоративные элементы находятся рядом, а не разбросаны по всему блоку. Но маленький недостаток всё-таки есть: это необходимость указать отдельно для IE6 свойство clip.

    Revers

    http://rg-jam.ru/revers/block_shadow.html — 5 элементов, 1 спрайт, проблемы в Opera

    Тут особо нечего сказать: минимум элементов, минимум правок для IE6. Очень хорошее решение. Но есть проблемы в Opera при отображении инлайнового блока.

    Владислав Трушин

    http://chikuyonok.ru/u/hw2/sloter/ — 7 элементов, 1 спрайт, тяжелое решение для IE6 (VML, expression)

    Для IE6 решение получилось чересчур громоздким: некэшируемые expressions для размеров блока, VML для отрисовки PNG. Всё это отрицательно сказывается на производительности.

    Олег Коровин

    http://olegkorovin.spb.ru/magicframe/ — 6 элементов, 1 спрайт

    В сравнении с другими решениями, у Олега для декоративных элементов не используется position: absolute. У этих блоков относительное позиционирование, а нужного расположения блоков Олег добивается с помощью отрицательных марджинов. Довольно интересный подход, стоит обратить на него внимание.

    Только в IE6 все довольно плохо: при ресайзе окна начинают пропадать блоки, не работает инлайн.


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

  • Домашка №2: тень

    Веб-технологи всего мира ненавидят дизайнеров, которые рисуют вот такие блоки:

    screenshot

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

    Предлагаю читателям придумать универсальный способ верстки таких блоков, на который можно будет спокойно ссылаться и дизайнерам, и технологам (и который попадет во все учебники по HTML/CSS :)). В Техногрете уже есть что-то подобное, но лично меня этот способ не устраивает по многим параметрам: это и большое количество декоративных HTML-элементов (9 штук), и запредельное количество хаков для IE, и неспособность работать в IE с включенным доктайпом. Однако оттуда можно почерпнуть некоторые интересные мысли.

    Итак, хороший способ должен:

    • работать во всех современных браузерах, включая IE6;
    • не использовать JavaScript, только HTML и CSS;
    • одинаково хорошо работать как для блоков с заданной шириной (пиксели, проценты, em’ы), так и с шириной auto;
    • содержать как можно меньше декоративных HTML-элементов (количество элементов в дереве напрямую влияет на производительность сайта);
    • использовать как можно меньше отдельных изображений (в идеале должен получиться один спрайт).

    А настоящие джедаи должны выполнить следующие условия:

    • Способ должен одинаково хорошо работать как для блочных элементов, так и для инлайновых: структура HTML остается одинаковой, правки вносим только в CSS.
    • Не использовать expressions в IE. В крайнем случае — одноразовый expression.
    • Использовать как можно меньше хаков.

    Вот вам заготовки:

    decor1decor2

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

  • Автоматическое копирование файлов на FTP/SSH в Eclipse

    В последнее время все чаще и чаще слышны просьбы веб-разработчиков сделать удобную работу в любимом редакторе/IDE, чтобы изменившиеся файлы автоматически попадали на удаленный сервер. Самый простой способ решить эту задачу — редактировать файлы напрямую на сервере. Хотя это вполне рабочее решение, у него есть ряд недостатков, самый большой из которых: отсутствие локальной копии файла. В случае, если ваш коллега через 5 минут закачает свою, исправленную и дополненную версию файла, можно быть уверенным, что ваши изменения потеряются безвозвратно. Более того, этот способ годиться только для мелких исправлений, на 5—10 минут. Если же нужно решить какую-то более глобальную задачу, дней на 5, например, вам в любом случает придется держать локальную копию проекта, чтобы спокойно переводить его в нерабочее состояние.

    Самый правильный способ решения задач с синхронизацией файлов, который проповедуют все маститые разработчики — использовать систему версионного контроля (VCS), вроде SVN или Git. Рабочий процесс в этом случае выглядит следующим образом. Разработчик локально, у себя на компьютере, вносит необходимые изменения и делает коммит в репозиторий. В этот момент у репозитория срабатывает хук (некий скрипт), который берет изменившиеся файлы и закачивает на продакшн-сервер. Это идеальное решение для командной работы, когда необходимо объединять свои исправления с чужими. И еще, как бонус: нет необходимости бегать по 10 разным папкам и вручную копировать изменившиеся файлы на сервер. Достаточно нажать всего на одну кнопку — и абсолютно все необходимые файлы оказываются на сервере. Многих, почему-то, пугает такая «сложность», хотя на настройку окружения требуется времени не больше, чем на очередной перекур или чтение новостей.

    Ну ладно, оставим это на совести каждого конкретного человека. Недавно у меня возникла, скажем так, промежуточная задача. Весь проект лежит в SVN, автоматом закачивается на продакшн — все работает просто замечательно. Только сайт написан на Java, и для его локального запуска требуется ой как много ресурсов, особенно если параллельно работает Eclipse, фотошоп и виртуальная машина с виндой. Обычный рефреш страницы занимал минуту. И я озадачился тем, чтобы над проектом можно было работать локально, а вот проверять его можно было на удаленном dev-сервере. То есть я правлю файл, сохраняю его, при необходимости делаю build (объединение и минификация JS и CSS) и все изменившиеся файлы автоматически попадают на dev-сервер, без каких-либо лишних телодвижений. Решение оказалось довольно простым и элегантным, возможно, сработает и для других редакторов и IDE. Итак:

    1. Под *nix системы есть замечательный проект под названием FUSE, который позволяет монтировать удаленный сервер как обычную папку в локальной файловой системе. На Маке я использовал MacFuse + оболочку MacFusion для настройки FTP/SSH-серверов. На винде можно использовать платный WebDrive или NetDrive для этих же целей.
    2. Устанавливаем FUSE или WebDrive/NetDrive, настраиваем подключение к серверу и монтируем его как локальную папку.
    3. Для Eclipse ставим плагин FileSync, задача которого — автоматически синхронизировать проект с какой-нибудь внешней папкой. Синхронизация одностронняя: копируются файлы из проекта в папку, но не из папки в проект.
    4. Идем в настройки проекта (Project → Properties) в секцию File synchronization и настраиваем синхронизацию для проекта (пример с сайта разработчика):

      Настроить синхронизацию можно довольно гибко: можно исключить какие-то папки из синхронизации, можно использовать переменные в путях.

    5. Не забываем включить автобилд (Project → Build Automatically), чтобы при любом изменении ресурсов проекта файлы автоматически синхронизировались, и опцию General → Workspace → Refresh automatically в настройках Eclipse, чтобы файлы, добавленные вне Eclipse (например, картинку новую скопировали) автоматически появлялись в проекте.

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

    UPD: Решение от Neolord для работы со стандартным синхронизатором из Aptana.

← старое