Создание сайта

Создание сайтаСоздание сайта. Основы веб-дизайна.

Содержание 1-й части учебного курса.

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

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

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

В этом разделе я планирую размещать шаблоны (макеты) html страниц . которые создаются мной исключительно с целью продемонстрировать основы применения html разметки и каскадных таблиц стилей CSS. а также, различные техники html верстки, дизайнерские находки и способы придания интернет страницам индивидуальности. На сайте уже есть раздел открытых программных проектов. а эта страница будет его аналогом, но исключительно в контексте веб-дизайна. Я не буду называть HTML языком программирования, но средством или инструментом программирования он, очевидно, является, поскольку с его использованием веб мастера программируют поведение браузера в момент открытия интернет страниц (в процессе интерпретации ими html разметки). Все, приводимые ниже примеры не претендуют на оригинальность и техническое совершенство, но их работоспособность проверялась мной на наиболее известных браузерах: Microsoft Internet Explorer, Opera, Chrome и Mozilla Firefox. Для оформления макетов страниц я намеренно использовал оттенки серого цвета, поскольку именно эта цветовая гамма является наиболее нейтральной для восприятия.

В приведенных ниже примерах (в первой части курса) не используются дополнительные программные компоненты или библиотеки, такие как jQuery. Все шаблоны построены исключительно с использованием HTML и CSS, а некоторые дополнительно с применением программного кода JavaScript. Если вы создаете сайт в любых целях, кроме учебных, а тем более, если вы участвуете в создании коммерческого проекта, то использовать уже готовые решения не только можно, но и нужно, поскольку очередное изобретение велосипеда имени вас вряд ли кто-то оценит по достоинству. Да и разрабатывают такие библиотеки профессионалы, и, скорее всего, их решение будет более эффективным. Но если вы все же хотите разобраться в механизмах работы основных технологий, применяемых в веб-дизайне, то попробовать реализовать простейшие задачи целиком и самостоятельно, я считаю, необходимо.

Итак, если вы ищете ответы на вопросы “Как самостоятельно создать свой сайт?” или “Как создать уникальный, эффектный и удобный пользовательский интерфейс для сайта?” то, надеюсь, представленные ниже техники и примеры веб-дизайна вам помогут на них ответить или понять, где этот ответ искать. Любые макеты и готовые примеры вы легко сможете скачать и использовать при создании собственного сайта. Все уроки данного курса оформлены следующим образом: суть каждой решаемой задачи кратко описана на главной странице ниже, а детали их реализации можно найти на страницах с примерами, перейти на которые можно, нажав на соответствующую ссылку-заголовок или скриншот.

Важно: Ввиду того что представленные ниже примеры представляют собой не HTML. а XHTML страницы, в программном коде JavaScript пришлось некоторые символы заменить кодами, поскольку они являются специальными символами в контексте well-formed XML. Заменены следующие символы: на lt;. на gt; и на amp; Этого можно было и не делать, если вынести JavaScript код в отдельный файл и подключить его через атрибут src тэга script . но для сохранения наглядности примеров я этого делать не стал.

Макет страницы информационного портала, созданный на основе табличной верстки. Макет представляет собой html страницу . разделенную на несколько основных разделов, про которые более подробно можно прочитать, открыв страницу с примером. Подобные шаблоны можно использовать для создания несложных информационных порталов. На таких сайтах активную область страницы часто разделяют на заголовок (header), меню (menu), основную область (main), и нижнюю часть с колонтитулом (footer). Макет – это всего лишь чертеж, который еще очень далек от работающего ресурса.

Рекомендую открыть макет и изучить исходный код html разметки. Все основные стили форматирования и графического оформления элементов разметки вынесены в каскадные таблицы стилей CSS. которые, в свою очередь, внедрены в сам xhtml документ и сопровождены комментариями. Такой способ работы с каскадными таблицами стилей может быть удобен, если саму разметку и стили хранят не в отдельных файлах на сервере, а формируют динамически на основе некоторой базы данных.

В ходе табличной верстки достаточно легко контролировать размеры каждой области. Особое внимание следует уделять свойствам border – толщине границы элементов, margin – внешнему отступу и padding – внутреннему отступу. Все эти свойства можно задавать отдельно с каждой стороны элемента, добавляя (через дефис) ключевые слова left. right. top и bottom. Особенность обработки таблиц браузерами состоит в том, что они рисуют рамку border (если она определена) вокруг каждой ячейки независимо от того, есть у нее соседние ячейки или нет. Для того чтобы избежать двойных рамок используется свойство border-collapse со значением collapse. Значением по умолчанию является separate. Для выравнивания элементов в отдельных ячейках используется свойство vertical-align.

В настоящее время в веб-дизайне все реже используют табличную верстку и все чаще – верстку на основе DIV блоков или просто DIV верстку. Почему – рассказ в следующем разделе.

Верстка html страницы с использованием блочного элемента DIV называют DIV версткой . Многие веб-мастера предпочитают именно DIV верстку, поскольку она, во-первых, является более гибким инструментом для разметки страницы и, во-вторых, позволяет сократить объем html кода и тем самым ускорить загрузку страницы. Но самым главным преимуществом div верстки перед табличной версткой, как мне кажется, является то, что она позволяет собрать мозаику из прямоугольников, длина сторон которых не обязана быть кратной некоторой минимальной величине. Да, табличная верстка позволяет создавать ячейки разных размеров, но размер каждой из них обязан быть равным целому числу, умноженному на размер единичной ячейки. Иными словами, таблица нам позволяет описать ортогональную сетку, а с помощью DIV-ов мы просто заполняем область прямоугольниками произвольных размеров.

Техника DIV верстки требует более глубокого понимания того, как браузер обрабатывает html разметку. По-умолчанию каждый новый элемент DIV размещается в новой строке, поскольку это блочный элемент, но, тем не менее, каждый такой элемент можно заставить вести себя, как строчный элемент, определив свойство float значением left или right. Это будет означать, что текущий элемент будет прижиматься к определенному краю предоставленной ему области, а последующие за ним элементы будут выстраиваться справа или слева от него. Элементы DIV со свойством float. определенным значением left или right называются плавающими элементами . а следующие за ними элементы их “обтекают”. В некоторых случаях (на примере будет видно, в каких именно), последующим элементам необходимо будет запрещать выстраиваться в одну строку за плавающими DIV элементами – запретить обтекать предшествующие DIV блоки. Для этого используется свойство clear. значение которого показывает, с какой стороны необходимо запретить обтекание. В случае DIV верстки нужно быть также внимательным к величинам внешнего (margin) и внутреннего (padding) отступов. Откройте макет страницы, просмотрите исходный html код, и большинство вопросов снимутся сами собой, поскольку настройки форматирования сопровождены подробными комментариями.

Отдельно стоит отметить, что особые усилия в приведенном примере были направлены на то, чтобы “прижать” нижнюю часть страницы (footer) к нижней части экрана независимо о того, заполнена ли основная часть (main) содержимым или нет. Сделано это с использованием свойства min-height для основного окна (frame) и еще ряда настроек, более подробно узнать про которые можно открыв исходный код страницы.

Возможно, этот пример несколько надуманный, но для того, чтобы продемонстрировать сразу несколько способов придания динамичности вашей странице он вполне подходит. Во-первых, пример с закладками показывает, что система координат, используемая браузером для размещения элементов — трехмерная. Координата Z устанавливается с использованием свойства z-index. а как, и для чего задается третья координата, надеюсь, станет понятно, когда этот пример вы откроете, посмотрите, как он работает, и изучите его исходную html разметку . Во-вторых, оказывается, что логикой размещения элементов в окне или в рамках другого элемента (контейнера) можно управлять. Точнее, можно выбирать режим позиционирования ( position ) блочных элементов, определяя относительные ( relative ), абсолютные ( absolute ) или фиксированные ( fixed ) координаты – горизонтальное и вертикальное смещение относительно границ страницы или границ элемента — контейнера. В-третьих, заливка элементов может быть прозрачной, а степень прозрачности задается с использованием атрибута opacity. Ну и, в-четвертых, в этом примере я использую JavaScript – язык программирования, чьи скрипты выполняются на стороне клиента самим браузером. Да, чтобы разобраться в работе закладок, необходимо знать основы программирования. Язык JavaScript, как мне кажется, не стоит изучать целенаправленно – лучше это делать на конкретных примерах. Внешне это обычный процедурный язык программирования. но с динамической типизацией (при определении переменной не требуется указывать ее тип – он определится в момент присвоения переменной конкретного значения ), и обрабатываемый встроенным в браузер интерпретатором.

Теперь, что же такое DHTML. Динамический HTML (Dynamic HTML, DHTML) – это симбиоз HTML. CSS. скриптового языка программирования (JavaScript, VB Script) и объектной модели документа, построенной по разметке загруженной интернет страницы. DOM – это также программный интерфейс, посредством которого (с использованием того же Java Script) вы можете не только анализировать структуру загруженного html документа . но и менять ее, а также редактировать связанные с каждым элементом разметки параметры CSS стиля — динамически изменять внешний вид HTML страницы. Еще один важный момент – это события, в том числе, события пользовательского интерфейса. Событие в программировании – это абстракция, которая позволяет организовать оповещение одних объектов о том, что с другими объектами что-то произошло. Например, с помощью событий можно реализовать ответные действия программы на определенные действия пользователя. В примере с закладками с помощью событий и процедур на Java Script я описываю логику листания и выбора закладок в те моменты, когда курсор находится над ними, а также, когда происходит нажатие на кнопку мыши. Более подробно логика работы закладок описана на самой демонстрационной странице: каждая закладка содержит комментарии к одному из ключевых аспектов реализации их работы. Для выбора закладки щелкните по ней мышкой, для отмены выбора (закладка вернется на свое место) щелкните по закладке еще раз. Еще одна реализация закладок на HTML, которая, как мне кажется, более привычная, удобная и изящная, также представлена в этом разделе.

Этот пример, в отличие от предыдущего, уж точно специально выдуманным не назовешь. Примеров и описаний того, как реализовать динамически выпадающее меню на HTML в сети довольно много. Я не буду подробно рассказывать о том, чем отличается моя реализация HTML меню. Скажу лишь, что Java Script в этом примере нет, поскольку мне необходимо только лишь изменять параметры отображения пунктов меню в тот момент, когда над ними находится курсор мыши, а с этой задачей замечательно справляется классический CSS без всяких скриптов и событий. Для этого достаточно использовать псевдокласс hover в селекторе стиля, определив тем самым отдельный набор параметров, который будет применен к элементу в тот момент, когда курсор мыши окажется над ним. Как только курсор мыши покинет пределы элемента, браузер автоматически применит к нему прежние настройки отображения. Про другие особенности селекторов в каскадных таблицах стилей этого примера более подробно написано в комментариях на самой странице и в ее исходном коде.

Другой особенностью реализации является то, что число вложений подменю ограничено только размерами экрана. Вложенных подменю может быть любое количество. Меню выполнено в двух вариантах: горизонтальное меню, которое довольно часто используют веб-дизайнеры в качестве главного меню сайта, и вертикальное или боковое меню, которое, как правило, находится в области страницы слева и выполняет второстепенные навигационные функции. Для управления видимостью элементов используется свойство display. которое при значении none скрывает элемент, а все остальные элементы сразу про него забывают и смело занимают его место. Значение block делает элемент видимым и заставляет его вести себя, как обычный блочный элемент. Кстати, с помощью атрибута display блочные элементы можно заставить вести себя, как строчные элементы и наоборот, задавая значения inline или block для атрибута display соответственно. Нужно отметить, что для того чтобы при появлении пункта подменю все окружающие его элементы не разбегались, предоставляя ему место, для списков подменю используется абсолютный режим позиционирования ( position. absolute ). Таким образом, если рядом с пунктом подменю есть другие элементы, то сам пункт подменю их скроет — будет выведен поверх. То, что подменю выводится именно поверх остальных элементов (а не оказывается под ними), определяется значением его третьей координаты – свойством z-index. отличным от нуля.

Фотогалерея в контексте интернет сайта – это, чаще всего, список миниатюр изображений с возможностью выбора любой из них с последующей ее загрузкой и увеличением в отдельной области. Довольно часто можно увидеть на различных сайтах, как эффектно реализована функция увеличения выбранной миниатюры: изображение увеличивается плавно и появляется в отдельном окне. Обычно, эту функциональность реализуют с использованием специальных библиотек и плагинов, написанных на JavaScript, которые, помимо функции увеличения изображения, предоставляют еще массу различных полезных возможностей и находятся в свободном доступе. Я же хочу продемонстрировать простейшую реализацию функции увеличения изображения по клику мыши . которая лишена элементов анимации, но выполняет все то же самое: позволяет выбирать изображение и увеличивать его в отдельной области браузера по центру экрана. Нажав на крестик в верхнем правом углу изображения окно можно закрыть.

Для работы примера никакие специальные библиотеки и плагины не нужны! В основе реализации элементы DIV, абсолютное позиционирование ( position. absolute ) блока с выбранным изображением и снова JavaScript. На этот раз с использованием JavaScript я загружаю выбранное изображение в отдельное окно и рассчитываю его размеры, исходя из размеров внутренней области окна браузера. Вся остальная “анимация” выполнена исключительно с использованием CSS и псевдокласса hover. Использовать общедоступные решения, о которых я сказал выше, или сделать свою реализацию — каждый решает сам. Конечно, заново изобретать велосипед практически всегда неразумно, но и стрелять из пушки по воробьям не рационально. И не забывайте: шаблонные решения делают сайт “одним из многих”, а иногда в веб-дизайне лучше что-то простое, но свое.

Декорирование блочных элементов в веб-дизайне обычно сводится к созданию для них нестандартных границ, например, с закругленными углами, тенью и прочими “наворотами”. До появления стандарта CSS3 (каскадные таблицы стилей третьего уровня) веб-дизайнеры чего только не придумывали, чтобы придать оригинальности интерфейсам своих сайтов. Порой, цели не оправдывали средств, поскольку для создания тех же самых сглаженных углов приходилось создавать суперпозицию блоков div с 4-мя и более уровнями вложенности. Делалось это исключительно для того, чтобы описать с использованием картинок или спецсимволов на каждом уровне лишь один элемент декора для конкретного угла или стороны прямоугольного блока. Точно также пытались создать эффект тени, подкладывая один DIV под другой.

С появлением CSS3 все стало на порядок проще – закругленные углы и тени теперь поддерживаются каскадными таблицами стилей непосредственно. Данный раздел – демонстрация новых возможностей CSS3, а также пара примеров “из прошлого”, в том числе эффект “загнутого уголка”. Еще с использованием отдельных стилей для псевдокласса hover (стили, которые применяются к элементу в момент, когда над ним находится курсор мыши) показаны различные варианты придания динамичности html странице от изменения параметров тени и подмены декорирующих изображений до манипуляции размерами внешнего отступа (margin) с целью создать эффект “прижимания” блока к странице.

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

Снова вернемся к вопросу экономной компоновки информации на сайте. Имеется в виду возможность размещения большего количества данных, чем позволяет отведенное под них место. Ранее уже была предпринята попытка создания закладок средствами Dynamic HTML, но на тот момент я не хотел использовать весь арсенал настроек CSS, и реализация получилась с виду простоватой и напоминала обычную картотеку. На этот раз все теми же средствами реализуем всем известный пользовательский элемент управления закладками TabControl, который часто встречается в обычных графических приложениях и используется для заполнения различных параметров и настроек работы программ. В основе реализации все те же блоки DIV, JavaScript и новые возможности CSS3.

Вся рабочая область закладок поделена на две части: область заголовка, где размещены DIV-ы закладок, и область содержимого закладок, где в каждый момент времени виден ( display:block ) только один блок DIV с содержимым выбранной закладки, а остальные просто не отображаются ( display:none ). Процедура JavaScript реализует логику переключения содержимого закладок в зависимости от выбранного заголовка. Более детально реализация описана на первой закладке, поэтому, рекомендую открыть страницу с примером, ознакомиться с его работой и изучить исходный код разметки. Особенность представленной реализации в том, что содержимое всех закладок должно быть загружено сразу, поэтому не стоит злоупотреблять их количеством и объемом. Такой элемент управления целесообразно использовать, например, для просмотра профиля пользователя или настроек аккаунта – т.е. для тех же целей, для которых он используется в обычных приложениях. Если вы хотите, чтобы содержимое каждой закладки соответствовало различным html страницам, то для этого вам следует использовать технологию AJAX. С примером приложения, в котором применяется AJAX (выполняется загрузка интернет страницы по ее URL в отдельный элемент html разметки) вы можете познакомиться здесь.

Организация иерархической навигации по разделам информационного ресурса – довольно популярный прием в веб-дизайне. В обычных графических приложениях эта задача решается с использованием специального пользовательского элемента управления TreeView. В веб-дизайне часто поступают точно также и реализуют TreeView средствами HTML на базе списков. Особенность представленной здесь реализации в том, что начальная разметка дерева максимально разгружена от ненужных деталей, но, поскольку без этих деталей не обойтись, приходится их определять автоматически. Речь идет о том, что инициализация начальной видимости узлов дерева и добавление обработчиков событий щелчка мыши выполняются в коде JavaScript, который запускается сразу же после загрузки страницы.

На этом примере впервые ощущаются все сложности программирования на JavaScript, если вы хотите, чтобы ваша страница работала одинаково под всеми известными браузерами. У каждого браузера есть свои тонкости, а наиболее капризными являются Microsoft Internet Explorer и Mozilla Firefox. Свойство страницы работать под любыми браузерами адекватно и единым образом называется кроссбраузерностью . Отличия браузеров зачастую сводятся к тому, что для решения одной и той же задачи они предоставляют различные интерфейсы. По этой причине веб-разработчикам приходится писать собственные надстройки – кроссбраузерные функции, которые определяют ‘кто перед ними’, а именно, в контексте какого браузера они работают, и ‘дергают нужные рычаги’ его окружения. Одной из таких функций в данном примере предстает функция добавления элементу обработчика события, которая жизненно необходима для инициализации дерева.

Прочие детали реализации дерева на HTML вы найдете на самой странице с примером. Описание реализации как раз и выполнено в виде дерева, а каждый его раздел является отдельным узлом. Дерево настроено таким образом, что каждый узел может иметь не только поддерево, но и вложенный блок DIV, который также можно скрывать и показывать, нажимая [+] и.

Одни из недостатков предложенной реализации дерева средствами HTML является тот факт, что дерево не запоминает своей конфигурации и после каждого обновления страницы предстает в первоначальном виде. Реализовать сохранение и восстановление состояния дерева можно средствами cookies – небольших файлов, которые браузер сохраняет на компьютере пользователя, в том числе и для хранения состояния сеанса работы с сайтом.

Если посетитель, открыв ваш сайт, увидит там окна до боли ему знакомого Windows, то, скорее всего, в первый момент у него будет недоумение типа “Чего с моим браузером?” или “Я не открывал эту …!”. Чуть позже, осознав, что это всего лишь имитация и дизайнерская находка, он начнет проверять эти самые окна на качество подделки, пытаясь их открывать, закрывать, перемещать и т.п. В любом случае, эффект будет положительным — ваш сайт запомнят. Этот пример веб-дизайна относится к тем, когда ресурс запоминается не чем-то новым и оригинальным, а реализацией довольно привычного для всех интерфейса, но в том контексте, в котором увидеть этот интерфейс никто не ожидает. Что ж, для привлечения внимания посетителей все средства веб-дизайна (законные) хороши.

Данный пример – демонстрация простейшей реализации оконного интерфейса средствами HTML/CSS и JavaScript. Сам интерфейс напоминает интерфейс Microsoft Windows 7 (хотя и весьма отдаленно) и позволяет размещать информацию в окнах, а также, разворачивать, сворачивать и перемещать выбранное окно. Набор функционала невелик, но для достижения поставленной цели — обратить на себя внимание пользователя путем легкого шока – вполне достаточный.

В основе реализации оконного интерфейса на HTML техника замены CSS класса выбранного элемента на другой, когда окно разворачивается или сворачивается и обработка событий мыши, когда окно перемещается. Также, особое внимание необходимо уделить особенностям размещения элементов в условиях абсолютного позиционирования ( position. absolute ). Детали реализации вы сможете узнать, открыв саму страницу с окнами.

Есть один минус подобной реализации: для описания одного окна в разметку нужно добавить много различных элементов по предопределенным правилам (само окно, заголовок, подпись, картинка-кнопка справа, основное содержимое и др.), что может не досаждать только тогда, когда html-разметку вы формируете программно, а не вручную. Частично этот минус я устраню в следующем примере, где расскажу о том, как реализовать собственный формат информационной ленты на XML по аналогии с RSS.

Продолжим разговор про оконный интерфейс на HTML. Как я уже отметил выше, представленная ранее реализация оконного интерфейса малопригодна для ручной верстки, поскольку каждое окно на HTML представлено не одним, а несколькими html тэгами, для каждого из которых необходимо указать соответствующий класс и атрибуты. Если вы формируете html разметку программно, например, в коде php. то подобной проблемы не существует, но если вы вручную набираете содержимое страницы, то помимо лишней работы есть еще и высокая вероятность допустить ошибку верстки. Допустить ошибку не страшно, но ее еще и найти потом желательно. Нужно как-то сократить ручную работу и все рутинные операции переложить на чьи-нибудь “автоматизированные плечи”… Обратим внимание на стандарт RSS. Что это такое в принципе? Стандарт RSS – это грамматика, построенная на базе XML (как, впрочем, и сам XHTML) и созданная для того, чтобы кратко описывать новости, анонсы статей, обзоры и другие виды интернет публикаций с тем, чтобы эта информация могла быть автоматически обработана программой-агрегатором на стороне пользователя. Да, RSS представляет данные ни разу не в HTML, а просто в XML формате, удобном для таких целей. Зайдите на любой сайт, откройте (если он это безобразие поддерживает) ссылку на его RSS ленту и посмотрите исходный код полученной страницы – там вы не найдете HTML тэгов (относящихся к разметке самой ленты), а обнаружите тэги типа item. title и description. В случае с RSS лентами финальный гипертекст формируется самим браузером по исходному XML и набору правил, представленному схемами XSL трансформации для каждого раздела. Более подробно про XSL преобразования вы узнаете, пройдя по ссылке, а сейчас достаточно понимать, что с помощью XSL можно описать преобразование формата на базе XML в любой другой структурированный текстовый формат, коим, в частности, является HTML/XHTML.

Итак, этот пример показывает, как несложную грамматику, созданную на основе XML можно преобразовывать в HTML, притом не своими руками, а средствами браузера. Перечень окон примера описан в xml файле. Описание каждого окна выглядит довольно просто и компактно: описываем само окно – тег window, его заголовок – тег head и содержимое — тег body. Причем, содержимым body может быть не только текст, но и гипертекст. Далее, создаем схему преобразования XML в HTML, подключаем эту схему и получаем свой аналог RSS ленты. Этот пример, скорее, не демонстрация техники веб-дизайна, а демонстрация одной из его технологий. Более подробно о том, как связать XML с XSL и получить на выходе HTML вы узнаете, перейдя на саму страницу с примером. Приходится констатировать, что на момент публикации этого материала демонстрационная страница отображается корректно не всех браузерах. На установленном у меня Internet Explorer 9 результат XSL преобразования выглядит “кривовато”, в то время как предыдущий пример – чистый код разметки оконного интерфейса на HTML — выглядит так, как и задумывалось автором. Надеюсь, что со временем и этот недостаток исчезнет сам собой. А результат в Opera, Chrome и Firefox меня вполне устраивает.

Опубликовал +автор Май 14 2012 13:28:35 34619 Прочтений.

Понравилась статья? Поделиться с друзьями:
Строительство и ремонт
Добавить комментарий