CGI: пишем простой сайт на Python. Часть 3: Пример приложения
Мы уже научились обрабатывать формы и устанавливать cookies. Сегодня же мы посмотрим, что может из этого получиться.
Чтобы работать с пользовательскими данными, нужно где-то эти данные сохранять. Самый простой (но далеко не самый изящный и безопасный) — хранение данных в файлах. Более продвинутый способ — хранение в базе данных. Мы остановимся на первом способе, как на самом простом.
Собственно, ничего нового здесь объясняться не будет. Работу с файлами вы уже знаете, обрабатывать формы уже умеете.
Сегодня мы напишем прототип приложения типа «твиттер». Данные в файлах будем хранить в json.
Создадим 2 файла: один будет отвечать за обработку данных, вводимых пользователем, второй — вспомогательный модуль, который упростит код первого.
cgi-bin/wall.py:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import cgi import html import http.cookies import os from _wall import Wall wall = Wall() cookie = http. cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) session = cookie.get("session") if session is not None: session = session.value user = wall.find_cookie(session) # Ищем пользователя по переданной куке form = cgi.FieldStorage() action = form.getfirst("action", "") if action == "publish": text = form.getfirst("text", "") text = html.escape(text) if text and user is not None: wall.publish(user, text) elif action == "login": login = form.getfirst("login", "") login = html.escape(login) password = form.getfirst("password", "") password = html.escape(password) if wall.find(login, password): cookie = wall.set_cookie(login) print('Set-cookie: session={}'.format(cookie)) elif wall.find(login): pass # А надо бы предупреждение выдать else: wall.register(login, password) cookie = wall.set_cookie(login) print('Set-cookie: session={}'.format(cookie)) pattern = ''' <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>Стена</title> </head> <body> Форма логина и регистрации.При вводе несуществующего имени зарегистрируется новый пользователь. <form action="/cgi-bin/wall.py"> Логин: <input type="text" name="login"> Пароль: <input type="password" name="password"> <input type="hidden" name="action" value="login"> <input type="submit"> </form> {posts} {publish} </body> </html> ''' if user is not None: pub = ''' <form action="/cgi-bin/wall.py"> <textarea name="text"></textarea> <input type="hidden" name="action" value="publish"> <input type="submit"> </form> ''' else: pub = '' print('Content-type: text/html\n') print(pattern.format(posts=wall.html_list(), publish=pub))
Здесь мы используем форматирование строк для формирования страницы (кстати, это первый шаг на пути к созданию собственного шаблонизатора).
Не забудьте дать этому файлу права на выполнение (второму файлу эти права не нужны).
cgi-bin/_wall.py (здесь определены функции publish, login и другие):
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import json import random import time class Wall: USERS = 'cgi-bin/users.json' WALL = 'cgi-bin/wall.json' COOKIES = 'cgi-bin/cookies.json' def __init__(self): """Создаём начальные файлы, если они не созданы""" try: with open(self.USERS, 'r', encoding='utf-8'): pass except FileNotFoundError: with open(self.USERS, 'w', encoding='utf-8') as f: json.dump({}, f) try: with open(self.WALL, 'r', encoding='utf-8'): pass except FileNotFoundError: with open(self.WALL, 'w', encoding='utf-8') as f: json.dump({"posts": []}, f) try: with open(self.COOKIES, 'r', encoding='utf-8'): pass except FileNotFoundError: with open(self.COOKIES, 'w', encoding='utf-8') as f: json.dump({}, f) def register(self, user, password): """Регистриует пользователя. Возвращает True при успешной регистрации""" if self.find(user): return False # Такой пользователь существует with open(self.USERS, 'r', encoding='utf-8') as f: users = json.load(f) users[user] = password with open(self.USERS, 'w', encoding='utf-8') as f: json.dump(users, f) return True def set_cookie(self, user): """Записывает куку в файл. Возвращает созданную куку.""" with open(self.COOKIES, 'r', encoding='utf-8') as f: cookies = json.load(f) cookie = str(time.time()) + str(random.randrange(10**14)) # Генерируем уникальную куку для пользователя cookies[cookie] = user with open(self.COOKIES, 'w', encoding='utf-8') as f: json.dump(cookies, f) return cookie def find_cookie(self, cookie): """По куке находит имя пользователя""" with open(self. COOKIES, 'r', encoding='utf-8') as f: cookies = json.load(f) return cookies.get(cookie) def find(self, user, password=None): """Ищет пользователя по имени или по имени и паролю""" with open(self.USERS, 'r', encoding='utf-8') as f: users = json.load(f) if user in users and (password is None or password == users[user]): return True return False def publish(self, user, text): """Публикует текст""" with open(self.WALL, 'r', encoding='utf-8') as f: wall = json.load(f) wall['posts'].append({'user': user, 'text': text}) with open(self.WALL, 'w', encoding='utf-8') as f: json.dump(wall, f) def html_list(self): """Список постов для отображения на странице""" with open(self.WALL, 'r', encoding='utf-8') as f: wall = json.load(f) posts = [] for post in wall['posts']: content = post['user'] + ' : ' + post['text'] posts. append(content) return '<br>'.join(posts)
Разумеется, в нашем простом «твиттере» очень много недостатков: не выводятся предупреждения пользователю, регистрация при несуществующем имени, пароли хранятся в открытом виде, использованные куки не удаляются, и многие другие. Кто хочет, может усовершенствовать.
Но есть и преимущество: поскольку у нас теперь 2 разных файла (почти независимых), то можно поменять систему хранения данных (например, база данных вместо файлов), вообще не затрагивая wall.py.
Напоследок покажу, как это работает:
Сначала зарегистрировались, теперь нужно ещё раз ввести логин-пароль, чтобы войти.
Можно писать.
В следующей (возможно последней) части я покажу, как это всё можно опубликовать в сети интернет.
Для вставки кода на Python в комментарий заключайте его в теги <pre><code>Ваш код</code></pre>
Готовые макеты блоков для веб-страниц на HTML и CSS
Всем привет!
Однажды я подумал: для чего постоянно прописывать один и тот же код для создания каких-либо сайтов, если можно создать заготовки и пользоваться ими. Это, во-первых, ускорит время создания сайтов. Во-вторых, если прописать сразу правильно макет, то ошибки в коде значительно уменьшатся. В-третьих, те, кто пользовался генераторами шаблонов, могут о них забыть.
Итак, существуют резиновые и фиксированные макеты.
Фиксированные макеты – это когда ширина блоков задается в пикселях (px), а это значит, что размер макета сайта будет фиксированным не зависимо от размера экрана.
Резиновые макеты – это когда ширина блоков задается в процентах (%), а это значит, что макет сайта будет полностью гибким и автоматически подстраиваться под любой размер экрана.
Макет может быть одноколоночным:
Двухколоночным:
и трехколоночным:
Одноколоночные макеты (веб-страницы)
○ Выравниваем блок с контентом по центру экрана.
Пример:
Такое размещение блока будет полезно и интересно для дизайна:
— сайта-визитки;
— точки входа на сайт или в админ-панель;
— сообщения об отправленном письме и т. д.
Теперь код:
<html> <head> <title>Одноколоночные макеты на BlogGood.ru</title> <style> .blok-center { position: absolute; /* Абсолютное позиционирование */ width: 600px; /* Ширина блока */ height: 400px; /* Высота блока */ margin: auto; /* Отступ от блока */ top: 0; /* Положение блока от верхнего края */ bottom: 0; /* Положение блока от нижнего края */ left: 0; /* Положение блока от левого края */ right: 0; /* Положение блока от правого края */ background: #fc0; /* Цвет фона блока */ border: 1px solid #000; /* Рамка блока */ padding: 10px; /* Отступ внутри блока */ overflow: auto; /* Полоса прокрутки */ } </style> </head> <body> <div> <form> <p>Ваше имя*<br /> <input name="name" ENGINE="text" /></p> <p>Электронная почта*<br /> <input name="email" type="text" /></p> <p>Тема сообщения<br /> <input name="sub" type="text" /></p> <p>Текст сообщения:<br /><textarea name="body" cols="1" rows="5" /></textarea></p> <p><input value="Отправить" type="submit" /></p> </form> </div> </body> </html>
Результат:
Код:
<html> <head> <title>Макет одной колонки на BLOGGOOD. RU</title> <style> #content { width: 500px; /* Ширина блока */ margin: 0 auto 50px; /* Выравнивание блока по центру */ } #footer { position: fixed; /* Фиксированное положение футера (подвала)*/ left: 0; bottom: 0; /* Левый нижний угол */ padding: 10px; /* Поля вокруг текста */ background: #000; /* Цвет фона */ color: #fff; /* Цвет текста */ width: 100%; /* Ширина слоя */ } </style> </head> <body> <div> Как управлять человечеством? Конечно же, установить законы. А какими бывают законы? Строгими, справедливыми, вечными, а еще … нелепыми! Прочитайте эту интересную статью и узнайте, в каких странах действуют эти нелепые законы. Я также постаралась найти причину возникновения каждого нелепого закона. </div> <div> © Костаневич Степан </div> </body> </html>
Результат:
○ Еще один вариант одноколоночного макета:
Код:
<html> <head> <title>одноколоночный макет на блоге BlogGood. ru</title> <style> html,body{margin:0;padding:0} body{font: 76% arial,sans-serif;text-align:center} p{margin:0 10px 10px} a{display:block;color: #981793;padding:10px} div#header h2{height:80px;line-height:80px;margin:0; padding-left:10px;background: #EEE;color: #79B30B} div#container{text-align:left} div#content p{line-height:1.4} div#navigation{background:#B9CAFF} div#extra{background:#FF8539} div#footer{background: #333;color: #FFF} div#footer p{margin:0;padding:5px 10px} div#container{width:700px;margin:0 auto} div#navigation{float:left;width:350px} div#extra{float:right;width:350px} div#footer{clear:both;width:100%} </style> </head> <body> <div> <div><h2>BlogGood.ru</h2></div> <div> <div> <p><strong>1) Контент.</strong> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! Рейчел Беквит – американская девочка из Сиетла, которая родилась в 2002 году. Однажды в церкви, которую посещала ее семья, она узнала, что в Африке каждый день погибает 4,5 тысяч деток от страшных болезней, потому что им приходиться утолять свою жажду водой из грязных луж и зараженных болот. Эта статистика толкнула Рейчел на удивительный поступок. Перед празднованием своего 9-летия она попросила своих родных и близких, чтобы они не тратили деньги ей на игрушки, сладости или другие какие-либо подарки. Вместо этого она призвала их всех пожертвовать эти деньги благотворительной организации Charity Water, которая помогала людям в тех странах, где не хватало питьевой воды. </p> </div> </div> <div> <p><strong>2) Новости. </strong> Как управлять человечеством? Конечно же, установить законы. А какими бывают законы? Строгими, справедливыми, вечными, а еще … нелепыми! Прочитайте эту интересную статью и узнайте, в каких странах действуют эти нелепые законы. Я также постаралась найти причину возникновения каждого нелепого закона. </p> </div> <div> <p><strong>3) Меню.</strong> Продолжаем узнавать интересные и невероятные факты. Тем, кто считает, что человеку свойственны пять чувств, спешу сказать, что их уже девять! Если вы интересуетесь интересными фактами о человеческом организме, то эта статья как раз для вас! Узнайте больше о себе и о своих органах чувств.</p> </div> <div><p>BlogGood.ru</p></div> </div> </body> </html>
Результат:
Двухколоночные макеты (веб-страницы)
Фиксированные макеты
Частенько в сети интернет встречаются двухколоночные веб-страницы. Это самые распространенные варианты верстки сайтов, так как считаются самыми удобными и для создания. А также они хорошо воспринимаются пользователями. В правой колонке размещается меню, а в левой – контент. Или в правой колонке размещается контент, а в левой – меню.
○ Двухколоночный макет (слева меню, справа контент):
Теперь код:
<html> <head> <title>Двухколоночный макет на BlogGood.ru</title> <style> body { font: 13pt Arial, Helvetica, sans-serif; /* Шрифт теста */ background: #e1dfb9; /* Цвет фона */ } h3 { font-size: 18px; /* Размер шрифта в заголовке */ color: #080808; /* Цвет заголовка */ margin-top: 0; /* Отступ сверху */ } .container { width: 600px; /* Ширина слоя */ margin: 0 auto; /* Выравнивнить весь блок по центру */ background: #f0f0f0; /* Цвет фона левой колонки */ } . header { font-size: 38px; /* Размер текста в шапке */ text-align: center; /* Выравнивание текст шапки по центру */ padding: 5px; /* Отступы внутри блока шапки */ background: #8fa09b; /* Цвет фона шапки */ color: #fff; /* Цвет текста */ } .sidebar { margin-top: 10px; width: 110px; /* Ширина блока */ padding: 0 10px; /* Отступы внутри левого блока */ float: left; /* Обтекание блока по правому краю */ } .content { margin-left: 130px; /* Отступ слева */ padding: 10px; /* Отступы внутри правого блока */ background: #fff; /* Цвет фона правого блока */ } .footer { background: #8fa09b; /* Цвет фона нижнего блока-подвала */ color: #fff; /* Цвет текста подвала */ padding: 5px; /* Отступы внутри блока */ clear: left; /* Отменяем действие float */ } </style> </head> <body> <div> <div>BLOGGOOD. RU</div> <div> <p><a href="#">Главная</a></p> <p><a href="#">Интервью</a></p> <p><a href="#">Вопросы</a></p> </div> <div> <h3>История, которая меня впечатлила…</h3> <p> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! </p> </div> <div>© Костаневич Степан - BlogGood.ru</div> </div> </body> </html>
Результат:
○ Двухколоночный макет (слева контент, справа меню):
Теперь код:
<html> <head> <title>Двухколоночный макет на BlogGood. ru</title> <style> body { font: 13pt Arial, Helvetica, sans-serif; /* Шрифт теста */ background: #e1dfb9; /* Цвет фона */ } h3 { font-size: 18px; /* Размер шрифта в заголовке */ color: #080808; /* Цвет заголовка */ margin-top: 0; /* Отступ сверху */ } .container { width: 600px; /* Ширина слоя */ margin: 0 auto; /* Выравнивнить весь блок по центру */ background: #f0f0f0; /* Цвет фона левой колонки */ } .header { font-size: 38px; /* Размер текста в шапке */ text-align: center; /* Выравнивание текст шапки по центру */ padding: 5px; /* Отступы внутри блока шапки */ background: #8fa09b; /* Цвет фона шапки */ color: #fff; /* Цвет текста */ } .sidebar { margin-top: 10px; width: 110px; /* Ширина блока */ padding: 0 10px; /* Отступы внутри левого блока */ float: right; /* Обтекание блока по левому краю */ } .content { margin-right: 130px; /* Отступ справа */ padding: 10px; /* Отступы внутри правого блока */ background: #fff; /* Цвет фона правого блока */ } . footer { background: #8fa09b; /* Цвет фона нижнего блока-подвала */ color: #fff; /* Цвет текста подвала */ padding: 5px; /* Отступы внутри блока */ clear: right; /* Отменяем действие float */ } </style> </head> <body> <div> <div>BLOGGOOD.RU</div> <div> <p><a href="#">Главная</a></p> <p><a href="#">Интервью</a></p> <p><a href="#">Вопросы</a></p> </div> <div> <h3>История, которая меня впечатлила…</h3> <p> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! </p> </div> <div>© Костаневич Степан - BlogGood.ru</div> </div> </body> </html>
Результат:
Примечание: чтобы поменять местами блоки, достаточно поменять значение в строках 30, 33, 41:
(слева контент, справа меню)
float: right; /* Обтекание блока по левому краю */
margin-right: 130px; /* Отступ справа */
clear: right; /* Отменяем действие float */
(слева меню, справа контент)
float: left; /* Обтекание блока по правому краю */
margin-left: 130px; /* Отступ слева */
clear: left; /* Отменяем действие float */
○ Другие варианты фиксированного макета в две колонки. С левой стороны первый блок – это контент, с правой стороны второй блок – новости и под ними меню:
Код:
<html> <head> <title>Двухколоночный макет на BlogGood. ru</title> <style> html,body{margin:0;padding:0} body{font: 76% arial,sans-serif;text-align:center} p{margin:0 10px 10px} a{display:block;color: #981793;padding:10px} div#header h2{height:80px;line-height:80px;margin:0; padding-left:10px;background: #EEE;color: #79B30B} div#container{text-align:left} div#content p{line-height:1.4} div#navigation{background:#B9CAFF} div#extra{background:#FF8539} div#footer{background: #333;color: #FFF} div#footer p{margin:0;padding:5px 10px} div#container{width:700px;margin:0 auto} div#content{float:left;width:500px} div#navigation{float:right;width:200px} div#extra{float:right;clear:right;width:200px} div#footer{clear:both;width:100%} </style> </head> <body> <div> <div><h2>BlogGood.ru</h2></div> <div> <div> <p><strong>1) Контент.</strong> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! Рейчел Беквит – американская девочка из Сиетла, которая родилась в 2002 году. Однажды в церкви, которую посещала ее семья, она узнала, что в Африке каждый день погибает 4,5 тысяч деток от страшных болезней, потому что им приходиться утолять свою жажду водой из грязных луж и зараженных болот. Эта статистика толкнула Рейчел на удивительный поступок. Перед празднованием своего 9-летия она попросила своих родных и близких, чтобы они не тратили деньги ей на игрушки, сладости или другие какие-либо подарки. Вместо этого она призвала их всех пожертвовать эти деньги благотворительной организации Charity Water, которая помогала людям в тех странах, где не хватало питьевой воды. </p> </div> </div> <div> <p><strong>2) Новости. </strong> Как управлять человечеством? Конечно же, установить законы. А какими бывают законы? Строгими, справедливыми, вечными, а еще … нелепыми! Прочитайте эту интересную статью и узнайте, в каких странах действуют эти нелепые законы. Я также постаралась найти причину возникновения каждого нелепого закона. </p> </div> <div> <p><strong>3) Меню.</strong> Продолжаем узнавать интересные и невероятные факты. Тем, кто считает, что человеку свойственны пять чувств, спешу сказать, что их уже девять! Если вы интересуетесь интересными фактами о человеческом организме, то эта статья как раз для вас! Узнайте больше о себе и о своих органах чувств.</p> </div> <div><p>BlogGood.ru</p></div> </div> </body> </html>
Результат:
○ Другие варианты фиксированного макета в две колонки. С левой стороны первый блок – это контент, с правой стороны второй блок – новости и под ними меню:
Код:
<html> <head> <title>Двухколоночный макет на BlogGood. ru</title> <style> html,body{margin:0;padding:0} body{font: 76% arial,sans-serif;text-align:center} p{margin:0 10px 10px} a{display:block;color: #981793;padding:10px} div#header h2{height:80px;line-height:80px;margin:0; padding-left:10px;background: #EEE;color: #79B30B} div#container{text-align:left} div#content p{line-height:1.4} div#navigation{background:#B9CAFF} div#extra{background:#FF8539} div#footer{background: #333;color: #FFF} div#footer p{margin:0;padding:5px 10px} div#container{width:700px;margin:0 auto} div#content{float:right;width:500px} div#navigation{float:left;width:200px} div#extra{float:left;clear:left;width:200px} div#footer{clear:both;width:100%} </style> </head> <body> <div> <div><h2>BlogGood.ru</h2></div> <div> <div> <p><strong>1) Контент.</strong> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! Рейчел Беквит – американская девочка из Сиетла, которая родилась в 2002 году. Однажды в церкви, которую посещала ее семья, она узнала, что в Африке каждый день погибает 4,5 тысяч деток от страшных болезней, потому что им приходиться утолять свою жажду водой из грязных луж и зараженных болот. Эта статистика толкнула Рейчел на удивительный поступок. Перед празднованием своего 9-летия она попросила своих родных и близких, чтобы они не тратили деньги ей на игрушки, сладости или другие какие-либо подарки. Вместо этого она призвала их всех пожертвовать эти деньги благотворительной организации Charity Water, которая помогала людям в тех странах, где не хватало питьевой воды. </p> </div> </div> <div> <p><strong>2) Новости. </strong> Как управлять человечеством? Конечно же, установить законы. А какими бывают законы? Строгими, справедливыми, вечными, а еще … нелепыми! Прочитайте эту интересную статью и узнайте, в каких странах действуют эти нелепые законы. Я также постаралась найти причину возникновения каждого нелепого закона. </p> </div> <div> <p><strong>3) Меню.</strong> Продолжаем узнавать интересные и невероятные факты. Тем, кто считает, что человеку свойственны пять чувств, спешу сказать, что их уже девять! Если вы интересуетесь интересными фактами о человеческом организме, то эта статья как раз для вас! Узнайте больше о себе и о своих органах чувств.</p> </div> <div><p>BlogGood.ru</p></div> </div> </body> </html>
Результат:
Резиновый двухколоночный макет
Многие веб-мастера используют резиновые макеты сайтов. Это удобно, так как размер сайта автоматически подстраивается под размер монитора.
○ Резиновый двухколоночный макет (слева меню, справа контент):
Теперь код:
<html> <head> <title>Резиновый двухколоночный макет на BlogGood.ru</title> <style> body { font: 14px Arial, Helvetica, sans-serif; /* Рубленый шрифт текста */ margin: 0; /* Отступы на странице */ } h2 { font-size: 36px; /* Размер шрифта заголовка шапки */ margin: 0; /* Убираем отступы */ color: #fc6; /* Цвет текста заголовка шапки */ } h3 { margin-top: 0; /* Убираем отступ сверху */ } .header { background: #0080c0; /* Цвет фона шапки */ padding: 10px; /* Поля вокруг текста */ } .sidebar { float: left; /* Обтекание справа */ border: 1px solid #333; /* Рамка левого меню */ width: 20%; /* Ширина левой колонки */ padding: 5px; /* Поля внутри блока */ margin: 10px 10px 20px 5px; /* Значения отступа от блока */ } . content { margin: 10px 5px 20px 25%; /* Значения отступа от левого блока */ padding: 5px; /* Поля внутри блока */ border: 1px solid #333; /* Рамка контента */ } .footer { background: #333; /* Цвет фона подвал (футера) */ padding: 5px; /* Поля внутри блока */ color: #fff; /* Цвет текста футера */ clear: left; /* Отменяем действие float */ } </style> </head> <body> <div><h2>Блог BlogGood.ru</h2></div> <div> <p><a href="#">Главная</a></p> <p><a href="#">Интервью</a></p> <p><a href="#">Вопросы</a></p> </div> <div> <h3>История, которая меня впечатлила…</h3> <p> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! </p> </div> <div>© Костаневич Степан</div> </body> </html>
Результат:
○ Резиновый двухколоночный макет (справа меню, слева контент):
Чтобы поменять местами меню с контентом (справа меню, слева контент), достаточно в строке 22 (.sidebar) исправить значение leftна right:
float: right; /* Обтекание справа */
и в строке 29 (.content) заменить числовое значение 10px 5px 20px 25% на 10px 25% 20px 5px
margin: 10px 25% 20px 5px; /* Значения отступа от правого блока */
<html> <head> <title>Резиновый двухколоночный макет на BlogGood.ru</title> <style> body { font: 14px Arial, Helvetica, sans-serif; /* Рубленый шрифт текста */ margin: 0; /* Отступы на странице */ } h2 { font-size: 36px; /* Размер шрифта заголовка шапки */ margin: 0; /* Убираем отступы */ color: #fc6; /* Цвет текста заголовка шапки */ } h3 { margin-top: 0; /* Убираем отступ сверху */ } . header { background: #0080c0; /* Цвет фона шапки */ padding: 10px; /* Поля вокруг текста */ } .sidebar { float: right; /* Обтекание справа */ border: 1px solid #333; /* Рамка левого меню */ width: 20%; /* Ширина левой колонки */ padding: 5px; /* Поля внутри блока */ margin: 10px 10px 20px 5px; /* Значения отступа от блока */ } .content { margin: 10px 25% 20px 5px; /* Значения отступа от правого блока */ padding: 5px; /* Поля внутри блока */ border: 1px solid #333; /* Рамка контента */ } .footer { background: #333; /* Цвет фона подвал (футера) */ padding: 5px; /* Поля внутри блока */ color: #fff; /* Цвет текста футера */ clear: left; /* Отменяем действие float */ } </style> </head> <body> <div><h2>Блог BlogGood.ru</h2></div> <div> <p><a href="#">Главная</a></p> <p><a href="#">Интервью</a></p> <p><a href="#">Вопросы</a></p> </div> <div> <h3>История, которая меня впечатлила…</h3> <p> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! </p> </div> <div>© Костаневич Степан</div> </body> </html>
Результат:
○ Другие варианты резинового макета в две колонки. С левой стороны первый блок – это контент, с правой стороны второй блок – новости и под ними меню:
Код:
<html> <head> <title>Двухколоночный резиновый макет на BlogGood.ru</title> <style> html,body{margin:0;padding:0} body{font: 76% arial,sans-serif} p{margin:0 10px 10px} a{display:block;color: #981793;padding:10px} div#header h2{height:80px;line-height:80px;margin:0; padding-left:10px;background: #EEE;color: #79B30B} div#content p{line-height:1.4} div#navigation{background:#B9CAFF} div#extra{background:#FF8539} div#footer{background: #333;color: #FFF} div#footer p{margin:0;padding:5px 10px} div#wrapper{float:left;width:100%;margin-left:-200px} div#content{margin-left:200px} div#navigation{float:right;width:200px} div#extra{float:right;clear:right;width:200px} div#footer{clear:both;width:100%} </style> </head> <body> <div> <div><h2>BlogGood. ru</h2></div> <div> <div> <p><strong>1) Контент.</strong> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! Рейчел Беквит – американская девочка из Сиетла, которая родилась в 2002 году. Однажды в церкви, которую посещала ее семья, она узнала, что в Африке каждый день погибает 4,5 тысяч деток от страшных болезней, потому что им приходиться утолять свою жажду водой из грязных луж и зараженных болот. Эта статистика толкнула Рейчел на удивительный поступок. Перед празднованием своего 9-летия она попросила своих родных и близких, чтобы они не тратили деньги ей на игрушки, сладости или другие какие-либо подарки. Вместо этого она призвала их всех пожертвовать эти деньги благотворительной организации Charity Water, которая помогала людям в тех странах, где не хватало питьевой воды. </p> </div> </div> <div> <p><strong>2) Новости.</strong> Как управлять человечеством? Конечно же, установить законы. А какими бывают законы? Строгими, справедливыми, вечными, а еще … нелепыми! Прочитайте эту интересную статью и узнайте, в каких странах действуют эти нелепые законы. Я также постаралась найти причину возникновения каждого нелепого закона. </p> </div> <div> <p><strong>3) Меню.</strong> Продолжаем узнавать интересные и невероятные факты. Тем, кто считает, что человеку свойственны пять чувств, спешу сказать, что их уже девять! Если вы интересуетесь интересными фактами о человеческом организме, то эта статья как раз для вас! Узнайте больше о себе и о своих органах чувств. </p> </div> <div><p>BlogGood.ru</p></div> </div> </body> </html>
Результат:
○ Другие варианты резинового макета в две колонки. С левой стороны первый блок – это контент, с правой стороны второй блок – новости и под ними меню:
Код:
<html> <head> <title>Двухколоночный резиновый макет на BlogGood.ru</title> <style> html,body{margin:0;padding:0} body{font: 76% arial,sans-serif} p{margin:0 10px 10px} a{display:block;color: #981793;padding:10px} div#header h2{height:80px;line-height:80px;margin:0; padding-left:10px;background: #EEE;color: #79B30B} div#content p{line-height:1.4} div#navigation{background:#B9CAFF} div#extra{background:#FF8539} div#footer{background: #333;color: #FFF} div#footer p{margin:0;padding:5px 10px} div#wrapper{float:right;width:100%;margin-left:-200px} div#content{margin-left:200px} div#navigation{float:left;width:200px} div#extra{float:left;clear:left;width:200px} div#footer{clear:both;width:100%} </style> </head> <body> <div> <div><h2>BlogGood. ru</h2></div> <div> <div> <p><strong>1) Контент.</strong> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! Рейчел Беквит – американская девочка из Сиетла, которая родилась в 2002 году. Однажды в церкви, которую посещала ее семья, она узнала, что в Африке каждый день погибает 4,5 тысяч деток от страшных болезней, потому что им приходиться утолять свою жажду водой из грязных луж и зараженных болот. Эта статистика толкнула Рейчел на удивительный поступок. Перед празднованием своего 9-летия она попросила своих родных и близких, чтобы они не тратили деньги ей на игрушки, сладости или другие какие-либо подарки. Вместо этого она призвала их всех пожертвовать эти деньги благотворительной организации Charity Water, которая помогала людям в тех странах, где не хватало питьевой воды. </p> </div> </div> <div> <p><strong>2) Новости.</strong> Как управлять человечеством? Конечно же, установить законы. А какими бывают законы? Строгими, справедливыми, вечными, а еще … нелепыми! Прочитайте эту интересную статью и узнайте, в каких странах действуют эти нелепые законы. Я также постаралась найти причину возникновения каждого нелепого закона. </p> </div> <div> <p><strong>3) Меню.</strong> Продолжаем узнавать интересные и невероятные факты. Тем, кто считает, что человеку свойственны пять чувств, спешу сказать, что их уже девять! Если вы интересуетесь интересными фактами о человеческом организме, то эта статья как раз для вас! Узнайте больше о себе и о своих органах чувств. </p> </div> <div><p>BlogGood.ru</p></div> </div> </body> </html>
Результат:
Триколоночные макеты (веб-страницы)
Фиксированный макет в три колонки
Частенько макет как в три колонки используют для создания блога.
○ В первой колонке размещается контент, во второй колонке может находиться реклама или новости и в третей колонке меню:
Код:
<html> <head> <title>Фиксированный макет в три колонки на блоге BlogGood.ru</title> <style> html,body{margin:0;padding:0} body{font: 76% arial,sans-serif;text-align:center} p{margin:0 10px 10px} a{display:block;color: #981793;padding:10px} div#header h2{height:80px;line-height:80px;margin:0; padding-left:10px;background: #EEE;color: #79B30B} div#container{text-align:left} div#content p{line-height:1. 4} div#navigation{background:#B9CAFF} div#extra{background:#FF8539} div#footer{background: #333;color: #FFF} div#footer p{margin:0;padding:5px 10px} div#container{width:700px;margin:0 auto} div#wrapper{float:left;width:100%} div#content{margin-right: 300px} div#navigation{float:left;width:150px;margin-left:-300px} div#extra{float:left;width:150px;margin-left:-150px} div#footer{clear:left;width:100%} </style> </head> <body> <div> <div><h2>BlogGood.ru</h2></div> <div> <div> <p><strong>1) Контент.</strong> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! Рейчел Беквит – американская девочка из Сиетла, которая родилась в 2002 году. Однажды в церкви, которую посещала ее семья, она узнала, что в Африке каждый день погибает 4,5 тысяч деток от страшных болезней, потому что им приходиться утолять свою жажду водой из грязных луж и зараженных болот. Эта статистика толкнула Рейчел на удивительный поступок. Перед празднованием своего 9-летия она попросила своих родных и близких, чтобы они не тратили деньги ей на игрушки, сладости или другие какие-либо подарки. Вместо этого она призвала их всех пожертвовать эти деньги благотворительной организации Charity Water, которая помогала людям в тех странах, где не хватало питьевой воды. </p> </div> </div> <div> <p><strong>2) Новости. </strong> Как управлять человечеством? Конечно же, установить законы. А какими бывают законы? Строгими, справедливыми, вечными, а еще … нелепыми! Прочитайте эту интересную статью и узнайте, в каких странах действуют эти нелепые законы. Я также постаралась найти причину возникновения каждого нелепого закона. </p> </div> <div> <p><strong>3) Меню.</strong> Продолжаем узнавать интересные и невероятные факты. Тем, кто считает, что человеку свойственны пять чувств, спешу сказать, что их уже девять! Если вы интересуетесь интересными фактами о человеческом организме, то эта статья как раз для вас! Узнайте больше о себе и о своих органах чувств.</p> </div> <div><p>BlogGood.ru</p></div> </div> </body> </html>
Результат:
○ Следующий вариант фиксированного трехблочного макета, когда в первой колонке размещается меню, во второй колонке может находиться реклама или новости и в третей колонке контент:
Код:
<html> <head> <title>Фиксированный макет в три колонки на блоге BlogGood. ru</title> <style> html,body{margin:0;padding:0} body{font: 76% arial,sans-serif;text-align:center} p{margin:0 10px 10px} a{display:block;color: #981793;padding:10px} div#header h2{height:80px;line-height:80px;margin:0; padding-left:10px;background: #EEE;color: #79B30B} div#container{text-align:left} div#content p{line-height:1.4} div#navigation{background:#B9CAFF} div#extra{background:#FF8539} div#footer{background: #333;color: #FFF} div#footer p{margin:0;padding:5px 10px} div#container{width:700px;margin:0 auto} div#wrapper{float:left;width:100%} div#content{margin-left: 300px} div#navigation{float:left;width:150px;margin-left:-700px} div#extra{float:left;width:150px;margin-left:-550px} div#footer{clear:left;width:100%} </style> </head> <body> <div> <div><h2>BlogGood.ru</h2></div> <div> <div> <p><strong>1) Контент. </strong> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! Рейчел Беквит – американская девочка из Сиетла, которая родилась в 2002 году. Однажды в церкви, которую посещала ее семья, она узнала, что в Африке каждый день погибает 4,5 тысяч деток от страшных болезней, потому что им приходиться утолять свою жажду водой из грязных луж и зараженных болот. Эта статистика толкнула Рейчел на удивительный поступок. Перед празднованием своего 9-летия она попросила своих родных и близких, чтобы они не тратили деньги ей на игрушки, сладости или другие какие-либо подарки. Вместо этого она призвала их всех пожертвовать эти деньги благотворительной организации Charity Water, которая помогала людям в тех странах, где не хватало питьевой воды. </p> </div> </div> <div> <p><strong>2) Новости.</strong> Как управлять человечеством? Конечно же, установить законы. А какими бывают законы? Строгими, справедливыми, вечными, а еще … нелепыми! Прочитайте эту интересную статью и узнайте, в каких странах действуют эти нелепые законы. Я также постаралась найти причину возникновения каждого нелепого закона. </p> </div> <div> <p><strong>3) Меню.</strong> Продолжаем узнавать интересные и невероятные факты. Тем, кто считает, что человеку свойственны пять чувств, спешу сказать, что их уже девять! Если вы интересуетесь интересными фактами о человеческом организме, то эта статья как раз для вас! Узнайте больше о себе и о своих органах чувств. </p> </div> <div><p>BlogGood.ru</p></div> </div> </body> </html>
Результат:
○ Следующий самый распространенный вариант фиксированного трехблочного макета, когда в первой колонке размещается меню, во второй колонке может находиться контент и в третьей колонке реклама или новости:
Код:
<html> <head> <title>Фиксированный макет в три колонки на блоге BlogGood.ru</title> <style> html,body{margin:0;padding:0} body{font: 76% arial,sans-serif;text-align:center} p{margin:0 10px 10px} a{display:block;color: #981793;padding:10px} div#header h2{height:80px;line-height:80px;margin:0; padding-left:10px;background: #EEE;color: #79B30B} div#container{text-align:left} div#content p{line-height:1.4} div#navigation{background:#B9CAFF} div#extra{background:#FF8539} div#footer{background: #333;color: #FFF} div#footer p{margin:0;padding:5px 10px} div#container{width:700px;margin:0 auto} div#wrapper{float:left;width:100%} div#content{margin: 0 150px} div#navigation{float:left;width:150px;margin-left:-700px} div#extra{float:left;width:150px;margin-left:-150px} div#footer{clear:left;width:100%} rgin-left:-550px} div#footer{clear:left;width:100%} </style> </head> <body> <div> <div><h2>BlogGood. ru</h2></div> <div> <div> <p><strong>1) Контент.</strong> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! Рейчел Беквит – американская девочка из Сиетла, которая родилась в 2002 году. Однажды в церкви, которую посещала ее семья, она узнала, что в Африке каждый день погибает 4,5 тысяч деток от страшных болезней, потому что им приходиться утолять свою жажду водой из грязных луж и зараженных болот. Эта статистика толкнула Рейчел на удивительный поступок. Перед празднованием своего 9-летия она попросила своих родных и близких, чтобы они не тратили деньги ей на игрушки, сладости или другие какие-либо подарки. Вместо этого она призвала их всех пожертвовать эти деньги благотворительной организации Charity Water, которая помогала людям в тех странах, где не хватало питьевой воды. </p> </div> </div> <div> <p><strong>2) Новости.</strong> Как управлять человечеством? Конечно же, установить законы. А какими бывают законы? Строгими, справедливыми, вечными, а еще … нелепыми! Прочитайте эту интересную статью и узнайте, в каких странах действуют эти нелепые законы. Я также постаралась найти причину возникновения каждого нелепого закона. </p> </div> <div> <p><strong>3) Меню.</strong> Продолжаем узнавать интересные и невероятные факты. Тем, кто считает, что человеку свойственны пять чувств, спешу сказать, что их уже девять! Если вы интересуетесь интересными фактами о человеческом организме, то эта статья как раз для вас! Узнайте больше о себе и о своих органах чувств. </p> </div> <div><p>BlogGood.ru</p></div> </div> </body> </html>
Результат:
Резиновый макет в три колонки
○ В первой колонке размещается контент, во второй колонке может находиться реклама или новости и в третьей колонке меню.
Код:
<html> <head> <title>Резиновый макет в три колонки на блоге BlogGood.ru</title> <style> html,body{margin:0;padding:0} body{font: 76% arial,sans-serif} p{margin:0 10px 10px} a{display:block;color: #981793;padding:10px} div#header h2{height:80px;line-height:80px;margin:0; padding-left:10px;background: #EEE;color: #79B30B} div#content p{line-height:1.4} div#navigation{background:#B9CAFF} div#extra{background:#FF8539} div#footer{background: #333;color: #FFF} div#footer p{margin:0;padding:5px 10px} div#wrapper{float:left;width:100%} div#content{margin-right: 50%} div#navigation{float:left;width:25%;margin-left:-50%} div#extra{float:left;width:25%;margin-left:-25%} div#footer{clear:left;width:100%} </style> </head> <body> <div> <div><h2>BlogGood. ru</h2></div> <div> <div> <p><strong>1) Контент.</strong> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! Рейчел Беквит – американская девочка из Сиетла, которая родилась в 2002 году. Однажды в церкви, которую посещала ее семья, она узнала, что в Африке каждый день погибает 4,5 тысяч деток от страшных болезней, потому что им приходиться утолять свою жажду водой из грязных луж и зараженных болот. Эта статистика толкнула Рейчел на удивительный поступок. Перед празднованием своего 9-летия она попросила своих родных и близких, чтобы они не тратили деньги ей на игрушки, сладости или другие какие-либо подарки. Вместо этого она призвала их всех пожертвовать эти деньги благотворительной организации Charity Water, которая помогала людям в тех странах, где не хватало питьевой воды. </p> </div> </div> <div> <p><strong>2) Новости.</strong> Как управлять человечеством? Конечно же, установить законы. А какими бывают законы? Строгими, справедливыми, вечными, а еще … нелепыми! Прочитайте эту интересную статью и узнайте, в каких странах действуют эти нелепые законы. Я также постаралась найти причину возникновения каждого нелепого закона. </p> </div> <div> <p><strong>3) Меню.</strong> Продолжаем узнавать интересные и невероятные факты. Тем, кто считает, что человеку свойственны пять чувств, спешу сказать, что их уже девять! Если вы интересуетесь интересными фактами о человеческом организме, то эта статья как раз для вас! Узнайте больше о себе и о своих органах чувств. </p> </div> <div><p>BlogGood.ru</p></div> </div> </body> </html>
Результат:
○ Следующий вариант резинового трехблочного макета, когда в первой колонке размещается меню, во второй колонке может находиться реклама или новости и в третьей колонке контент.
Код:
<html> <head> <title>Резиновый макет в три колонки на блоге BlogGood.ru</title> <style> html,body{margin:0;padding:0} body{font: 76% arial,sans-serif} p{margin:0 10px 10px} a{display:block;color: #981793;padding:10px} div#header h2{height:80px;line-height:80px;margin:0; padding-left:10px;background: #EEE;color: #79B30B} div#content p{line-height:1.4} div#navigation{background:#B9CAFF} div#extra{background:#FF8539} div#footer{background: #333;color: #FFF} div#footer p{margin:0;padding:5px 10px} div#wrapper{float:left;width:100%} div#content{margin-left: 50%} div#navigation{float:left;width:25%;margin-left:-100%} div#extra{float:left;width:25%;margin-left:-75%} div#footer{clear:left;width:100%} </style> </head> <body> <div> <div><h2>BlogGood. ru</h2></div> <div> <div> <p><strong>1) Контент.</strong> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! Рейчел Беквит – американская девочка из Сиетла, которая родилась в 2002 году. Однажды в церкви, которую посещала ее семья, она узнала, что в Африке каждый день погибает 4,5 тысяч деток от страшных болезней, потому что им приходиться утолять свою жажду водой из грязных луж и зараженных болот. Эта статистика толкнула Рейчел на удивительный поступок. Перед празднованием своего 9-летия она попросила своих родных и близких, чтобы они не тратили деньги ей на игрушки, сладости или другие какие-либо подарки. Вместо этого она призвала их всех пожертвовать эти деньги благотворительной организации Charity Water, которая помогала людям в тех странах, где не хватало питьевой воды. </p> </div> </div> <div> <p><strong>2) Новости.</strong> Как управлять человечеством? Конечно же, установить законы. А какими бывают законы? Строгими, справедливыми, вечными, а еще … нелепыми! Прочитайте эту интересную статью и узнайте, в каких странах действуют эти нелепые законы. Я также постаралась найти причину возникновения каждого нелепого закона. </p> </div> <div> <p><strong>3) Меню.</strong> Продолжаем узнавать интересные и невероятные факты. Тем, кто считает, что человеку свойственны пять чувств, спешу сказать, что их уже девять! Если вы интересуетесь интересными фактами о человеческом организме, то эта статья как раз для вас! Узнайте больше о себе и о своих органах чувств. </p> </div> <div><p>BlogGood.ru</p></div> </div> </body> </html>
Результат:
○ Следующий самый распространенный вариант резинового трехблочного макета, когда в первой колонке размещается меню, во второй колонке может находиться контент и в третьей колонке может находиться реклама или новости:
Код:
<html> <head> <title>Резиновый макет в три колонки на блоге BlogGood.ru</title> <style> html,body{margin:0;padding:0} body{font: 76% arial,sans-serif} p{margin:0 10px 10px} a{display:block;color: #981793;padding:10px} div#header h2{height:80px;line-height:80px;margin:0; padding-left:10px;background: #EEE;color: #79B30B} div#content p{line-height:1.4} div#navigation{background:#B9CAFF} div#extra{background:#FF8539} div#footer{background: #333;color: #FFF} div#footer p{margin:0;padding:5px 10px} div#footer a{display:inline;padding:0;color: #C6D5FD} div#wrapper{float:left;width:100%} div#content{margin: 0 25%} div#navigation{float:left;width:25%;margin-left:-25%} div#extra{float:left;width:25%;margin-left:-100%} div#footer{clear:left;width:100%} </style> </head> <body> <div> <div><h2>BlogGood. ru</h2></div> <div> <div> <p><strong>1) Контент.</strong> Как часто вы задумываетесь над смыслом жизни? А находите ли вы ответ на вопрос «в чем смысл жизни»? Что уже успели сделать за дарованные вам годы жизни? Вот еще один год подходит к концу… Довольны ли вы тем, как вы его прожили? Я очень часто огорчаюсь от того, что за свои годы ничего существенного не достигла. Нет в моей жизни такого поступка, которым действительно можно было бы гордиться. И когда я познакомилась с историей этой маленькой девочки, я до глубины души была впечатлена! Рейчел Беквит – американская девочка из Сиетла, которая родилась в 2002 году. Однажды в церкви, которую посещала ее семья, она узнала, что в Африке каждый день погибает 4,5 тысяч деток от страшных болезней, потому что им приходиться утолять свою жажду водой из грязных луж и зараженных болот. Эта статистика толкнула Рейчел на удивительный поступок. Перед празднованием своего 9-летия она попросила своих родных и близких, чтобы они не тратили деньги ей на игрушки, сладости или другие какие-либо подарки. Вместо этого она призвала их всех пожертвовать эти деньги благотворительной организации Charity Water, которая помогала людям в тех странах, где не хватало питьевой воды. </p> </div> </div> <div> <p><strong>2) Новости.</strong> Как управлять человечеством? Конечно же, установить законы. А какими бывают законы? Строгими, справедливыми, вечными, а еще … нелепыми! Прочитайте эту интересную статью и узнайте, в каких странах действуют эти нелепые законы. Я также постаралась найти причину возникновения каждого нелепого закона. </p> </div> <div> <p><strong>3) Меню.</strong> Продолжаем узнавать интересные и невероятные факты. Тем, кто считает, что человеку свойственны пять чувств, спешу сказать, что их уже девять! Если вы интересуетесь интересными фактами о человеческом организме, то эта статья как раз для вас! Узнайте больше о себе и о своих органах чувств. </p> </div> <div><p>BlogGood.ru</p></div> </div> </body> </html>
Результат:
Постараюсь в следующей статье написать свои собственные макеты, может, мои решения вам покажутся лучше.
Понравился пост? Помоги другим узнать об этой статье, кликни на кнопку социальных сетей ↓↓↓
Добавить комментарий
Метки: css, html, Дизайн и верстка
Скрапинг сайта с помощью Python: гайд для новичков
В этой статье мы разберемся, как создать HTML скрапер на Python, который получает неофициальный доступ к коду сайта и позволяет извлечь необходимые данные.
Отличие от вызовов API
Альтернативный метод получения данных сайта — вызовы API. Взаимодействие с API — это официально предоставляемый владельцем сайта способ получения данных прямо из БД или обычных файлов. Обычно для этого требуется разрешение владельца сайта и специальный токен. Однако апи доступен не всегда, поэтому скрапинг так привлекателен, однако его законность вызывает вопросы.
Юридические соображения
Скрапинг может нарушать копирайт или правила использования сайта, особенно когда он используется для получения прибыли, конкурентного преимущества или причинения ущерба (например из-за слишком частых запросов). Однако скрапинг публично доступен и используется для личного использования, академических целей или безвредного некоммерческого использования.
Если данные являются платными, требуют регистрации, имеют явную защиту от скрапинга, содержат конфиденциальные данные или личные данные пользователей, то нужно избегать любого из видов скрапинга.
Установка Beautiful Soup в Python
Beautiful Soup — это Python библиотека для скрапинга данных сайтов через HTML код.
Установите последнюю версию библиотеки.
$ pip install beautifulsoup4
Чтобы делать запросы, установите requests (библиотеку для отправки HTTP запросов):
$ pip install requests
Импортируйте библиотеки в файле Python или Jupiter notebook:
from bs4 import BeautifulSoup import requests
И несколько стандартных библиотек, которые потребуются для скрапинга на Python:
import re from re import sub from decimal import Decimal import io from datetime import datetime import pandas as pd
Введение
Представьте, что мы хотим произвести скрапинг платформы, содержащей общедоступные объявления о недвижимости. Мы хотим получить цену недвижимости, ее адрес, расстояние, название станции и ближайший до нее тип транспорта для того, чтобы узнать, как цены на недвижимость распределяются в зависимости от доступности общественного транспорта в конкретном городе.
Предположим, что запрос приведет к странице результатов, которая выглядит следующим образом:
Как только мы узнаем, в каких элементах сайта хранятся необходимые данные, нам нужно придумать логику скрапинга, которая позволит нам получить всю нужную информацию из каждого объявления.
Нам предстоит ответить на следующие вопросы:
- Как получить одну точку данных для одного свойства (например данные из тега price в первом объявлении)?
- Как получить все точки данных для одного свойства со всей страницы (например все теги price с одной страницы)?
- Как получить все точки данных для одного свойства всех страниц с результатами (например все теги price со всех страниц с результатами)?
- Как устранить несоответствие, когда данные могут быть разных типов (например, есть некоторые объявления, в которых в поле цены указана цена по запросу. В конечном итоге у нас будет столбец, состоящий из числовых и строковых значений, что в нашем случае не позволяет провести анализ)?
- Как лучше извлечь сложную информацию (Например, предположим, что каждое объявление содержит информацию об общественном транспорте, например “0,5 мили до станции метро XY”)?
Логика получения одной точки данных
Все примеры кода для скрапинга на Python можно найти в Jupiter Notebook файле на GitHub автора.
Запрос кода сайта
Во-первых, мы используем поисковый запрос, который мы сделали в браузере в скрипте Python:
# поиск в определённой зоне url = 'https://www.website.com/london/page_size=25&q=london&pn=1' # делаем запрос и получаем html html_text = requests.get(url).text # используем парсер lxml soup = BeautifulSoup(html_text, 'lxml')
Переменная soup содержит полный HTML-код страницы с результатами поиска.
Поиск тегов-свойств
Для этого нам потребуется браузер. Некоторые популярные браузеры предлагают удобный способ получения информации о конкретном элементе напрямую. В Google Chrome вы можете выбрать любой элемент сайта и, нажав правой кнопкой, выбрать пункт «Исследовать элемент» . Справа откроется код сайта с выделенным элементом.
HTML классы и атрибут id
HTML-классы и id в основном используются для ссылки на класс в таблице стилей CSS, чтобы данные могли отображаться согласованным образом.
В приведенном выше примере, класс, используемый для получения информации о ценах из одного объявления, также применяется для получения цен из других объявлений (что соответствует основной цели класса).
Обратите внимание, что HTML-класс также может ссылаться на ценники за пределами раздела объявлений (например, специальные предложения, которые не связаны с поисковым запросом, но все равно отображаются на странице результатов). Однако для целей этой статьи мы фокусируемся только на ценах в объявлениях о недвижимости.
Вот почему мы сначала ориентируемся на объявление и ищем HTML-класс только в исходном коде для конкретного объявления:
# используем парсер lxml soup = BeautifulSoup(html_text, 'lxml') # находим одно объявление ad = soup. find('div', class_ = 'css-ad-wrapper-123456') # находим цену price = ad.find('p', class_ = 'css-aaabbbccc').text
Использование .text в конце метода find() позволяет нам возвращать только обычный текст, как показано в браузере. Без .text он вернет весь исходный код строки HTML, на которую ссылается класс:
Важное примечание: нам всегда нужно указывать элемент, в данном случае это p.
Логика получения всех точек данных с одной страницы
Чтобы получить ценники для всех объявлений, мы применяем метод find.all() вместо find():
ads = ad.find_all('p', class_ = 'css-ad-wrapper-123456')
Переменная ads теперь содержит HTML-код для каждого объявления на первой странице результатов в виде списка списков. Этот формат хранения очень полезен, так как он позволяет получить доступ к исходному коду для конкретных объявлений по индексу.
Чтобы получить все ценники, мы используем словарь для сбора данных:
map = {} id = 0 # получаем все элементы ads = ad. find_all('p', class_ = 'css-ad-wrapper-123456') for i in range(len(ads)): ad = ads[i] id += 1 map[id] = {} # находим цену price = ad.find('p', class_ = 'css-aaabbbccc').text # находим адрес address = ad.find('p', class_ = 'css-address-123456').text map[id]["address"] = address map[id]["price"] = price
Важное примечание: использование идентификатора позволяет находить объявления в словаре:
Получение точек данных со всех страниц
Обычно результаты поиска либо разбиваются на страницы, либо бесконечно прокручиваются вниз.
Вариант 1. Веб-сайт с пагинацией
URL-адреса, полученные в результате поискового запроса, обычно содержат информацию о текущем номере страницы.
Как видно на рисунке выше, окончание URL-адреса относится к номеру страницы результатов.
Важное примечание: номер страницы в URL-адресе обычно становится видимым со второй страницы. Использование базового URL-адреса с дополнительным фрагментом &pn=1 для вызова первой страницы по-прежнему будет работать (в большинстве случаев).
Применение одного цикла for-loop поверх другого позволяет нам перебирать страницы результатов:
url = 'https://www.website.com/london/page_size=25&q=london&pn=' map = {} id = 0 # максимальное количество страниц max_pages = 15 for p in range(max_pages): cur_url = url + str(p + 1) print("Скрапинг страницы №: %d" % (p + 1)) html_text = requests.get(cur_url).text soup = BeautifulSoup(html_text, 'lxml') ads = soup.find_all('div', class_ = 'css-ad-wrapper-123456') for i in range(len(ads)): ad = ads[i] id += 1 map[id] = {} price = ad.find('p', class_ = 'css-aaabbbccc').text address = ad.find('p', class_ = 'css-address-123456'). text map[id]["address"] = address map[id]["price"] = price
Определение последней страницы результатов
Вы можете задаться вопросом, как определить последнюю страницу результатов? В большинстве случаев после достижения последней страницы, любой запрос с большим числом, чем фактическое число последней страницы, приведет нас обратно на первую страницу. Следовательно, использование очень большого числа для ожидания завершения сценария не работает. Через некоторое время он начнет собирать повторяющиеся значения.
Чтобы решить эту проблему, мы будем проверять, есть ли на странице кнопка с такой ссылкой:
url = 'https://www.website.com/london/page_size=25&q=london&pn=' map = {} id = 0 # используем очень большое число max_pages = 9999 for p in range(max_pages): cur_url = url + str(p + 1) print("Скрапинг страницы №: %d" % (p + 1)) html_text = requests.get(cur_url).text soup = BeautifulSoup(html_text, 'lxml') ads = soup. find_all('div', class_ = 'css-ad-wrapper-123456') # ищем ссылку в кнопке page_nav = soup.find_all('a', class_ = 'css-button-123456') if(len(page_nav) == 0): print("Максимальный номер страницы: %d" % (p)) break (...)
Вариант 2. Сайт с бесконечным скроллом
В таком случае HTML скрапер не сработает. Альтернативные методы мы обсудим в конце статьи.
Устранение несогласованности данных
Если нам нужно избавиться от ненужных данных в самом начале скрапинга на Python, мы можем использовать обходной метод:
Функция для определения аномалий
def is_skipped(price): ''' Определение цен, которые не являются ценами (например "Цена по запросу") ''' for i in range(len(price)): if(price[i] != '£' and price[i] != ',' and (not price[i].isdigit())): return True return False
И применить его при сборе данных:
(. \d.]', '', price)) return float(value)
Используем эту функцию:
(...) for i in range(len(ads)): ad = ads[i] id += 1 map[id] = {} price = ad.find('p', class_ = 'css-aaabbbccc').text if(is_dropped(price)): continue map[id]["price"] = to_num(price) (...)
Получение вложенных данных
Информация об общественном транспорте имеет вложенную структуру. Нам потребуются данные о расстоянии, названии станции и типе транспорта.
Отбор информации по правилам
Каждый кусочек данных представлен в виде: число миль, название станции. Используем слово «миль» в качестве разделителя.
map[id]["distance"] = [] map[id]["station"] = [] transport = ad.find_all('div', class_ = 'css-transport-123') for i in range(len(transport)): s = transport[i].text x = s.split(' miles ') map[id]["distance"].append(float(x[0])) map[id]["station"]. append(x[1])
Первоначально переменная transport хранит два списка в списке, поскольку есть две строки информации об общественном транспорте (например, “0,3 мили Слоун-сквер”, “0,5 мили Южный Кенсингтон”). Мы перебираем эти списки, используя len транспорта в качестве значений индекса, и разделяем каждую строку на две переменные: расстояние и станцию.
Поиск дополнительных HTML атрибутов для визуальной информации
В коде страницы мы можем найти атрибут testid, который указывает на тип общественного транспорта. Он не отображается в браузере, но отвечает за изображение, которое отображается на странице. Для получения этих данных нам нужно использовать класс css-StyledIcon:
map[id]["distance"] = [] map[id]["station"] = [] map[id]["transport_type"] = [] transport = ad.find_all('div', class_ = 'css-transport-123') type = ad.find_all('span', class_ = 'css-StyledIcon') for i in range(len(transport)): s = transport[i].text x = s. split(' miles ') map[id]["distance"].append(float(x[0])) map[id]["station"].append(x[1]) map[id]["transport_type"].append(type[i]['testid'])
Преобразование в датафрейм и экспорт в CSV
Когда скрапинг выполнен, все извлеченные данные доступны в словаре словарей.
Давайте сначала рассмотрим только одно объявление, чтобы лучше продемонстрировать заключительные шаги трансформации.
Преобразуем словарь в список списков, чтобы избавиться от вложенности
result = [] cur_row = 0 for idx in range(len(map[1]["distance"])): result.append([]) result[cur_row].append(str(map[1]["uuid"])) result[cur_row].append(str(map[1]["price"])) result[cur_row].append(str(map[1]["address"])) result[cur_row].append(str(map[1]["distance"][idx])) result[cur_row].append(str(map[1]["station"][idx])) result[cur_row].append(str(map[1]["transport_type"][idx])) cur_row += 1
Создаём датафрейм
df = pd. DataFrame(result, columns = ["ad_id", "price", "address", "distance", "station", "transport_type"])
Мы можем экспортировать датафрейм в CSV:
filename = 'test.csv' df.to_csv(filename)
Преобразование всех объявлений в датафрейм:
result = [] cur_row = 0 for id in map.keys(): cur_price = map[id]["price"] cur_address = map[id]["address"] for idx in range(len(map[id]["distance"])): result.append([]) result[cur_row].append(int(cur_id)) result[cur_row].append(float(cur_price)) result[cur_row].append(str(cur_address)) result[cur_row].append(float(map[id]["distance"][idx])) result[cur_row].append(str(map[id]["station"][idx])) result[cur_row].append(str(map[id]["transport_type"][idx])) cur_row += 1 # преобразование в датафрейм df = pd.DataFrame(result, columns = ["ad_id", "price","address", "distance", "station", "transport_type"]) # экспорт в csv filename = 'test. csv' df.to_csv(filename)
Мы это сделали! Теперь наш скрапер готов к тестированию.
Ограничения HTML скрапинга и его альтернативы
Этот пример показывает, насколько простым может быть скрапинг HTML на Python в стандартном случае. Для этого не нужно исследовать документацию. Это требует, скорее, творческого мышления, чем опыта веб-разработки.
Однако HTML скраперы имеют недостатки:
- Можно получить доступ только к информации в HTML-коде, которая загружается непосредственно при вызове URL-адреса. Веб-сайты, которые требуют JavaScript и Ajax для загрузки контента, не будут работать.
- HTML-классы или идентификаторы могут изменяться в связи с обновлениями веб-сайта.
- Может быть легко обнаружен, если запросы кажутся аномальными для веб-сайта (например, очень большое количество запросов в течение короткого промежутка времени).
Альтернативы:
- Shell скрипты — загружают всю страницу, с помощью регулярных выражений могут обрабатывать html.
- Screen scraper — изображают реального пользователя, используют браузер (Selenium, PhantomJS).
- ПО для скрапинга — рассчитаны на стандартные случаи, не требуют написания кода (webscraper.io).
- Веб сервисы скраперы — не требуют написания кода, хорошо справляются со скрапингом, платные (zyte.com).
Здесь вы найдёте список инструментов и библиотек для скрапинга.
Источник Turn Website Data Into Data Sets: A Beginner’s Guide to Python Web Scraping
Как утащить простой сайт за 5 минут
Когда начинаешь практиковаться в вёрстке сайтов, может быть очень полезно разобраться, как устроены сайты у других ребят. Вот как это сделать.
👉 Всё, что мы делаем в этой статье, мы делаем в учебных целях. Если вы просто скопируете себе чужой сайт и будете выдавать его за свой, это может плохо кончиться.
💡 На самом деле всё сказанное в этой статье нужно для тех, кто боится отключения интернета и хочет сохранить у себя на компьютере самую важную информацию. Но эта мысль бредовая сразу на стольких уровнях, что мы стесняемся её произносить вслух. Разве что шёпотом.
В чём идея
Мы будем копировать чужой сайт, чтобы его можно было запустить на своём сервере или на домашнем компьютере. Задача — не просто открыть сайт в браузере и посмотреть его код, а забрать из него все важные файлы — и стили, и скрипты, и изображения. Чтобы было проще, мы будем практиковаться на одностраничном сайте, но всё то же самое будет работать и на многостраничном.
❌ Мы не сможем утащить чужие PHP-скрипты и страницы, связанные с данными пользователя (например, не сможем утащить из интернет-магазина рабочую версию корзины с покупками). Для этого нужен доступ к файлам сервера, а этого у нас нет.
Главный принцип этой работы: когда ваш браузер запрашивает страницу чужого сайта, веб-сервер отправляет ему эту страницу, в буквальном смысле. То же с картинками, стилями и скриптами: каждый раз, когда вы посещаете сайт, вы как будто делаете его копию у себя на компьютере. Браузер получает страницу от сервера и выводит её копию на экран, а в памяти держит исходный код. Разве что он не сохраняет эту страницу на диск, чтобы вы могли её редактировать.
Вот этот последний этап мы и исправим: теперь мы будем сохранять чужие сайты к себе на диск.
Весь процесс покажем на примере сайта ux-posters.ru – простом одностраничном сайте, где есть картинки, стили и скрипты. Автору этого текста пришлось помогать авторам этого сайта с похожей задачей, так что пример свеженький.
Быстрый путь: грабберы
Есть категория программ под названием «веб-грабберы», или «веб-рипперы». Они работают так:
- Ты говоришь программе, на какую страницу сайта зайти.
- Программа собирает все ссылки с этой страницы, переходит по этим ссылкам и строит себе виртуальную карту сайта — то есть пытается понять, сколько на этом сайте страниц и как они связаны.
- Потом граббер начинает ползать по этим страницам подряд, запрашивать их у сервера, получать ответы и сохранять ответы на вашем жёстком диске.
- В какой-то момент граббер останавливается, потому что он скачал все доступные ему страницы с этого сайта.
После работы граббер оставляет у вас на диске гору файлов, которые представляют собой статичный отпечаток чужого сайта. Эту гору можно загрузить на собственный сервер, и издалека это будет похоже на чужой сайт.
✅ Плюсы: граббер может быстро охватить много страниц и скачать из них огромное количество стилей, картинок и всего подряд. Работа очень быстрая и хорошо автоматизирована.
❌ Минусы: часто он качает всё без разбора, оставляя на диске много дублей. Также он бессилен с сайтами, в которых контент выводится динамически или имеет нестандартную систему адресации.
💡 В целом грабберы можно использовать, чтобы скачивать сайты библиотек, архивов и других мест, где документов много и всё устроено логично. Например, с помощью граббера можно скачать какую-нибудь классическую книгу из онлайн-библиотеки.
Вот ссылки на грабберы для разных платформ:
- HTTrack — старый интерфейс из нулевых, но свою задачу выполняет полностью. Бесплатный и надёжный, работает везде.
- Getleft — мультиплатформенный граббер, который пытается выкачивать всё, до чего дотянется, включая PHP-скрипты.
- Cyotek WebCopy — для тех, кто любит только Windows, тоже бесплатный.
Сложный путь: ручное сохранение
Допустим, мы хотим сохранить какую-то отдельную страницу сайта или конкретные её части (например, картинки). Но эти картинки как-то так хитро встроены, что вы не можете просто нажать «Сохранить картинку как…». Тогда потребуется ручной метод.
Заходим на страницу и нажимаем в браузере Ctrl + I (в Виндоус) или ⌥ + ⌘ + I (если у вас мак). Появляется окно «Инспектора», где видна внутренняя структура страницы:
Мы видим, что текущий документ в браузере состоит:
- из страницы index.html;
- скрипта likely.js;
- четырёх таблиц стилей;
- шрифтов, подключённых через сервис Google;
- папки с картинками.
Шрифты нам скачивать необязательно — сайт и так их подключит с сервера гугла, а всё остальное скачать нужно. Чтобы не создавать хаос на компьютере, создадим сначала папку ux-posters — в ней будет храниться наш сайт. Потом в эту папку сохраняем все файлы таким способом:
- Нажимаем правой кнопкой мыши на очередной файл.
- Выбираем пункт Save as, или «Сохранить как».
- Пишем имя и расширение файла — точно так, как указано в списке.
- Если лень писать самому — скопируйте перед этим название файла, нажав правую кнопку мыши и выбрав Copy file name, или «Скопировать имя файла».
- Чаще всего название файла подставится само, но если нет — смотрите пункт 4.
Исключения в названии файлов два:
- (index) — это index.html.
- В любом файле знак вопроса и всё, что после него, писать не нужно.
Скачать можно всё, а можно только то, что вам нужно для работы и экспериментов. Например, если вам нужны только стили и код страницы, сохраняйте файлы .css и (index). Если нужны картинки, заходите в папку pics и сохраняйте всё оттуда.
Щёлкаем на очередном файле и выбираем «Сохранить как»Выбираем нашу папку для сохранения и пишем имя файлаЧто в итоге
Если мы пройдёмся по всем папкам и сохраним в них всё нужное нам, у нас получится локальный слепок сайта. Теперь можно:
- Изучить, как он устроен, что-то отредактировать и увидеть результат у себя на компьютере.
- Открыть файл index.html в браузере, и будет ощущение, что вы зашли на сайт, но с локального компьютера. Сайт откроется по протоколу file:// — это так браузер говорит нам, что файл взялся с нашего компьютера, а не из интернета.
- Запустить MAMP и завести на нём локальную копию сайта для экспериментов. Тогда браузер будет думать, что ходит за этим сайтом в интернет. Можно написать какие-нибудь php-скрипты и оживить сайт.
Что нужно поставить на компьютер, чтобы делать сайты
💡 Важно понимать, что перед нами именно «слепок» — то, что мы бы увидели, если бы сервер сегодня ответил на наш запрос. Если завтра сервер будет отвечать по-другому, мы этого в своей локальной копии не увидим.
Когда ещё это пригодится
Защитить сайт перед наплывом пользователей. С помощью грабберов можно быстро создать неубиваемую статическую копию сайта и временно подменить ей динамическую версию сайта. Это полумера, но может сработать. А вообще вместо этого есть специальные надстройки, которые делают почти то же самое, но более умно, — поищите слово «кеширование».
Делаем неубиваемый сайт: статика и динамика
Сделать копию своего блога, личного сайта или ещё чего-то важного вам, если вы потеряли к нему доступ, но сайт всё ещё на ходу.
Если вы едете туда, где не будет интернета, а вам нужна информация с сайта (например, путеводитель по чужой стране). Помните, что динамические карты и видеоролики так не сохранятся.
Сделать собственный «веб-архив» — это сервис, который ползает по сайтам и делает их «слепки» для истории. Благодаря этому сервису можно посмотреть, как выглядели ваши любимые сайты много лет назад — например, Яндекс.
Текст:
Михаил Полянин
Редактор:
Максим Ильяхов
Художник:
Даня Берковский
Корректор:
Ирина Михеева
Вёрстка:
Кирилл Климентьев
Соцсети:
Олег Вешкурцев
HTML Примеры
HTML Основы
HTML документ
HTML заголовки
HTML абзацы
HTML ссылки
HTML изображения
К теории HTML Основы
HTML Атрибуты
Атрибут title
Атрибут alt
Атрибут href
Атрибут без кавычек
К теории HTML Атрибуты
HTML Форматирование текста
Жирный (<b>) и важный (<strong>) текст
Акцент (<em>) и курсив (<i>)
Большой (<big>) и маленький (<small>) шрифт
Перевод строк (<hr>) и горизонтальная линия (<br>)
Подсветка текста (<mark>)
Выделение текста, который был удален (<del>)
Выделение текста, который был добавлен (<ins>)
Отображение текста в нижнем индексе (<sub>)
Отображение текста в верхнем индексе (<sup>)
К теории HTML Форматирование
HTML Цитаты
Длинные (<q>) и короткие (<blockquote>) цитаты
Аббревиатура (<abbr>)
Контактная информация (<address>)
Источники (<cite>) и определения (<dfn>)
Направление отображаемого текста (<bdo>)
К теории HTML Цитаты
HTML Программный код
Ввод текста с сохранением всех пробелов, табуляций и переносов строк
Ввод с клавиатуры (<kbd>) и компьютерный вывод(<samp>)
Выделение переменных (<var>) в программном коде
К теории HTML Программный код
HTML Комментарии
Комментарии в коде
К теории HTML Комментарии
HTML Стили
Применение стилей к элементу
Внешняя таблица стилей
Внутренняя таблица стилей
Приоритетность стилей
К теории HTML Стили
HTML Ссылки
Создание абсолютной ссылки
Ссылка на адрес электронной почты
Открытие ссылок в новом окне
Открытие ссылок в окне с нужным именем
Всплывающая подсказка для ссылки
Ссылка на закладку из другой веб-страницы
Изображения-ссылки
К теории HTML Ссылки
HTML Изображения
Как указать путь к изображению?
Альтернативный текст к изображению
Атрибуты «width» и «height»
Задание размеров изображения с помощью атрибута style
Задание размеров изображения с помощью max-width
Создание карты изображений
К теории HTML Изображения
HTML Цвета
Задание цвета по его названию
Задание цвета с помощью RGB
Цвет HEX
К теории HTML Цвета
HTML Таблицы
Простая HTML-таблица
Применение свойства border
Одинарная рамка для таблицы
Поля и интервалы таблицы
Ширина таблицы
Объединение столбцов
Объединение строк
Заголовок таблицы
Теги группирования элементов таблиц
К теории HTML Таблицы
HTML Списки
Нумерованный список
Применение атрибутов type и start
Применение атрибута value
Форматирование нумерованных списков с помощью CSS
Маркированный список
Вложенные списки
Форматирование маркированных списков
Графические маркеры
Списки определений (описаний)
К теории HTML Списки
Блочные и встроенные элементы
Блочные и встроенные элементы
Общие элементы <div> и <span>
К теории HTML Блочные и встроенные элементы
Идентификаторы и классы
Применение идентификатора
Применение атрибутов id и class
К теории HTML Идентификаторы и классы
HTML Фреймы
Структура HTML-документа с фреймами
Убираем границу между фреймами
Управление границей фреймов
Ссылки внутри фреймов
Плавающий фрейм
Удаление границы плавающего фрейма
Изменение размер, стиля и цвета границы встроенного фрейма
Открытие ссылки в окне встроенного фрейма
К теории HTML Фреймы
Макеты веб-страниц
Макет на основе таблицы
Макет на основе DIV-элементов
Макет на основе элементов HTML5
К теории HTML Макеты
HTML Раздел Head
Элемент <title> создает название документа
Элемент <link> служит для подключения внешнего файла CSS
Элемент <style> содержит правила CSS
Элемент <script> присоединяет к документу сценарии
Элемент <base> служит для указания полного базового URL-адреса документа
К теории HTML Раздел Head
HTML JavaScript
Встроенный скрипт
Запуск скрипта
Подключение внешнего скрипта
Использование тега <noscript>
JavaScript может менять HTML контент
JavaScript может менять значение HTML атрибута
JavaScript может менять стили
JavaScript может менять шрифты
К теории HTML скрипт
HTML Специальные символы
Использование кавычек
Дефис и тире
Спецситмвол €
К теории HTML Специальные символы
HTML Формы
Простая HTML-форма
Поле ввода пароля
Использование радио-переключателей
Флажки (checkbox)
Кнопки подтверждения (submit) и очистки (reset)
Группировка элементов формы
К теории HTML Формы
HTML Элементы формы
Текстовая область <textarea>
Раскрывающийся список (select)
Прокручиваемый список
Группировка пунктов списка (optgroup)
Использование кнопки <button>
Использование элемента <datalist>
Метки элементов формы (label)
К теории HTML Элементы формы
Значения атрибута type элемента <input>
Значение атрибута type: text
Значение атрибута type: password
Значение атрибута type: radio
Значение атрибута type: checkbox
Значение атрибута type: submit
Значение атрибута type: button
Значение атрибута type: date
Значение атрибута type: week
Значение атрибута type: month
Значение атрибута type: time
Значение атрибута type: datetime
Значение атрибута type: datetime-local
Значение атрибута type: number
Значение атрибута type: range
Значение атрибута type: color
Значение атрибута type: email
Значение атрибута type: url
Значение атрибута type: search
Значение атрибута type: tel
К теории HTML Aтрибут type элемента <input>
HTML Атрибуты элемента <input>
Атрибут value
Атрибут disabled
Атрибут readonly
Атрибут size
Атрибут maxlength
Атрибут placeholder
Атрибут autofocus
Атрибуты min и mах
Атрибут step
Атрибут autocomplete
Атрибут required
Атрибут novalidate
Атрибут pattern
Атрибут formnovalidate
Атрибут form
Атрибут formaction
Атрибут formenctype
Атрибут formmethod
Атрибут formtarget
Атрибут multiple
Атрибут multiple
К теории HTML Атрибуты элемента <input>
Давайте писать HTML-код, как профессионалы
Хочешь знать больше про веб?
Подпишись на наш телеграм-канал TechRocks WEB-разработка?
Подписаться
×
Перевод статьи «Let’s write HTML like a pro».
Photo by Goran Ivos on UnsplashHTML напоминает ребенка, с которым никто не играет, потому что JavaScript и CSS отвлекают внимание на себя. Сегодня мы рассмотрим несколько вещей, способных помочь вернуть этого «ребенка» в центр внимания.
Все, описанное здесь, – часть создания чистого, поддерживаемого и масштабируемого кода, в котором должным образом используются семантические элементы разметки из HTML5 и который правильно отображается в поддерживаемых браузерах.
DOCTYPE
Начнем с самого верха вашего index.html. Обязательно декларируйте DOCTYPE. Это активирует стандартный режим во всех браузерах и уведомляет их о том, как следует интерпретировать этот документ. Имейте в виду, что DOCTYPE не является элементом HTML.
В HTML5 это выглядит следующим образом:
<!DOCTYPE html>
Примечание: если вы используете фреймворк, эта часть будет заполнена без вашего участия. В противном случае я настоятельно рекомендую использовать сниппеты вроде Emmet, доступные в VS Code.
Хотите узнать побольше о других типах документов? Можете почитать об этом здесь.
Опциональные теги
Некоторые теги в HTML5 опциональны, главным образом потому, что элемент присутствует неявным образом. Это может показаться странным, но вы вполне можете пропустить тег <html>, и страница все равно прекрасно отобразится.
<!DOCTYPE HTML> <head> <title>Hello</title> </head> <body> <p>Welcome to this example.</p> </body> </html>
Приведенный пример HTML-кода валиден, но есть некоторые случаи, когда так сделать не получится, например, когда после тегов идут комментарии:
<!DOCTYPE HTML> <!-- where is this comment in the DOM? --> <head> <title>Hello</title> </head> <body> <p>Welcome to this example.</p> </body> </html>
Этот код невалиден, потому что комментарий оказывается вне тега <html>.
Закрывающие теги
Теги всегда следует закрывать, поскольку в некоторых браузерах могут возникнуть проблемы с отображением вашей страницы. Закрытие тегов улучшает читаемость кода, а также имеет большое значение по другим причинам, о которых мы поговорим немного позже.
<div> <img src="example.jpg" alt="example" /> <a href="#" title="test">example</a> <p>example</p> </div>
Все приведенные в этом примере теги валидны. Но есть и исключения из правила, предписывающего закрывать теги.
В следующих элементах самозакрывающиеся теги валидны, но не обязательны:
<br>, <hr>, <img>, <input>, <link>, <meta>, <area>, <base>, <col>, <command>, <embed>, <keygen>, <param>, <source>, <track>, <wbr>
Примечание: обычные теги не могут быть самозакрывающимися.
<title />
Это неправильное написание.
Charset
Заранее определяйте кодировку своего документа. Хороший тон — поместить эту информацию в самом верху, внутри элемента <head>.
<head> <title>This is a super duper cool title, right 😥?</title> <meta charset="utf-8"> </head>
Приведенный выше пример кода невалиден, название отобразится неверным образом. Декларировать кодировку нужно выше.
<head> <meta charset="utf-8"> <title>This is a super duper cool title, right 😃?</title> </head>
Язык
Еще одна причина не пропускать опциональные теги — использование атрибутов. Не отказываясь от тега <html>, вы можете (и это рекомендуется) определить язык вашей веб-страницы. Это очень важно с точки зрения доступности и поиска.
<html lang="fr-CA"> ... </html>
Тег title
Никогда не пропускайте тег <title>. Это очень ухудшает доступность. Кроме того, я бы не пользовался сайтом, где не используется этот тег. Если открыть страницу такого сайта, то 2 минуты и 20 вкладок спустя вы ее уже не найдете (вкладке будет нечего вам показать).
Тег base
Очень полезный тег, но пользоваться им нужно с известной осторожностью. Он устанавливает базовый URL для приложения. После его установки все ссылки будут формироваться относительно него, а это может привести к нежелательному поведению:
<base href="http://www.example.com/" />
Если в вашем приложении установлен базовый URL, как в примере выше, то href=»#internal» будет интерпретироваться как href=»http://www.example.com/#internal«.
Но при этом href=»example.org» будет интерпретироваться как href=»http://www.example.com/example.org«.
Description
Этот мета тег очень полезен, хотя и не является неотъемлемой частью лучших подходов. Он имеет огромное значение для поисковиков, когда они исследуют ваш сайт.
<meta name="description" content="HTML best practices">
Семантические теги
Хотя вы можете обойтись одними div-ами, это еще не значит, что так нужно делать. Семантический HTML наполняет вашу страницу смыслом. Такие теги как p, section, h{1-6}, main, nav являются семантическими. Если вы используете тег <p>, пользователи будут знать, что это абзац текста, а браузеры будут понимать, как его следует отображать.
Разбирать все семантические элементы разметки мы здесь не будем, но почитать о них вы можете здесь.
Не используйте hr для форматирования
<hr> это не элемент форматирования, так что прекращайте использовать его с этой целью. В HTML5 этот тег представляет тематический разрыв вашего контента. Правильное использование <hr> может выглядеть следующим образом:
<p>Абзац о щенках.</p> <p>Абзац о любимой еде щенков.</p> <p>Абзац о породах щенков.</p> <hr> <p>Абзац о том, почему я брею голову.</p>
Будьте осторожны, используя атрибут title
Атрибут title это мощный инструмент. С его помощью создается всплывающая подсказка, способная пояснить действие или назначение элемента на странице. При этом не следует забывать, что этот атрибут и, например, атрибут alt для изображений не являются взаимозаменяемыми.
Из спецификации HTML5 следует, что в настоящее время использование атрибута title не поощряется. Для появления всплывающей подсказки нужно навести на элемент указатель мыши, а это недоступное действие для тех, кто пользуется только клавиатурой или современными телефонами и планшетами.
О правильном использовании этого атрибута можно почитать здесь.
Одинарные и парные кавычки
Во многих кодовых базах в разметке используются оба вида кавычек одновременно. Это не хорошо, особенно если в вашем фреймворке используются одинарные кавычки или если вы работаете без фреймворка, но используете кавычки в тексте. И, кроме того, нужно просто быть последовательным в написании кода. Не делайте так:
<img alt="super funny meme" src='/img/meme.jpg'>
Делайте так:
<img alt="super funny meme" src="/img/meme.jpg">
Опускайте булевы значения
Что касается булевых значений для атрибутов, рекомендуется их опускать, поскольку они не несут смысловой нагрузки и при этом увеличивают вес разметки.
<audio autoplay="autoplay" src="podcast.mp3"> <!-- лучше так --> <audio autoplay src="podcast.mp3">
Опускайте атрибут type
Не нужно добавлять атрибут type в теги script и style. В некоторых сервисах, например, в W3C Validator, вы получите ошибку валидации при проверке вашего кода.
Проверяйте вашу разметку
Используйте для проверки разметки специальные сервисы, к примеру, тот же валидатор от W3C. Это позволит вам быть уверенным, что ваша разметка валидна.
Скажите «нет» встроенным стилям
В HTML-файле пишется контент. То, как он выглядит, это уже представление. Оставьте представление CSS и не используйте встроенные стили. Это поможет как разработчикам, которые будут работать с кодом в дальнейшем, так и браузерам.
Заключение
Конечно, это лишь верхушка айсберга — просто несколько вещей, которые следует иметь в виду при написании разметки. Чтобы познакомиться с этой темой подробнее, можно обратиться к следующим источникам (среди прочих):
- HTML best practices on GitHub
- W3C school HTML style guide
Примеры HTML
❮ Предыдущий Далее ❯
HTML Basic
HTML-документ HTML-заголовки HTML-абзацы HTML-ссылки HTML-изображения HTML-кнопки Списки HTML
Объяснение примеров
Атрибуты HTML
Атрибут title Атрибут href Атрибуты ширины и высоты Атрибут alt Атрибут без кавычек Атрибут без кавычек не работает
Объяснение примеров
Заголовки HTML
Заголовки HTML Горизонтальные правила HTML HTML-заголовок
Объяснение примеров
Абзацы HTML
Абзацы HTML Дополнительные абзацы HTML Использование разрывов строк в HTML Проблемы со стихотворением (некоторые проблемы с форматированием HTML) Как управлять разрывами строк и пробелами с помощью тега
Объяснение примеров
Стили HTML
Стили HTML Цвет фона HTML Цвет HTML-текста HTML-текстовый шрифт Размер HTML-текста Выравнивание текста HTML
Объяснение примеров
Форматирование текста HTML
Выделение жирным шрифтом с использованием элемента Сильное форматирование с использованием элемента Курсивное форматирование с использованием элемента Подчеркнутое форматирование с использованием элемента Небольшое форматирование с использованием элемента Отмеченное форматирование с использованием элемента Отмечено как удаленное с помощью элемента
Помечен как вставленный с помощью элемента Отмечено как удаленное и вставленное с помощьюи Форматирование нижнего индекса с использованием элемента Форматирование верхнего индекса с использованием элементаОбъяснение примеров
HTML цитаты и цитаты
Форматирование коротких цитат с помощью элемента
. Форматирование цитируемых разделов с помощью элемента. Форматирование информации об авторе/владельце документа с помощью элемента Форматирование сокращений и акронимов элементом Форматирование названия работы с помощью элемента Форматирование направления текста с помощью элементаОбъяснение примеров
Комментарии HTML
Скрытые комментарии Условные комментарии Комментарии для отладки
Объяснение примеров
HTML CSS
HTML со встроенным CSS HTML с внутренним CSS HTML с внешним CSS HTML со шрифтами CSS HTML с CSS с использованием атрибута id HTML с CSS с использованием атрибута class HTML и CSS границы HTML и CSS заполнение HTML и CSS поля Полная демонстрация HTML и CSS
Объяснение примеров
HTML-ссылки
Связывание с использованием абсолютного URL-адреса Связывание с использованием относительного URL Изменение цвета ссылок Удаление подчеркивания со ссылок Изменение цели ссылки Изображение как ссылка Создание ссылки на закладку Ссылка, которая вырывается из фрейма Ссылка на почту Почтовая ссылка с темой
Объяснение примеров
HTML-изображения
Изображение Высота и ширина изображения с использованием атрибутов Высота и ширина изображения с использованием CSS Высота и ширина изображения с использованием обоих Изображение в другой папке Изображение с битой ссылкой Изображение на другом сервере Использование изображения в качестве ссылки Движущееся изображение Карта изображений с интерактивными областями Плавающее изображение
Объяснение примеров
Таблицы HTML
Базовые таблицы HTML Стол с границами Таблица со свернутыми границами Таблица с заполнением ячеек Таблица с заголовками Таблица с заголовками, выровненными по левому краю Горизонтальные/вертикальные заголовки таблиц Таблица с заголовком Ячейки таблицы, охватывающие более одного столбца Ячейки таблицы, охватывающие более одной строки Таблица с интервалом между ячейками Таблица с HTML-тегами внутри Таблицы с другим стилем с использованием идентификатора I Таблицы с другим стилем с использованием id II Столы с другим стилем с использованием класса I Столы в другом стиле с использованием класса II
Объяснение примеров
Списки HTML
Ненумерованный список (по умолчанию) Неупорядоченный список с дисковыми маркерами Ненумерованный список с круглыми маркерами Ненумерованный список с квадратными маркерами Ненумерованный список без маркеров Упорядоченный список (по умолчанию) Упорядоченный список с номерами Упорядоченный список с буквами Упорядоченный список со строчными буквами Упорядоченный список с римскими цифрами Упорядоченный список со строчными римскими цифрами Список описаний Вложенный список I Вложенный список II Горизонтальный список Меню горизонтального списка
Объяснение примеров
Блочные и встроенные элементы HTML
Элемент
Элемент Стилизация элементаСтилизация элементаОбъяснение примеров
Классы HTML
Придание стиля всем элементам с указанным именем класса Доступ к элементам с указанным именем класса с помощью JavaScript Несколько классов Тот же класс, другой тег
Объяснение примеров
Идентификатор HTML
Стиль элемента с определенным идентификатором Разница между классом и идентификатором Доступ к элементу с определенным идентификатором с помощью JavaScript
Объяснение примеров
Макет HTML
Макет с использованием float Вёрстка с использованием flexbox Макет с использованием flexbox 2 Макет с использованием flexbox 3
Объяснение примеров
HTML IFrame
Встроенный фрейм (фрейм внутри HTML-страницы)
Объяснение примеров
HTML-элементы заголовка
Действительный HTML-документ без <голова> Действительный HTML-документ без элемента
Элементопределяет заголовок документа. Элемент