Кроссворд из регулярных выражений: интерактивная версия

от автора

Вдохновлённый недавним постом и комментарием к нему, решил сделать аналогичную интерактивную версию.
Есть навигация с клавиатуры, подсветка активных строк, а также индикация соответствия строки регулярному выражению. Для удобства подсказки выделенной ячейки поворачиваются горизонтально.
Разметка – чистый HTML+CSS3.
Почти работает в последних версиях популярных браузеров. В IE9 глючит навигация мышкой, в FF и Opera наблюдаются проблемы с производительностью. И только Chrome – 100% OK.
Буду благодарен за советы по оптимизации.
Ссылка – вот. Детали реализации – под катом.
image

Реализация

Пожалуй, самое интересное в реализации – это сетка кроссворда. Ячейка сверстана с помощью развития идеи «честных полигонов». Если коротко – создаются несколько контейнеров с visibility:hidden и overflow:hidden, что предоставляет отсекание лишнего содержимого. Внутри создаётся содержимое с visibility:visible. Использование этого вместе с вращением у контейнеров позволяет задать конечному элементу форму практически любого выпуклого многоугольника.
Чтобы сделать этот многоугольник с границами в несколько пикселей, к содержимому были добавлены дополнительные внешние контейнеры с аналогичными поворотами и нужными границами. Суть показана на картинке. Здесь красным пунктиром обозначены внешние «невидимые контейнеры», чёрным – внутренние контейнеры с границами.

Сначала идут 3 вложенных друг в друга элемента с красной рамкой, внутри них – так же вложенные видимые контейнеры с чёрной рамкой.

Код

HTML

<span class="hexcell"> 	<span> 		<span> 			<span> 				<span> 					<span class="input"></span> 				</span> 			</span> 		</span> 	</span> </span> 

CSS

.hexcell { 	display: inline-block; 	vertical-align: middle; 	text-align: center; 	width: 50px; 	height: 70px; 	overflow:hidden; 	visibility:hidden; 	-webkit-transform: rotate(120deg); 	   -moz-transform: rotate(120deg); 	    -ms-transform: rotate(120deg); 	     -o-transform: rotate(120deg); 	        transform: rotate(120deg); } .hexcell span { 	position:relative; 	width:100%; 	height:100%; 	display:inline-block; 	overflow:hidden; 	visibility:hidden; 	vertical-align: middle; 	text-align: center; } .hexcell > span { 	-webkit-transform: rotate(-60deg); 	   -moz-transform: rotate(-60deg); 	    -ms-transform: rotate(-60deg); 	     -o-transform: rotate(-60deg); 	        transform: rotate(-60deg); } .hexcell > span > span { 	-webkit-transform: rotate(-60deg); 	   -moz-transform: rotate(-60deg); 	    -ms-transform: rotate(-60deg); 	     -o-transform: rotate(-60deg); 	        transform: rotate(-60deg); } .hexcell > span > span > span{	/*первая рамка*/ 	border: 1px solid #000000; 	height:68px; 	width:48px; 	visibility:visible; 	-webkit-transform: rotate(120deg); 	   -moz-transform: rotate(120deg); 	    -ms-transform: rotate(120deg); 	     -o-transform: rotate(120deg); 	        transform: rotate(120deg); } .hexcell > span > span > span > span{	/*вторая рамка*/ 	border: 1px solid #000000; 	height:68px; 	width:48px; 	top:-1px; 	left:-1px; 	visibility:visible; 	-webkit-transform: rotate(-60deg); 	   -moz-transform: rotate(-60deg); 	    -ms-transform: rotate(-60deg); 	     -o-transform: rotate(-60deg); 	        transform: rotate(-60deg); } .hexcell > span > span > span > span > span.input{	/*содержимое с третьей рамкой*/ 	border: 1px solid #000000; 	height:68px; 	width:48px; 	top:-1px; 	left:-1px; 	position:relative; 	visibility:visible; 	font-size:34px; 	-webkit-transform: rotate(-60deg); 	   -moz-transform: rotate(-60deg); 	    -ms-transform: rotate(-60deg); 	     -o-transform: rotate(-60deg); 	        transform: rotate(-60deg); } 

Для корректного объединения ячеек в сетку делается следующее:

  • ячейки оборачиваются в контейнер, содержимое которого выравнивается по центру
  • используется псевдо-border-collapse: всем ячейкам, кроме последней, ставится меньшая ширина и последнего элемента (контейнер содержимого) убирается правая граница
  • для совмещения строчек добавляется отрицательный margin-top

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

Работоспособность

Отдельные вопросы вызывает функционирование. Кроссворд гарантированно функционирует только под Webkit (разработка велась под Chrome последней версии). В Firefox и Opera тоже работает, но почему-то с заметными тормозами, особенно в Opera. Как показал профайлер в той же Opera, больше всего времени уходит на перерисовку, даже с отключёнными transitions. Под IE10 не тестировалось. Под 9-м был баг с позиционированием заголовков (горизонтальные съезжали влево). Как я понял, это какая-то его специфика. Первый элемент в строке с position:absolute съезжает к левому краю, несмотря на отсутствие явного указания положения. Исправлено через display:inline-block у контейнера строки.
Также вместе с поворотами криво рендерится текст. В целом, как показал опыт, рендеринг графики вместе с transform пока оставляет желать лучшего.

ссылка на оригинал статьи http://habrahabr.ru/post/175847/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *