[Перевод] Создаем веб-сайт, будто на дворе 1999 год
Задумывались ли вы когда-нибудь о том, как жилось веб-разработчикам 20+ лет назад, когда всемирная паутина была явлением совершенно новым, а чтобы войти в неё, приходилось некоторое время слушать специфические звуковые сигналы, JavaScript и CSS воспринимались скорее как диковинка, а не как привычные средства разработки веб-сайтов, а самым популярным браузером был Internet Explorer? Что ж, вероятнее всего, нет… Но, если у вас найдется несколько свободных минут и вы захотите разобраться в очередной бесполезной штуке — эта статья вас не разочарует!
Немного предыстории
В начале 2022 года я поддался приступу ностальгии и решил поиграть в одну из любимых игр детства (The Prince and The Coward — польская point and click игра, а, я как раз родом из Польши). У меня был диск с оригинальной игрой, но не было машины, на которой можно было бы её запустить. Мне показалось, что интереснее было бы поиграть на настоящем олдскульном Windows PC, поэтому я отправился шерстить аукционы и барахолки, чтобы купить подходящее железо (а заодно и программное обеспечение в виде Windows 98) и собрать себе старый-новый компьютер… Впрочем, как я его собирал и с какими проблемами столкнулся — это уже другая история.
Пройдя игру, я растерял весь свой ностальгический настрой. Передо мной вместо интересного старого ПК вновь оказался тяжеленный, никчемный пылесборник. Но в голову мне пришла отличная идея — попытаться разработать на этом ПК что-то типа веб-сайта. К сожалению, из-за работы я долго откладывал эту затею. И откладывал бы еще дальше, если бы не решил наконец написать эту самую статью!
1999
Мне 10 лет, и у меня за плечами уже как минимум 3 года общения с операционными системами Microsoft Windows. Мой путь в веб-разработку начался в начале 2000-х, и для своих первых «проектов» я использовал Macromedia Dreamweaver, табличную верстку и сниппеты JS, скопированные из Интернета — чтобы получить какой-нибудь модный эффект вроде анимации падающего снега. И никакого CSS!
В 1999 году интернет сам по себе был для меня загадкой. Возможно, я слышал о нём и знал, что это такое, но впервые я столкнулся с ним уже в XXI веке.
Что же происходило тогда в мире? Европейский союз ввел новую валюту — евро. Билл Клинтон до сих пор был президентом США. Всемирная метеорологическая организация объявила, что 90-е годы были самым жарким (если говорить о средней температуре) десятилетием за всю историю наблюдений. На канале Nickelodeon дебютировал Губка Боб Квадратные Штаны. Эминем выпустил альбом The Slim Shady LP. Состоялись мировые премьеры таких фильмов, как «Матрица» и «Звёздные войны: Эпизод 1 — Скрытая угроза» (тогда мне очень понравился этот фильм, а недавно я пересмотрел его и, черт возьми, он до сих пор хорош!).
Все только и говорили о «баге миллениума», ведь 2000 год должен был повлечь за собой глобальный компьютерный апокалипсис из-за проблем с форматированием даты. Так что, если вы не успели сделать свой персональный сайт раньше, 1999 — это ваш последний шанс.
Проект
Что же мы будем делать? Простой персональный сайт с тремя вкладками — home (поздороваемся с посетителями), about (краткая биография) и contact (немного контактной информации). Макет не должен быть чересчур сложным — хедер (с заголовком и навигацией по вкладкам) вверху, футер внизу и область содержимого вкладок между ними.
Хотелось бы использовать как можно больше CSS, а переключение между вкладками реализовать при помощи JavaScript. Никаких подстраниц не будет — только один индексный HTML-файл, один JS-файл, один CSS-файл и несколько (две штуки) изображений. Вот структура моего проекта:
project-root/
├── assets/
│ ├── scripts.js
│ ├── styles.css
| ├── bg.gif (used as background of the page)
| └── mk.jpg (my face for about section)
|
└── index.html
Страница должна нормально работать и красиво выглядеть во всех (в смысле, в обоих) основных браузерах, доступных на тот момент, — MS Internet Explorer 5 и Netscape Navigator 4.51.
Инструментарий
Я мог бы пойти классическим путем и взять MS Notepad для написания кода для своего сайта. Но давай поступим чуть более профессионально и обзаведёмся настоящим кодовым редактором. Сначала я подумал о Notepad++, но раз уж он вышел в 2003 году, то в моем воображаемом 1999-ом его не существует. На ум мне пришел польский редактор под названием Pajączek (Spidey), существовавший с 1996 года, но, по-моему, он выпускался только на польском языке и был не бесплатным. Спустя несколько минут поиска в Google и Wikipedia я нашёл редактор Arachnophilia — выпущен в 1996 году, бесплатный, на английском языке, а в названии есть намек на пауков. Сгодится.
Pajączek 2000 v4.8.1 by Cream Software
Моя Windows 98 шла с предустановленным Internet Explorer (v5.0), но мне нужно было раздобыть где-то другие приложения — Netscape Navigator и Arachnophilia. Естественно, оба должны были иметь версию, представленную 23 года назад. Искать старое программное обеспечение нелегко, но я сразу же отправился на сайт oldversion.com. К сожалению, на тот момент сайт перестал работать, я даже подумал, что он исчез навсегда. Однако сейчас, когда я пишу эти строки, он, похоже, снова онлайн.
Как бы то ни было, мне пришлось искать ПО в другом месте. Это отняло у меня немало времени, потому что по фразе типа «netscape 4.5 download», набранной в google, ничего хорошего в наши дни не найдешь. Пришлось как следует поковыряться. В конце концов, на archive.org нашлась страница, давшая то, что мне было нужно, — образ диска apcmag.cd от мая 1999 года, который включал в себя оба приложения: Netscape Navigator v4.51 и Arachnophilia v3.9.
Мой изначальный амбициозный план предполагал использование локального сервера и запуск сайта на localhost (я даже нашел старую статью об установке Apache и PHP на Windows 98). Однако для проекта такого масштаба это казалось слегка чересчур, так что в итоге я отказался от этой идеи. Возможно, когда-нибудь я примусь за более продвинутые ретро-веб-штуки, требующие наличия бэкэнд-логики, но пока что давайте сосредоточимся только на фронтенде.
Arachnophilia
Коротко обсудим выбранный мною редактор кода. Может быть, тогда он и казался кому-то неплохим, но теперь он выглядит весьма убого. Но тем не менее он превосходит по возможностям обычный MS Notepad — в нём есть базовая подсветка синтаксиса HTML и функция предварительного просмотра (нажимаешь на кнопку, и Arachnophilia сохраняет текущий HTML-код во временный файл и открывает его в IE для предварительного просмотра; в инструкции сказано, что после каждого сохранения страница перезагружается, но, к сожалению, у меня эта функция не сработала).
Программа не поддерживает JS- и CSS-файлы, но их можно создать в виде txt-файлов с расширением .js или .css. А затем просто писать туда код.
При создании нового HTML-файла появляется окно подсказки, в котором можно установить заголовок страницы, цвета текста и ссылок. На основе этих данных Arachnophilia сгенерирует исходный HTML-код, при этом заголовок попадет в head, а стили текста и ссылок добавятся в качестве атрибутов к тегу body (но мне такой подход очень не нравится).
В исходном HTML-коде имена тегов написаны заглавными буквами, и мне это нравится, так как создается ощущение настоящей олдскульности, так что я постараюсь следовать этому стилю.
В первую очередь логика
Прежде чем приступить к реализации целой страницы, я хочу выяснить, на что способен JavaScript. Я поставил перед собой цель создать вкладки, управляемые JS, — при нажатии на навигационную ссылку должна отображаться связанная с ней вкладка, а остальные — скрываться.
Сначала я остановился на Internet Explorer. В нём нет ни инструментов разработчика, ни консоли JS — если что-то выдает ошибку, IE показывает значок предупреждения в нижней панели, дабл-кликом по нему мы получаем более подробную информацию — сообщение об ошибке и место, где она произошла.
Не то, к чему я привык, но все же вполне пригодно. Когда у меня возникала какая-то проблема, я обычно находил решение в гугле (результаты поиска вели меня к старым темам на заброшенных форумах) или использовал сайт caniuse.com, чтобы выяснить, какие методы мне доступны (там приведены данные о IE v6 и выше, но по моему опыту, если что-то было отмечено «зеленым» для 6–8, то оно работало и на IE v5).
Вот несколько особенностей, о которых я узнал во время PoC-разработки JavaScript для Internet Explorer 5:
getElementsByClassName
не поддерживается, ноgetElementsByNameworks
при этом отлично работает (поэтому я использовал его для выбора всех навигационных ссылок)……но не с DIV’ами (поэтому я не мог использовать его для выбора содержимого вкладок),
addEventListener
не существует, но в IE есть собственный метод для этого —attachEvent
— он принимает как минимум два аргумента — eventName (но с on в начале, как пример: onclick вместо click) и callback (который не получает объект события в качестве аргумента),anchorElement.getAttribute('href')
возвращает весь URL, а не только значение, добавленное в атрибут href (поэтому если атрибуту присвоено значение #foobar, то локально получится что-то вроде C:\…#foobar).
Это мой HTML для проверки правильности реализации вкладок:
Link 1
Link 2
Link 3
Content 1
Я сохранил атрибуты href, чтобы сделать код более семантичным, но мне понадобился пользовательский атрибут tab
, чтобы проще получать идентификатор вкладки с помощью JS.
А вот мой JavaScript-код для управления переключением между вкладками:
var tabLinks = document.getElementsByName('link');
var currentOpenTabElement = document.getElementById('tab0');
for (var i = 0; i < tabLinks.length; i++) {
tabLinks[i].attachEvent('onclick', createOnClickHandler(i))
}
function createOnClickHandler(tabLinkIndex) {
var tabLink = tabLinks[tabLinkIndex];
var tabId = tabLink.getAttribute('tab');
return function() {
openTab(tabId);
}
}
function openTab(tabId) {
var tab = document.getElementById(tabId);
currentOpenTabElement.style.display = 'none';
tab.style.display = ''
currentOpenTabElement = tab;
}
И должен признать — я удивлен. Код выглядит довольно неплохо и делает то, что я хотел (переключается между вкладками). Это 1999 год, это Internet Explorer, и все работает. Я действительно удивлён.
Netscape Navigator — первый удар
Если мой код работает в Internet Explorer, то что может пойти не так в браузере Netscape? — спросил я себя. В 90-е годы это вообще был самый популярный браузер, и несмотря на то, что в итоге он проиграл IE, я был уверен, что мне не о чем беспокоиться. Поэтому я открыл свою страницу в Netscape Navigator и…
…управление вкладками не работает.
Сначала я подумал, что attachEvent
— это фишка IE, поэтому в Netscape он работать не будет. Но как убедиться в этом? Где Netscape выводит сообщения об JS-ошибках? Есть ли какая-нибудь JS-консоль? Нет. Есть ли какая-то информация в нижней панели, как в IE? Нет. Есть ли хоть какой-то признак того, что при выполнении JS-кода что-то пошло не так? Ну… код не работает, и это своего рода обратная связь, но это все, что мне доступно.
Так как же отладить JavaScript в Netscape Navigator 4.51? Что ж, придется самостоятельно реализовать обработку ошибок — добавить обработчик window.onerror
, который будет вызывать метод alert
с сообщением об ошибке (это не я придумал, нашёл вот здесь).
Окей, getElementsByName
тогда еще не существовало в мире Netscape. А как насчет getElementsByClassName
? Нет. Может быть, хотя бы getElementById
? Нет. Неужели в Netscape Navigator вообще ничего нет?
На сайте caniuse.com нет никакой информации о поддержке тех или иных фич, поэтому приходится ограничиваться теми крупицами, что еще остались в Интернете. И, по счастью, нашелся один полезный материал, Client-Side JavaScript reference (версия 1.3) компании Netscape Communications Corporation, изданный в 1999 году. Это дало мне некоторое представление о том, что умеет браузер и, о боже, версия JavaScript от Netscape оказалась будто с другой планеты. Здесь есть такие коллекции, как document.ids или document.classes, но сделать с ними можно не так уж много — как правило, только задать некоторые базовые стили, но только один раз, когда браузер загружает страницу.
Моя идея заключалась в том, чтобы использовать атрибут onClick
(так как это кроссбраузерное решение) для прикрепления обработчиков кликов, отвечающих за установку свойства display style для элементов вкладки. Но ничего не выходило! Пришлось снова обратиться к дядюшке Google и попытать счастья. Я нашел несколько старых статей, но большинство из них оказались бесполезны. Наконец, мне попалась вот эта статья, и именно она спасла ситуацию. Оказывается, в Netscape есть собственный HTML-тег layer
, который предназначен для позиционирования на странице и анимации элементов с помощью скриптов.
Единственная проблема с тегом
состоит в том, что он ведет себя как элемент с абсолютным позиционированием (относительно родительского слоя или окна). К счастью, существует также инлайн-тег
. Это уже более практичный вариант, но все равно остается одна небольшая проблема — атрибут visibility
для layer работает как свойство CSS visibility
, то есть скрыть элемент можно, но он все равно будет занимать место на экране. В результате первая вкладка будет отображаться там, где нужно, а остальные — гораздо ниже, и на практике это будет выглядеть скверно. Чтобы это исправить, нужно задать свойству top отрицательное значение. Ф-фух…
Итак, как же выглядит кроссбраузерная версия моего сайта? Во-первых, в документа пришлось добавить небольшой скрипт, чтобы определить, является ли браузер Netscape:
Почему я не использовал свойство navigator
для проверки браузера? Скажем так, это не совсем надежный метод. Проверка наличия в документе элементов типа layer, являющихся Netscape-специфичными, гарантирует верное срабатывание.
Как бы то ни было — информацию о браузере я буду использовать и в файле scripts.js, и непосредственно в HTML. Кстати, о HTML, вот он:
Link 1
Link 2
Link 3
Content 1
Content 2
Content 3
Как видите, я использовал инлайн-скрипт, чтобы добавить вкладкам, которые должны быть изначально скрыты, если браузер не Netscape, стиль display: none
. Поступил я так потому, что возможность изменять свойство display
с помощью JS в Netscape Navigator работает не так, как хотелось бы.
Свойства
, такие как visibility
и top
, будут понятны только Netscape. Другие браузеры будут их игнорировать (ну, IE 5 их игнорирует, так что я надеюсь, что и другие будущие браузеры будут делать то же самое).
Ссылки для навигации по вкладкам имеют атрибуты onClick
с назначенными обработчиками кликов, которые определены в моем файле scripts.js
:
var activeTab = 'tab0';
if (probablyNetscape) {
window.onerror = function(message, file, line) {
alert('JavaScript error!\nFile: ' + file + '\nLine: ' + line + '\nMessage: ' + message);
}
// Set position for layers in Netscape Navigator
document.layers.tab1.top = -38;
document.layers.tab2.top = -76;
}
function tabLinkClickHandler(tab) {
if (tab === activeTab) return;
if (probablyNetscape) {
document.layers[activeTab].visibility = 'hide'
document.layers[tab].visibility = 'show'
} else {
document.getElementById(activeTab).style.display = 'none';
document.getElementById(tab).style.display = 'block';
}
activeTab = tab;
}
Я знаю — если кто-то нажмет на ссылку до загрузки файла скрипта, это вызовет ошибку, поэтому на этом этапе можно было бы поместить весь код скрипта в index.html, но… Я решил пока что оставить всё как есть.
Теперь у меня есть рабочий кроссбраузерный proof of concept. Этот опыт оказался — благодаря Netscape Navigator — слегка разочаровывающим. Но теперь пришло время расслабиться — займемся версткой и css!
Вы только посмотрите…
Я усвоил урок — не имеет смысла разрабатывать сайт специально для IE5, а потом пытаться адаптировать его для Netscape Navigator, так как в итоге получится совершенно другой код. С самого начала нужно искать решения, которые будут работать в обоих браузерах.
Пришло время рассказать вам шокирующую историю о безумствах, связанных со стилизацией HTML-страниц в 1999 году.
Центрирование элементов с margin left и right, установленным на auto, не работает. Есть два возможных решения — тег CSS flexbox существовал далеко не всегда. Если вы занимаетесь веб-разработкой более ~10 лет, то, скорее всего, помните, что для создания грид-макета многие разработчики применяли свойство Так вот, я использовал float для выравнивания элементов управления вкладками (ссылок). Я хотел было применить тут теги списков — Цвет фона DIV, заданный с помощью CSS, — это слишком круто для Netscape Navigator v4.51. Если свойство CSS IE vs Netscape Navigator IE vs Netscape Navigator Настройка Когда я работал над навигацией, мне захотелось изменить стили ссылок при открытии связанной с ними вкладки. Из-за ограничений Netscape мне пришлось поиграть с тегом (i)layer, и я докатился до того, что мой HTML стал вызывать критическую ошибку Netscape. Следующая проблема — отступы (margins). Уточню: margins в Netscape Navigator v4.51. Можно везде задать На этом этапе я понял, что никогда не сделаю Netscape-версию своего сайта такой хорошей, как мне хочется. К тому же придется использовать для нее специальные стили. Как их дифференцировать? Первой моей мыслью было добавить дополнительный класс к body с помощью JavaScript (если страница открыта не в Netscape), но оказалось, что Netscape Navigator 4 настолько сломан, что просто игнорирует половину стилей. Мне так и не удалось убрать пробелы между ссылками вкладок, что видно на картинке выше. Конечно, Internet Explorer 5 тоже не идеален, у него есть некоторые странности, но Netscape Navigator 4 — это просто чистое безумие. Кстати, об IE — я хотел реализовать простую анимацию фразы (Welcome to 1999!) под заголовком страницы, которая бы непрерывно скользила слева направо. Для этого я использовал Если сначала определить функцию, а затем передать ее в Я готов поспорить, что у IE есть какая-то проблема с управлением памятью в случае использования анонимных функций. У Netscape Navigator с этим проблем нет. Хорошая работа Netscape, 10 баллов Гриффиндору. Если бы я захотел рассказать обо всех проблемах, с которыми я столкнулся при работе над проектом, то пришлось бы писать целую книгу. В любом случае, спустя несколько часов работы моя страница была готова и функционировала как в Internet Explorer 5, так и в Netscape Navigator 4.51. Общий размер всех файлов, необходимых для работы страницы, составляет ~42 КБ (html, css, js и два изображения — все без сжатия). Я не смог найти достоверной информации о средней скорости интернет-соединения в 1999 году, поэтому рассчитаем время загрузки для телефонного модема, который в конце 90-х мог развивать скорость 56 кбит/с — с таким устройством (работающим на полной скорости) на получение всех данных уйдет 6 секунд. В 1999 году это было, наверное, приемлемо. Я не буду вставлять сюда весь код (это долго и скучно), ссылка на репозиторий Github будет приведена ниже. А теперь взглянем на несколько скриншотов моей страницы, которые я сделал на Windows 98. Start About Contact Должен сказать, что я очень горжусь тем, как всё получилось для Internet Explorer. Страница выглядит и работает так, как я хотел. Start About Contact Как видно, версия для Netscape Navigator имеет ряд недостатков… Секция с контентом и вкладки кажутся сломанными, и, несмотря на то, что я потратил кучу времени, пытаясь сделать их вид как можно более близким к тому, что получилось в IE, мне это в итоге не удалось… Возможно, если бы я построил все на Вернемся в 2023 год и откроем мою страницу в каком-нибудь современном браузере, например в Google Chrome. Она выглядит… скромно, но в остальном все смотрится и работает хорошо. Есть одна небольшая проблема с размером блока контента (он слишком широкий, это легко определить, если посмотреть на правый-нижний угол серого блока). Обёртка страницы имеет ширину 480 px, а блок контента внутри обёртки страницы также имеет ширину 480 px, но при этом имеет 10 px padding с каждой стороны. В далеком 1999 году это работало нормально (хотя я подозреваю, что это баг как в IE, так и в Netscape). Теперь же блок контента имеет общую ширину 500 px (сумма ширины и padding с обеих сторон), что является более ожидаемым поведением. Это можно исправить с помощью следующих трех строк CSS-кода: Ретро-браузеры его не поймут, поэтому там ничего не должно сломаться. Больше никаких изменений не требуется (ну, разве что нужно добавить короткую информацию о политике конфиденциальности, так как в ЕС действует закон GDPR). Если вам захочется самостоятельно протестировать эту страницу, она опубликована по адресу 1999.mihau.co, а код можно найти в репозитории Github. Этот маленький незамысловатый сайт занял у меня гораздо больше времени, чем я предполагал вначале, и вовсе не потому, что я плохо оцениваю задачи. Возможности Internet Explorer 5, по сравнению с современными браузерами, конечно, гораздо, гораздо более скромны, но в процессе работы я ощущал контакт со знакомым мне виром веб-разработки. Netscape Navigator 4.51 оказался совершенно другой вселенной. В нём мои возможности по работе с DOM и обработке событий были очень ограничены, а CSS казался полностью сломанным (все описанные баги можно найти здесь). Но… Во-первых, это был 1999 год. Я считаю, что даже в начале 2000-х табличные макеты и атрибуты для стилизации все еще были более популярны, чем CSS. Да и сам контент был важнее внешнего вида. JavaScript? Он был относительно молод и ему не хватало стандартизации. Netscape внедрил его, Microsoft реализовала собственную версию, с другим API и большими возможностями. К тому же Flash тогда был более популярен. Во-вторых — 4.51 не являлся полноценным релизом, в отличие от Internet Explorer 5. Я твердо уверен, что Netscape многое улучшили и исправили в Navigator v5 (выпущенном в 2000 году). Впрочем, сам я это не проверял. В любом случае, несмотря на все разочарование, вызванное сломанным браузером Netscape, это все равно было приятное путешествие во времени. Теперь я могу вернуться в будущее и жить долго и счастливо со всеми этими JS-фреймворками и браузерами, которые обновляются чаще, чем я выношу мусор. Спасибо, что уделили мне время. На этом всё.
или align="center"
. Этим элементом следует обернуть контейнер с содержимым страницы (с шириной, установленной на 480 px). В обоих случаях IE центрирует и содержимое потомков, поэтому для контейнера страницы стоит установить атрибут align="left"
, и это исправит проблему. Однако Netscape сдвигает весь контейнер обратно влево, поэтому, чтобы вернуть его в правильное положение, нам нужен третий контейнер с атрибутом align
, установленным на left
. Вот код, чтобы вам было проще понять, о чем речь:
float
(даже в Bootstrap так было). ul
и li
, но, похоже, Netscape не любит сочетание float и list… Более того, использование float непосредственно на теге a удаляет все его стили (речь идет именно о Netscape, на IE все в порядке). В итоге у меня получился список на основе DIV’ов.border
не установлено в none
, то только текст внутри DIV
будет иметь желаемый цвет фона (как будто вы его выделили).background-image
принесла мне еще одну головную боль. IE требует, чтобы путь к изображению (bg.gif)
был относительным к файлу styles.css (так что url('bg.gif')
— это нормально), но Netscape ожидает, что он будет относительным к файлу index.html (url('assets/bg.gif')
). Самое простое решение в данном случае — задать фон непосредственно в атрибуте body style (с указанием пути относительно index.html, разумеется)....
...
margin: 0
, но Netscape и тут отличился! Он же знает, как лучше! Отступы должны быть везде. Конечно, есть решение — использовать отрицательные значения. Однако это повлияет на работу в других браузерах, а другие браузеры понимают, что ZERO — это ZERO. ЗНАЧИТ, НИКАКИХ ОТСТУПОВ НЕ ДОЛЖНО БЫТЬ. ЧТО С ТОБОЙ НЕ ТАК, NETSCAPE? setInterval
, и оказалось, что передача анонимной функции в качестве коллбэка приводит к падению IE спустя несколько секунд.// IE5 KILLER
setInterval(function() {...}, 100);
setInterval
, то все становится на свои места.// THAT'S FINE!
function animateCatchphrase() {...}
setInterval(animateCatchphrase, 100);
В заключение…
Internet Explorer 5
Netscape Navigator 4.51
LAYER
ах… Нет, это уже слишком! Назад в будущее
* {
box-sizing: border-box;
}
Пара слов напоследок