Задумывались ли вы когда-нибудь о том, как жилось веб-разработчикам 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.

Список программ на apcmag.cd, май 1999

Мой изначальный амбициозный план предполагал использование локального сервера и запуск сайта на 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 для проверки правильности реализации вкладок:

<A href="#tab0" tab="tab0" name="link">Link 1</a>
<A href="#tab1" tab="tab1" name="link">Link 2</a>
<A href="#tab2" tab="tab2" name="link">Link 3</a>
<DIV id="tab0">Content 1</div>
<DIV id="tab1" style="display: none;">Content 2</div>
<DIV id="tab2" style="display: none;">Content 3</div>

Я сохранил атрибуты 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, который предназначен для позиционирования на странице и анимации элементов с помощью скриптов.

Единственная проблема с тегом <layer> состоит в том, что он ведет себя как элемент с абсолютным позиционированием (относительно родительского слоя или окна). К счастью, существует также инлайн-тег <ilayer>. Это уже более практичный вариант, но все равно остается одна небольшая проблема — атрибут visibility для layer работает как свойство CSS visibility, то есть скрыть элемент можно, но он все равно будет занимать место на экране. В результате первая вкладка будет отображаться там, где нужно, а остальные — гораздо ниже, и на практике это будет выглядеть скверно. Чтобы это исправить, нужно задать свойству top отрицательное значение. Ф-фух...

Итак, как же выглядит кроссбраузерная версия моего сайта? Во-первых, в <head> документа пришлось добавить небольшой скрипт, чтобы определить, является ли браузер Netscape:

<SCRIPT>
  var probablyNetscape = !!document.layers && !!document.classes && !!document.ids;
</SCRIPT>

Почему я не использовал свойство navigator для проверки браузера? Скажем так, это не совсем надежный метод. Проверка наличия в документе элементов типа layer, являющихся Netscape-специфичными, гарантирует верное срабатывание. 

Как бы то ни было — информацию о браузере я буду использовать и в файле scripts.js, и непосредственно в HTML. Кстати, о HTML, вот он:

<A href="#tab0" onClick="tabLinkClickHandler('tab0')">Link 1</A>
<A href="#tab1" onClick="tabLinkClickHandler('tab1')">Link 2</A>
<A href="#tab2" onClick="tabLinkClickHandler('tab2')">Link 3</A>
<DIV>
 <ILAYER name="tab0" style="display: block;">
   <DIV id="tab0">Content 1</DIV>
 </ILAYER>
 <ILAYER name="tab1" visibility="hide" style="display: block;">
   <DIV id="tab1">Content 2</DIV>
 </ILAYER>
 <SCRIPT>if (!probablyNetscape) {document.getElementById('tab1').style.display = 'none';}</SCRIPT>
 <ILAYER name="tab2" visibility="hide" style="display: block;">
   <DIV id="tab2">Content 3</DIV>
 </ILAYER>
 <SCRIPT>if (!probablyNetscape) {document.getElementById('tab2').style.display = 'none';}</SCRIPT>
</DIV>

Как видите, я использовал инлайн-скрипт, чтобы добавить вкладкам, которые должны быть изначально скрыты, если браузер не Netscape, стиль display: none. Поступил я так потому, что возможность изменять свойство display с помощью JS в Netscape Navigator работает не так, как хотелось бы.

Свойства <ILAYER>, такие как 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, не работает. Есть два возможных решения — тег <center> или <div> с атрибутом align="center". Этим элементом следует обернуть контейнер с содержимым страницы (с шириной, установленной на 480px). В обоих случаях IE центрирует и содержимое потомков, поэтому для контейнера страницы стоит установить атрибут align="left", и это исправит проблему. Однако Netscape сдвигает весь контейнер обратно влево, поэтому, чтобы вернуть его в правильное положение, нам нужен третий контейнер с атрибутом align, установленным на left. Вот код, чтобы вам было проще понять, о чем речь:

<DIV align="center">
 <!-- this one has width set to 480px in styles.css -->
   <DIV class="page-container">
     <DIV align="left">...</DIV>
   </DIV>
</DIV>

CSS flexbox существовал далеко не всегда. Если вы занимаетесь веб-разработкой более ~10 лет, то, скорее всего, помните, что для создания грид-макета многие разработчики применяли свойство float (даже в Bootstrap так было).  

Так вот, я использовал float для выравнивания элементов управления вкладками (ссылок). Я хотел было применить тут теги списков — ul и li, но, похоже, Netscape не любит сочетание float и list... Более того, использование float непосредственно на теге a удаляет все его стили (речь идет именно о Netscape, на IE все в порядке). В итоге у меня получился список на основе DIV'ов.

Цвет фона DIV, заданный с помощью CSS, — это слишком круто для Netscape Navigator v4.51. Если свойство CSS border не установлено в none, то только текст внутри DIV будет иметь желаемый цвет фона (как будто вы его выделили).

IE vs Netscape Navigator
IE vs Netscape Navigator

Настройка background-image принесла мне еще одну головную боль. IE требует, чтобы путь к изображению (bg.gif) был относительным к файлу styles.css (так что url('bg.gif') — это нормально), но Netscape ожидает, что он будет относительным к файлу index.html (url('assets/bg.gif')). Самое простое решение в данном случае — задать фон непосредственно в атрибуте body style (с указанием пути относительно index.html, разумеется).

Когда я работал над навигацией, мне захотелось изменить стили ссылок при открытии связанной с ними вкладки. Из-за ограничений Netscape мне пришлось поиграть с тегом (i)layer, и я докатился до того, что мой HTML стал вызывать критическую ошибку Netscape. 

...
<DIV class="tab-control">
  <ILAYER name="start-link" class="tab-control-layer">
    <DIV class="tab-control-inner">
      <A href="#start" id="start-link">Start</A>
    </DIV>
  </ILAYER>
</DIV>
...

Следующая проблема — отступы (margins). Уточню: margins в Netscape Navigator v4.51. Можно везде задать margin: 0, но Netscape и тут отличился! Он же знает, как лучше! Отступы должны быть везде. Конечно, есть решение — использовать отрицательные значения. Однако это повлияет на работу в других браузерах, а другие браузеры понимают, что ZERO — это ZERO. ЗНАЧИТ, НИКАКИХ ОТСТУПОВ НЕ ДОЛЖНО БЫТЬ. ЧТО С ТОБОЙ НЕ ТАК, NETSCAPE?

На этом этапе я понял, что никогда не сделаю Netscape-версию своего сайта такой хорошей, как мне хочется. К тому же придется использовать для нее специальные стили. Как их дифференцировать? Первой моей мыслью было добавить дополнительный класс к body с помощью JavaScript (если страница открыта не в Netscape), но оказалось, что Netscape Navigator 4 настолько сломан, что просто игнорирует половину стилей.  

Мне так и не удалось убрать пробелы между ссылками вкладок, что видно на картинке выше.

Конечно, Internet Explorer 5 тоже не идеален, у него есть некоторые странности, но Netscape Navigator 4 — это просто чистое безумие.

Кстати, об IE — я хотел реализовать простую анимацию фразы (Welcome to 1999!) под заголовком страницы, которая бы непрерывно скользила слева направо. Для этого я использовал setInterval, и оказалось, что передача анонимной функции в качестве коллбэка приводит к падению IE спустя несколько секунд.

// IE5 KILLER
setInterval(function() {...}, 100);

Если сначала определить функцию, а затем передать ее в setInterval, то все становится на свои места.

// THAT'S FINE!
function animateCatchphrase() {...}

setInterval(animateCatchphrase, 100);

Я готов поспорить, что у IE есть какая-то проблема с управлением памятью в случае использования анонимных функций. У Netscape Navigator с этим проблем нет. Хорошая работа Netscape, 10 баллов Гриффиндору.

В заключение...

Если бы я захотел рассказать обо всех проблемах, с которыми я столкнулся при работе над проектом, то пришлось бы писать целую книгу. В любом случае, спустя несколько часов работы моя страница была готова и функционировала как в Internet Explorer 5, так и в Netscape Navigator 4.51. 

Общий размер всех файлов, необходимых для работы страницы, составляет ~42 КБ (html, css, js и два изображения — все без сжатия). Я не смог найти достоверной информации о средней скорости интернет-соединения в 1999 году, поэтому рассчитаем время загрузки для телефонного модема, который в конце 90-х мог развивать скорость 56 кбит/с — с таким устройством (работающим на полной скорости) на получение всех данных уйдет 6 секунд. В 1999 году это было, наверное, приемлемо. 

Я не буду вставлять сюда весь код (это долго и скучно), ссылка на репозиторий Github будет приведена ниже. А теперь взглянем на несколько скриншотов моей страницы, которые я сделал на Windows 98.

Internet Explorer 5

Start
About
Contact

Должен сказать, что я очень горжусь тем, как всё получилось для Internet Explorer. Страница выглядит и работает так, как я хотел.

Netscape Navigator 4.51

Start
About
Contact

Как видно, версия для Netscape Navigator имеет ряд недостатков... Секция с контентом и вкладки кажутся сломанными, и, несмотря на то, что я потратил кучу времени, пытаясь сделать их вид как можно более близким к тому, что получилось в IE, мне это в итоге не удалось... Возможно, если бы я построил все на LAYERах... Нет, это уже слишком!

Назад в будущее

Вернемся в 2023 год и откроем мою страницу в каком-нибудь современном браузере, например в Google Chrome.

Она выглядит... скромно, но в остальном все смотрится и работает хорошо. Есть одна небольшая проблема с размером блока контента (он слишком широкий, это легко определить, если посмотреть на правый-нижний угол серого блока). Обёртка страницы имеет ширину 480px, а блок контента внутри обёртки страницы также имеет ширину 480px, но при этом имеет 10px padding с каждой стороны. В далеком 1999 году это работало нормально (хотя я подозреваю, что это баг как в IE, так и в Netscape). Теперь же блок контента имеет общую ширину 500px (сумма ширины и padding с обеих сторон), что является более ожидаемым поведением. Это можно исправить с помощью следующих трех строк CSS-кода:

* {
 box-sizing: border-box;
}

Ретро-браузеры его не поймут, поэтому там ничего не должно сломаться. Больше никаких изменений не требуется (ну, разве что нужно добавить короткую информацию о политике конфиденциальности, так как в ЕС действует закон 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-фреймворками и браузерами, которые обновляются чаще, чем я выношу мусор. 

Спасибо, что уделили мне время. На этом всё.