aboutsummaryrefslogtreecommitdiff
path: root/files/ru/learn/tools_and_testing/cross_browser_testing
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:42:52 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:42:52 -0500
commit074785cea106179cb3305637055ab0a009ca74f2 (patch)
treee6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/learn/tools_and_testing/cross_browser_testing
parentda78a9e329e272dedb2400b79a3bdeebff387d47 (diff)
downloadtranslated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz
translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2
translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip
initial commit
Diffstat (limited to 'files/ru/learn/tools_and_testing/cross_browser_testing')
-rw-r--r--files/ru/learn/tools_and_testing/cross_browser_testing/feature_detection/index.html344
-rw-r--r--files/ru/learn/tools_and_testing/cross_browser_testing/html_and_css/index.html487
-rw-r--r--files/ru/learn/tools_and_testing/cross_browser_testing/index.html34
-rw-r--r--files/ru/learn/tools_and_testing/cross_browser_testing/introduction/index.html203
4 files changed, 1068 insertions, 0 deletions
diff --git a/files/ru/learn/tools_and_testing/cross_browser_testing/feature_detection/index.html b/files/ru/learn/tools_and_testing/cross_browser_testing/feature_detection/index.html
new file mode 100644
index 0000000000..8ddb3ea207
--- /dev/null
+++ b/files/ru/learn/tools_and_testing/cross_browser_testing/feature_detection/index.html
@@ -0,0 +1,344 @@
+---
+title: Реализация функции обнаружения
+slug: Learn/Tools_and_testing/Cross_browser_testing/Feature_detection
+translation_of: Learn/Tools_and_testing/Cross_browser_testing/Feature_detection
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/Accessibility","Learn/Tools_and_testing/Cross_browser_testing/Automated_testing", "Learn/Tools_and_testing/Cross_browser_testing")}}</div>
+
+<p class="summary">Обнаружение функций включает определение того, поддерживает ли браузер определенный блок кода, и выполнение другого кода в зависимости от того, поддерживает ли он или нет, так что браузер всегда может обеспечить работу, а не сбой / ошибку в некоторых браузерах. В этой статье подробно описывается, как написать собственное простое обнаружение функций, как использовать библиотеку для ускорения реализации, а также встроенные функции для обнаружения функций, такие как <code>@supports</code>.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Предусловия:</th>
+ <td>Знакомство с основными языками <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, и  <a href="/en-US/docs/Learn/JavaScript">JavaScript</a>; идея высокого уровня <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">принципов кросс-браузерного тестирования.</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Задача:</th>
+ <td>Понять, что такое концепция выявления функций, и уметь внедрять подходящие решения в CSS и JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Концепция_обнаружения_функций.">Концепция обнаружения функций.</h2>
+
+<p>Идея обнаружения функции заключается в том, что вы можете запустить тест, чтобы определить, поддерживается ли функция в текущем браузере, а затем условно запустить код, чтобы обеспечить приемлемый опыт как в браузерах, которые поддерживают функцию, так и в браузере, который не поддерживает. Если вы этого не сделаете, браузеры, которые не поддерживают функции, которые вы используете в своем коде, не будут отображать ваши сайты должным образом и просто не сработают, создавая плохой опыт пользователя.</p>
+
+<p>Давайте подведем итоги и посмотрим на пример, который мы затронули в нашем документе <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript#Feature_detection">Решение самых распространненых проблем JavaScript</a>— <a href="/en-US/docs/Web/API/Geolocation/Using_geolocation">Использование геолокации</a> (который предоставляет доступные данные о местоположении для устройства, на котором работает веб-браузер) есть основная точка входа для его использования, свойство <code>geolocation,</code>  доступное на глобальном объекте <a href="/en-US/docs/Web/API/Navigator">Navigator</a>. Следовательно, вы можете определить, поддерживает ли браузер геолокацию или нет, используя что-то вроде следующего:</p>
+
+<pre class="language-js"><span class="keyword token">if </span><span class="punctuation token">(</span><span class="string token">"geolocation"</span> <span class="keyword token">in</span> navigator<span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ navigator<span class="punctuation token">.</span>geolocation<span class="punctuation token">.</span><span class="function token">getCurrentPosition</span><span class="punctuation token">(</span><span class="keyword token">function</span><span class="punctuation token">(</span>position<span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ // show the location on a map, perhaps using the Google Maps API
+ <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;
+}</span> <span class="keyword token">else</span> <span class="punctuation token">{</span>
+ // Give the user a choice of static maps instead perhaps
+<span class="punctuation token">}</span></pre>
+
+<p>Однако, вероятно, лучше использовать установленную библиотеку обнаружения объектов, а не писать свою собственную все время. Modernizr - это отраслевой стандарт для тестирования функций, и мы рассмотрим это позже.</p>
+
+<p>Прежде чем мы продолжим, мы хотели бы сразу сказать одну вещь - не путайте обнаружение функций с <strong>перехватом браузера</strong> (обнаружение того, какой конкретный браузер обращается к сайту) - это ужасная практика, от которой следует отказаться любой ценой. См. <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript#Using_bad_browser_sniffing_code">Использование плохого кода перехвата браузера</a> для дополнительной информации.</p>
+
+<h2 id="Написание_ваших_собственных_тестов_обнаружения_функций">Написание ваших собственных тестов обнаружения функций</h2>
+
+<p>В этом разделе мы рассмотрим реализацию ваших собственных тестов обнаружения функций как в CSS, так и в JavaScript.</p>
+
+<h3 id="CSS">CSS</h3>
+
+<p>Вы можете написать тесты для функций CSS, протестировав существование <em><a href="/en-US/docs/Web/API/HTMLElement/style">element.style.property</a></em> (например, <code>paragraph.style.transform</code>) в JavaScript.</p>
+
+<p>Классическим примером может быть проверка поддержки <a href="/en-US/docs/Learn/CSS/CSS_layout/Flexbox">Flexbox</a> в браузере; для браузеров, которые поддерживают новейшие спецификации Flexbox, мы могли бы использовать гибкую и надежную гибкую компоновку. Для браузеров, которые этого не делают, мы могли бы использовать плавающий макет, который работает нормально, хотя он немного более хрупкий и хакерский, и не такой привлекательный.</p>
+
+<p>Давайте реализуем что-то, что демонстрирует это, хотя мы пока оставим это простым.</p>
+
+<ol>
+ <li>Начните с создания локальных копий наших файлов <code><a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/feature-detection/css-feature-detect.html">css-feature-detect.html</a></code>, <code><a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/feature-detection/flex-layout.css">flex-layout.css</a></code>, <code><a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/feature-detection/float-layout.css">float-layout-css</a></code>, и <code><a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/feature-detection/basic-styling.css">basic-styling.css</a></code>. Сохраните их в новой дирекции.</li>
+ <li>Мы добавим HTML5 Shiv и в наш пример, чтобы семантические элементы HTML5 правильно стилизовались в старых версиях IE. Загрузите последнюю версию  (См. <a href="https://github.com/aFarkas/html5shiv#manual-installation">Ручная установка</a>), разархивируйте ZIP, скопируйте файлы <code>html5shiv-printshiv.min.js</code> и <code>html5shiv.min.js</code> в ваш пример дирекции и создайте ссылку на один из файлов, поместив следующее в свой {{htmlelement("title")}} элемент:
+ <pre>&lt;script src="html5shiv.min.js"&gt;&lt;/script&gt;</pre>
+ </li>
+ <li>Посмотрите ваши примеры CSS-файлов - вы увидите, что <code>basic-styling.css</code> обрабатывает все стили, которые мы хотим дать каждому браузеру, тогда как два других CSS-файла содержат CSS, который мы хотим выборочно применять к браузеру в зависимости от  их уровни поддержки. Вы можете посмотреть на различные эффекты этих двух файлов, вручную изменив CSS-файл, на который ссылается второй элемент {{htmlelement("link")}}, но давайте вместо этого реализуем некоторый JavaScript, чтобы автоматически заменять их при необходимости.</li>
+ <li>Сначала удалите содержимое атрибута <code>href</code> второго элемента <code>&lt;link&gt;</code> . Мы будем заполнять это динамически позже.</li>
+ <li>Затем добавьте элемент <code>&lt;script&gt;&lt;/script&gt;</code> внизу вашего контекста (непосредственно перед закрывающим тегом <code>&lt;/body&gt;</code>).</li>
+ <li>Дайте ему следующее содержание:
+ <pre class="brush: js">const conditional = document.querySelector('.conditional');
+const testElem = document.createElement('div');
+if (testElem.style.flex !== undefined &amp;&amp; testElem.style.flexFlow !== undefined) {
+ conditional.setAttribute('href', 'flex-layout.css');
+} else {
+ conditional.setAttribute('href', 'float-layout.css');
+}</pre>
+ </li>
+</ol>
+
+<p>Здесь мы берем ссылку на второй элемент <code>&lt;link&gt;</code> и создаем элемент <code>&lt;div&gt;</code> как часть нашего теста.  В нашем условном выражении мы проверяем, что свойства {{cssxref ("flex")}} и {{cssxref ("flex-flow")}} существуют в браузере. Обратите внимание, что представления JavaScript этих свойств, которые хранятся внутри объекта {{domxref ("HTMLElement.style")}}, используют нижний горбатый регистр, а не дефисы, для разделения слов.</p>
+
+<div class="note">
+<p><strong>Примечание: </strong>Если у вас возникли проблемы с выполнением этого, вы можете сравнить его с нашим кодом <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/feature-detection/css-feature-detect-finished.html">css-feature-detect-finished.html</a> (см. Также <a href="http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/feature-detection/css-feature-detect-finished.html">живую версию</a>).</p>
+</div>
+
+<p>Когда вы сохраните все и опробуете свой пример, вы должны увидеть макет flexbox, примененный к странице, если браузер поддерживает современный flexbox, и макет float, если нет.</p>
+
+<div class="note">
+<p><strong>Примечание:</strong> Часто такой подход является излишним из-за незначительной проблемы с обнаружением функций - вы часто можете обойтись без использования префиксов нескольких поставщиков и свойств резервирования, как описано в разделе <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS#CSS_fallback_behaviour">Поведение CSS-откат</a> и <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS#Handling_CSS_prefixes">Обработка префиксов CSS</a>.</p>
+</div>
+
+<h4 id="supports">@supports</h4>
+
+<p>Недавно, в CSS появился собственный механизм обнаружения собственных функций — {{cssxref("@supports")}} at-rule. Это работает аналогично <a href="/en-US/docs/Web/CSS/Media_Queries">медиазапросам</a> (см. Также <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS#Responsive_design_problems">Адаптивные проблемы дизайна</a>) — за исключением того, что вместо выборочного применения CSS в зависимости от медиа-функции, такой как разрешение, ширина экрана или соотношение сторон, выборочно применяется CSS в зависимости от того, поддерживается ли функция CSS.</p>
+
+<p>Например, мы могли бы переписать наш предыдущий пример для использования <code>@supports</code> — см. <code><a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/feature-detection/supports-feature-detect.html">supports-feature-detect.html</a></code> и <code><a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/feature-detection/supports-styling.css">supports-styling.css</a></code>. Если вы посмотрите на последнее, вы увидите пару блоков <code>@supports</code> например:</p>
+
+<pre class="brush: css">@supports (flex-flow: row) and (flex: 1) {
+
+ main {
+ display: flex;
+ }
+
+ main div {
+ padding-right: 4%;
+ flex: 1;
+ }
+
+ main div:last-child {
+ padding-right: 0;
+ }
+
+}</pre>
+
+<p>Этот блок at-rule применяет правило CSS только в том случае, если текущий браузер поддерживает объявления как <code>flex-flow: row</code> так и <code>flex: 1</code>. Чтобы каждое условие работало, вам необходимо включить полное объявление (а не просто имя свойства) и НЕ включать точку с запятой в конце.</p>
+
+<p><code>@supports</code> также имеет логику <code>OR</code> и <code>NOT</code> — другой блок применяет разметку с плавающей запятой, если свойства flexbox недоступны:</p>
+
+<pre class="brush: css">@supports not (flex-flow: row) and (flex: 1) {
+
+ /* rules in here */
+
+}</pre>
+
+<p>Это может выглядеть намного удобнее, чем в предыдущем примере - мы можем выполнять все наши функции обнаружения в CSS, JavaScript не требуется, и мы можем обрабатывать всю логику в одном файле CSS, сокращая HTTP-запросы. Проблема здесь в поддержке браузера — <code>@supports</code> вообще не поддерживается в IE, а поддерживается только в самых последних версиях Safari / iOS WebKit (9 + / 9.2 +), тогда как версия JavaScript должна работать в гораздо более старых браузерах (вероятно, назад  до IE8 или 9, хотя в более старых версиях IE будут возникать дополнительные проблемы, такие как отсутствие поддержки {{domxref ("Document.querySelector")}} и наличие испорченной блочной модели).</p>
+
+<h3 id="JavaScript">JavaScript</h3>
+
+<p>Мы уже видели пример теста на обнаружение функций JavaScript ранее. Как правило, такие тесты выполняются по одному из следующих общих шаблонов:</p>
+
+<table class="standard-table">
+ <caption>Краткое изложение методов обнаружения функций JavaScript</caption>
+ <thead>
+ <tr>
+ <th scope="col">Тип обнаружения функции</th>
+ <th scope="col">Объяснение</th>
+ <th scope="col">Пример</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><em>Если член в объекте</em></td>
+ <td>Проверьте, существует ли определенный метод или свойство (обычно точка входа в использование API или другой функции, которую вы обнаруживаете) в его родительском объекте.</td>
+ <td>
+ <p><code>if("geolocation" in navigator) { ... }</code></p>
+ </td>
+ </tr>
+ <tr>
+ <td><em>Свойство на элементе</em></td>
+ <td>Создайте элемент в памяти, используя {{domxref ("Document.createElement()")}}, а затем проверьте, существует ли свойство для него.  Показанный пример является способом определения поддержки  <a href="/en-US/docs/Web/API/Canvas_API">HTML5 Canvas</a>.</td>
+ <td><code>function supports_canvas() {<br>
+ return !!document.createElement('canvas').getContext;<br>
+ }<br>
+ <br>
+ if(supports_canvas()) { ... }</code></td>
+ </tr>
+ <tr>
+ <td><em>Метод на возвращаемое значение элемента</em></td>
+ <td>Создайте элемент в памяти, используя {{domxref ("Document.createElement()")}}, а затем проверьте, существует ли метод для него.  Если это так, проверьте, какое значение он возвращает.</td>
+ <td>См. <a href="http://diveinto.html5doctor.com/detect.html#video-formats">Dive Into HTML5 Video Formats detection</a>.</td>
+ </tr>
+ <tr>
+ <td><em>Свойство на сохраняемое значение элемента</em></td>
+ <td>Создайте элемент в памяти, используя {{domxref ("Document.createElement()")}}, установите для свойства определенное значение, затем проверьте, сохраняется ли значение.</td>
+ <td>См. <a href="http://diveinto.html5doctor.com/detect.html#input-types">Dive into HTML5 <code>&lt;input&gt;</code> types detection</a>.</td>
+ </tr>
+ </tbody>
+</table>
+
+<div class="note">
+<p><strong>Примечание:</strong> Двойное <code>NOT</code> в приведенном выше примере (<code>!!</code>) это способ заставить возвращаемое значение стать «правильным» логическим значением, а не {{glossary("Truthy")}}/{{glossary("Falsy")}} значение, которое может исказить результаты.</p>
+</div>
+
+<p>Страница <a href="http://diveinto.html5doctor.com/detect.html">Погружение в HTML5 Обнаружение функций HTML5</a> содержит гораздо больше полезных тестов для обнаружения функций, помимо перечисленных выше, и вы можете найти тест обнаружения функций для большинства вещей, выполнив поиск «обнаружение поддержки для ВАШИ-ФУНКЦИИ-ЗДЕСЬ» в своей любимой поисковой системе. Имейте в виду, однако, что некоторые функции, как известно, не обнаруживаются - см. список Modernizr <a href="https://github.com/Modernizr/Modernizr/wiki/Undetectables">Необнаруживаемые</a>.</p>
+
+<h4 id="matchMedia">matchMedia</h4>
+
+<p>Мы также хотели упомянуть функцию JavaScript {{domxref("Window.matchMedia")}} на этом этапе. Это свойство, которое позволяет вам запускать тесты медиа-запросов внутри JavaScript. Это выглядит так:</p>
+
+<pre class="brush: js">if (window.matchMedia("(max-width: 480px)").matches) {
+ // run JavaScript in here.
+}</pre>
+
+<p>В качестве примера, наша демо версия <a href="https://github.com/chrisdavidmills/snapshot">Snapshot</a> использует ее для выборочного применения библиотеки Brick JavaScript и ее использования для обработки макета пользовательского интерфейса, но только для небольшого экрана (шириной 480 пикселей или меньше). Сначала мы используем атрибут <code>media</code>,чтобы применить CSS-код Brick к странице, только если ширина страницы составляет 480px или меньше:</p>
+
+<pre class="brush: css">&lt;<span class="pl-ent">link</span> <span class="pl-e">href</span>=<span class="pl-s"><span class="pl-pds">"</span>dist/brick.css<span class="pl-pds">"</span></span> <span class="pl-e">type</span>=<span class="pl-s"><span class="pl-pds">"</span>text/css<span class="pl-pds">"</span></span> <span class="pl-e">rel</span>=<span class="pl-s"><span class="pl-pds">"</span>stylesheet<span class="pl-pds">"</span></span> <span class="pl-e">media</span>=<span class="pl-s"><span class="pl-pds">"</span>all and (max-width: 480px)<span class="pl-pds">"</span></span>&gt;</pre>
+
+<p>Затем мы используем <code>matchMedia()</code> в JavaScript несколько раз, чтобы запускать функции навигации Brick только в том случае, если мы на маленьком экране (в более широких экранах все можно увидеть сразу, поэтому нам не нужно переходить между различными изображениями).</p>
+
+<pre class="brush: js">if (window.matchMedia("(max-width: 480px)").matches) {
+ deck.shuffleTo(1);
+}</pre>
+
+<h2 id="Использование_Modernizr_для_реализации_обнаружения_функций">Использование Modernizr для реализации обнаружения функций</h2>
+
+<p>Можно реализовать свои собственные тесты обнаружения функций, используя методы, подобные тем, которые подробно описаны выше. Вы можете также использовать специальную библиотеку обнаружения функций, так как она всё упрощает. Основой всех библиотек обнаружения функций является <a href="https://modernizr.com/">Modernizr</a>, и он может обнаружить практически все, что вам когда-либо понадобится. Давайте посмотрим, как его использовать.</p>
+
+<p>Когда вы экспериментируете с Modernizr, вы также можете использовать сборку разработки, которая включает в себя все возможные тесты обнаружения функций. Скачать:</p>
+
+<ol>
+ <li>Нажав на ссылку <a href="https://modernizr.com/download?do_not_use_in_production">Сборка разработки</a>.</li>
+ <li>Нажав на большую розовую кнопку <em>Build</em> на появившейся странице.</li>
+ <li>Нажав на верхнюю ссылку <em>Download</em> в появившемся диалоговом окне.</li>
+</ol>
+
+<p>Сохраните его где-нибудь разумно, например, в директории, для которой вы создавали другие примеры в этой статье.</p>
+
+<p>Когда вы используете Modernizr в рабочей среде, вы можете перейти на <a href="https://modernizr.com/download">Страницу скачивания</a> которую вы уже посетили, и нажимать кнопки плюс только для тех функций, которые вам нужны. Затем, когда вы нажмете кнопку <em>Build</em> вы загрузите пользовательскую сборку, содержащую только те функции, которые обнаружены, что позволит значительно уменьшить размер файла.</p>
+
+<h3 id="CSS_2">CSS</h3>
+
+<p>Давайте посмотрим, как Modernizr работает с точки зрения избирательного применения CSS.</p>
+
+<ol>
+ <li>Во-первых, создайте копию <code><a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/feature-detection/supports-feature-detect.html">supports-feature-detect.html</a></code> и <code><a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/feature-detection/supports-styling.css">supports-styling.css</a></code>. Сохраните их как <code>modernizr-css.html</code> и <code>modernizr-css.css</code>.</li>
+ <li>Обновите ваш элемент {{htmlelement ("link")}} в своем HTML-коде, чтобы он указывал на правильный файл CSS (также следует обновить элемент {{htmlelement ("title")}} на что-то более подходящее!):
+ <pre class="brush: html">&lt;link href="modernizr-css.css" rel="stylesheet"&gt;</pre>
+ </li>
+ <li>Над этим элементом <code>&lt;link&gt;</code> добавьте элемент {{htmlelement ("script")}}, чтобы применить библиотеку Modernizr к странице, как показано ниже. Это должно быть применено к странице перед любым CSS (или JavaScript), который может ее использовать.
+ <pre class="brush: html">&lt;script src="modernizr-custom.js"&gt;&lt;/script&gt;</pre>
+ </li>
+ <li>Теперь отредактируйте открывающий тег <code>&lt;html&gt;</code>, чтобы он выглядел так:
+ <pre class="brush: html">&lt;html class="no-js"&gt;</pre>
+ </li>
+</ol>
+
+<p>На этом этапе попробуйте загрузить свою страницу, и вы получите представление о том, как Modernizr работает с функциями CSS. Если вы посмотрите на инспектор DOM инструментов разработчика вашего браузера, вы увидите, что Modernizr обновил значение вашего <code>&lt;html&gt;</code> <code>class</code> следующим образом:</p>
+
+<pre>&lt;html class="js no-htmlimports sizes flash transferables applicationcache blobconstructor
+blob-constructor cookies cors ...AND LOADS MORE VALUES!&gt;</pre>
+
+<p>Теперь он содержит большое количество классов, которые указывают на состояние поддержки различных функций. Например, если браузер вообще не поддерживает flexbox, <code>&lt;html&gt;</code> будет присвоено имя класса <code>no-flexbox</code>. Если бы он поддерживал современный flexbox, он получил бы имя класса <code>flexbox</code>. Если вы выполните поиск в списке классов, вы также увидите другие, относящиеся к flexbox, например:</p>
+
+<ul>
+ <li><code>flexboxlegacy</code> для старой спецификации flexbox (2009).</li>
+ <li><code>flexboxtweener</code> для промежуточного синтаксиса 2011 года, поддерживаемого IE10.</li>
+ <li><code>flexwrap</code> для свойства {{cssxref ("flex-wrap")}}, которого нет в некоторых реализациях.</li>
+</ul>
+
+<div class="note">
+<p><strong>Примечание:</strong> Вы можете найти список того, что означают все имена классов — см.  <a href="https://modernizr.com/docs#features">Функции, обнаруженные Modernizr</a>.</p>
+</div>
+
+<p>Далее, давайте обновим наш CSS, чтобы использовать Modernizr вместо <code>@supports</code>. Перейдите в <code>modernizr-css.css</code>, и замените два блока <code>@supports</code> следующим:</p>
+
+<pre class="brush: css">/* Properties for browsers with modern flexbox */
+
+.flexbox main {
+ display: flex;
+}
+
+.flexbox main div {
+ padding-right: 4%;
+ flex: 1;
+}
+
+.flexbox main div:last-child {
+ padding-right: 0;
+}
+
+/* Fallbacks for browsers that don't support modern flexbox */
+
+.no-flexbox main div {
+ width: 22%;
+ float: left;
+ padding-right: 4%;
+}
+
+.no-flexbox main div:last-child {
+ padding-right: 0;
+}
+
+.no-flexbox footer {
+ clear: left;
+}</pre>
+
+<p>Так как же это работает? Поскольку все эти имена классов были помещены в элемент <code>&lt;html&gt;</code> вы можете настроить таргетинг на браузеры, которые поддерживают или не поддерживают функцию, используя определенные селекторы-потомки. Поэтому здесь мы применяем верхний набор правил только для браузеров, которые поддерживают flexbox, а нижний набор правил - только для браузеров, которые не поддерживают (<code>no-flexbox</code>).</p>
+
+<div class="note">
+<p><strong>Примечание:</strong> Имейте в виду, что все тесты функций HTML и JavaScript Modernizr также представлены в этих именах классов, так что вы можете свободно применять CSS выборочно в зависимости от того, поддерживает ли браузер функции HTML или JavaScript, если это необходимо.</p>
+</div>
+
+<div class="note">
+<p><strong>Примечание:</strong> Если у вас возникли проблемы с выполнением этого, проверьте ваш код по файлам <code><a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/feature-detection/modernizr-css.html">modernizr-css.html</a></code> и <code><a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/feature-detection/modernizr-css.css">modernizr-css.css</a></code> (см. Также этот запуск в реальном времени).</p>
+</div>
+
+<h3 id="JavaScript_2">JavaScript</h3>
+
+<p>Modernizr также одинаково хорошо подготовлен для реализации функций обнаружения JavaScript. Это достигается за счет того, что глобальный объект <code>Modernizr</code> становится доступным для страницы, к которой он применяется, и содержит результаты функции, определяемой как свойства <code>true</code>/<code>false</code>.</p>
+
+<p>Например, загрузите наш пример <code><a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/feature-detection/modernizr-css.html">modernizr-css.html</a></code> в своем браузере, затем попробуйте перейти на консоль JavaScript и набрать  <code>Modernizr.</code>, а после некоторые из этих имен классов (они тоже здесь одинаковы). Например:</p>
+
+<pre>Modernizr.flexbox
+Modernizr.websqldatabase
+Modernizr.xhr2
+Modernizr.fetch</pre>
+
+<p>Консоль вернет значения <code>true</code>/<code>false</code>, чтобы указать, поддерживает ли ваш браузер эти функции или нет.</p>
+
+<p>Давайте посмотрим на пример, чтобы показать, как вы бы пользовали эти свойства.</p>
+
+<ol>
+ <li>Прежде всего, сделайте локальную копию файла примера <code><a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/feature-detection/modernizr-js.html">modernizr-js.html</a></code>.</li>
+ <li>Присоедините библиотеку Modernizr к HTML, используя элемент <code>&lt;script&gt;</code> , как мы делали в предыдущих демонстрациях. Поместите его над существующим элементом <code>&lt;script&gt;</code> который прикрепляет API Google Maps к странице.</li>
+ <li>Затем заполните текст-заполнитель <code>YOUR-API-KEY</code> во втором элементе <code>&lt;script&gt;</code> (как он есть сейчас) действительным ключом API Google Maps. Чтобы получить ключ, войдите в учетную запись Google, перейдите на страницу <a href="https://developers.google.com/maps/documentation/javascript/get-api-key">Получить ключ / Аутентификация</a> затем нажмите синюю кнопку <em>Get a Key</em> и следуйте инструкциям.</li>
+ <li>Наконец, добавьте еще один элемент <code>&lt;script&gt;</code> внизу тела HTML (непосредственно перед тегом <code>&lt;/body&gt;</code> ) и поместите следующий скрипт в теги:
+ <pre class="brush: js">if (Modernizr.geolocation) {
+
+ navigator.geolocation.getCurrentPosition(function(position) {
+
+ let latlng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
+ let myOptions = {
+ zoom: 8,
+ center: latlng,
+ mapTypeId: google.maps.MapTypeId.TERRAIN,
+ disableDefaultUI: true
+ }
+ let map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
+ });
+
+} else {
+ const para = document.createElement('p');
+ para.textContent = 'Argh, no geolocation!';
+ document.body.appendChild(para);
+}</pre>
+ </li>
+</ol>
+
+<p>Опробуйте свой пример! Здесь мы используем тест <code>Modernizr.geolocation</code>, чтобы проверить, поддерживается ли геолокация текущим браузером. Если это так, мы запускаем некоторый код, который получает текущее местоположение вашего устройства и отображает его на карте Google.</p>
+
+<h2 id="Подведение_итогов">Подведение итогов</h2>
+
+<p>В этой статье было рассмотрено обнаружение функций с достаточным количеством подробностей, рассмотрены основные концепции и показано, как реализовать свои собственные тесты обнаружения функций и использовать библиотеку Modernizr для более легкой реализации тестов.</p>
+
+<p>Далее мы начнем изучать автоматизированное тестирование.</p>
+
+<p>{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/Accessibility","Learn/Tools_and_testing/Cross_browser_testing/Automated_testing", "Learn/Tools_and_testing/Cross_browser_testing")}}</p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">Введение в кросс-браузерное тестирование</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies">Стратегии проведения тестирования</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS">Решение распространенных проблем HTML и CSS</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript">Решение распространенных проблем JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility">Решение распространенных проблем доступности</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection">Реализация функции обнаружения</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing">Введение в автоматизированное тестирование</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Настройка собственной среды автоматизации тестирования</a></li>
+</ul>
diff --git a/files/ru/learn/tools_and_testing/cross_browser_testing/html_and_css/index.html b/files/ru/learn/tools_and_testing/cross_browser_testing/html_and_css/index.html
new file mode 100644
index 0000000000..64ff9cafcc
--- /dev/null
+++ b/files/ru/learn/tools_and_testing/cross_browser_testing/html_and_css/index.html
@@ -0,0 +1,487 @@
+---
+title: Handling common HTML and CSS problems
+slug: Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS
+translation_of: Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies","Learn/Tools_and_testing/Cross_browser_testing/JavaScript", "Learn/Tools_and_testing/Cross_browser_testing")}}</div>
+
+<p class="summary">With the scene set, we'll now look specifically at the common cross-browser problems you will come across in HTML and CSS code, and what tools can be used to prevent problems from happening, or fix problems that occur. This includes linting code, handling CSS prefixes, using browser dev tools to track down problems, using polyfills to add support into browsers, tackling responsive design problems, and more.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Пререквизиты:</th>
+ <td>Знакомство с основами <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, и <a href="/en-US/docs/Learn/JavaScript">JavaScript</a>; идея высокого уровня <a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">кросс-браузерного тестирования</a></td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Иметь возможность находить распространенные кросс-браузерные проблемы HTML и CSS, использовать нужные инструменты и методы для их устранения</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="The_trouble_with_HTML_and_CSS">The trouble with HTML and CSS</h2>
+
+<p>Some of the trouble with HTML and CSS lies with the fact that both languages are fairly simple, and often developers don't take them seriously, in terms of making sure the code is well-crafted, efficient, and semantically describes the purpose of the features on the page. In the worst cases, JavaScript is used to generate the entire web page content and style, which makes your pages inaccessible, and less performant (generating DOM elements is expensive). In other cases, nascent features are not supported consistently across browsers, which can make some features and styles not work for some users. Responsive design problems are also common — a site that looks good in a desktop browser might provide a terrible experience on a mobile device, because the content is too small to read, or perhaps the site is slow because of expensive animations.</p>
+
+<p>Let's go forth and look at how we can reduce cross browser errors that result from HTML/CSS.</p>
+
+<h2 id="First_things_first_fixing_general_problems">First things first: fixing general problems</h2>
+
+<p>We said in the <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction#Testingdiscovery">first article of this series</a> that a good strategy to begin with is to test in a couple of modern browsers on desktop/mobile, to make sure your code is working generally, before going on to concentrate on the cross browser issues.</p>
+
+<p>In our <a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/Debugging_HTML">Debugging HTML</a> and <a href="/en-US/docs/Learn/CSS/Introduction_to_CSS/Debugging_CSS">Debugging CSS</a> articles, we provided some really basic guidance on debugging HTML/CSS — if you are not familiar with the basics, you should definitely study these articles before carrying on.</p>
+
+<p>Basically, it is a matter of checking whether your HTML and CSS code is well formed and doesn't contain any syntax errors.</p>
+
+<div class="note">
+<p><strong>Note</strong>: One common problem with CSS and HTML arises when different CSS rules begin to conflict with one another. This can be especially problematic when you are using third party code. For example, you might use a CSS framework and find that one of the class names it uses clashes with one you've already used for a different purpose. Or you might find that HTML generated by some kind of third party API (generating ad banners, for example) includes a class name or ID that you are already using for a different purpose. To ensure this doesn't happen, you need to research the tools you are using first and design your code around them. It is also worth "namespacing" CSS, e.g. if you have a widget, make sure it has a distinct class, and then start the selectors that select elements inside the widget with this class, so conflicts are less likely. For example <code>.audio-player ul a</code>.</p>
+</div>
+
+<h3 id="Validation">Validation</h3>
+
+<p>For HTML, validation involves making sure all your tags are properly closed and nested, you are using a DOCTYPE, and you are using tags for their correct purpose. A good strategy is to validate your code regularly. One service that can do this is the W3C <a class="external external-icon" href="https://validator.w3.org/">Markup Validation Service</a>, which allows you to point to your code, and returns a list of errors:</p>
+
+<p><img alt="The HTML validator homepage" src="https://mdn.mozillademos.org/files/12441/validator.png" style="display: block; margin: 0px auto;"></p>
+
+<p>CSS has a similar story — you need to check that your property names are spelled correctly, property values are spelled correctly and are valid for the properties they are used on, you are not missing any curly braces, and so on. The W3C has a <a class="external external-icon" href="http://jigsaw.w3.org/css-validator/">CSS Validator</a> available too, for this purpose.</p>
+
+<h3 id="Linters">Linters</h3>
+
+<p>Another good option to choose is a so-called Linter application, which not only points out errors, but can also flag up warnings about bad practices in your CSS, and other points besides. Linters can generally be customized to be stricter or more relaxed in their error/warning reporting.</p>
+
+<p>There are many online linter applications, the best of which are probably <a href="https://www.dirtymarkup.com/">Dirty Markup</a> (HTML, CSS, JavaScript), and <a href="http://csslint.net/">CSS Lint</a> (CSS only). These allows you to paste your code into a window, and it will flag up any errors with crosses, which can then be hovered to get an error message informing you what the problem is. Dirty Markup also allows you to make fixes to your markup using the <em>Clean</em> button.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14113/dirty-markup.png" style="border-style: solid; border-width: 1px; display: block; height: 203px; margin: 0px auto; width: 1204px;"></p>
+
+<p>However, it is not very convenient to have to copy and paste your code over to a web page to check its validity several times. What you really want is a linter that will fit into your standard workflow with the minimum of hassle.</p>
+
+<p>Many code editors have linter plugins. Github's <a href="https://atom.io/">Atom</a> code editor for example has a rich plugin ecosystem available, with many linting options. To show you an example of how such plugins generally work:</p>
+
+<ol>
+ <li>Install Atom (if you haven't got an up-to-date version already installed) — download it from the Atom page linked above.</li>
+ <li>Go to Atom's <em>Preferences...</em> dialog (e.g. by Choosing <em>Atom &gt; Preferences...</em> on Mac, or <em>File &gt; Preferences...</em> on Windows/Linux) and choose the <em>Install</em> option in the left hand menu.</li>
+ <li>In the <em>Search packages</em> text field, type "lint" and press Enter/Return to search for linting-related packages.</li>
+ <li>You should see a package called <strong>lint</strong> at the top of the list. Install this first (using the <em>Install</em> button), as other linters rely on it to work. After that, install the <strong>linter-csslint</strong> plugin for linting CSS, and the <strong>linter-tidy</strong> plugin for linting HTML.</li>
+ <li>After the packages have finished installing, try loading up an HTML file and a CSS file: you'll see any issues highlighted with green (for warnings) and red (for errors) circles next to the line numbers, and a separate panel at the bottom provides line numbers, error messages, and sometimes suggested values or other fixes.</li>
+</ol>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14109/atom-htmltidy.png" style="display: block; margin: 0 auto;"><img alt="" src="https://mdn.mozillademos.org/files/14107/atom-csslint.png" style="display: block; height: 516px; margin: 0px auto; width: 700px;"></p>
+
+<p>Other popular editors have similar linting packages available. For example, see:</p>
+
+<ul>
+ <li><a href="www.sublimelinter.com/">SublimeLinter</a> for Sublime Text</li>
+ <li><a href="https://sourceforge.net/projects/notepad-linter/">Notepad++ linter</a></li>
+</ul>
+
+<h3 id="Browser_developer_tools">Browser developer tools</h3>
+
+<p>The developer tools built into most browsers also feature useful tools for hunting down errors, mainly for CSS.</p>
+
+<div class="note">
+<p><strong>Note</strong>: HTML errors don't tend to show up so easily in dev tools, as the browser will try to correct badly-formed markup automatically; the W3C validator is the best way to get HTML errors — see {{anch("Validation")}} above.</p>
+</div>
+
+<p>As an example, in Firefox the CSS inspector will show CSS declarations that aren't applied crossed out, with a warning triangle. Hovering the warning triangle will provide a descriptive error message:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14111/css-message-devtools.png" style="display: block; height: 311px; margin: 0px auto; width: 451px;"></p>
+
+<p>Other browser devtools have similar features.</p>
+
+<h2 id="Common_cross_browser_problems">Common cross browser problems</h2>
+
+<p>Now let's move on to look at some of the most common cross browser HTML and CSS problems. The main areas we'll look at are lack of support for modern features, and layout issues.</p>
+
+<h3 id="Older_browsers_not_supporting_modern_features">Older browsers not supporting modern features</h3>
+
+<p>This is a common problem, especially when you need to support old browsers (such as old IE versions) or you are using features that are implemented using CSS prefixes. In general, most core HTML and CSS functionality (such as basic HTML elements, CSS basic colors and text styling) works across most browsers you'll want to support; more problems are uncovered when you start wanting to use newer features such as <a href="/en-US/docs/Learn/CSS/CSS_layout/Flexbox">Flexbox</a>, or <a href="/en-US/docs/Web/Apps/Fundamentals/Audio_and_video_delivery">HTML5 video/audio</a>, or even more nascent, <a href="/en-US/docs/Learn/CSS/CSS_layout/Grids#Native_CSS_Grids_with_Grid_Layout">CSS Grids</a> or <a href="/en-US/docs/Learn/CSS/Styling_boxes/Advanced_box_effects#-webkit-background-clip_text">-webkit-background-clip: text</a>.</p>
+
+<p>Once you've identified a list of potential problem technologies you will be using, it is a good idea to research what browsers they are supported in, and what related techniques are useful. See {{anch("Finding help")}} below.</p>
+
+<h4 id="HTML_fallback_behaviour">HTML fallback behaviour</h4>
+
+<p>Some problems can be solved by just taking advantage of the natural way in which HTML/CSS work.</p>
+
+<p>Unrecognised HTML elements are treated by the browser as anonymous inline elements (effectively inline elements with no semantic value, similar to {{htmlelement("span")}} elements). You can still refer to them by their names, and style them with CSS, for example — you just need to make sure they are behaving as you want them to, for example setting <code>display: block;</code> on all of the new semantic elements (such as {{htmlelement("article")}}, {{htmlelement("aside")}}, etc.), but only in old versions of IE that don't recognise them (so, IE 8 and lower). This way new browsers can just use the code as normal, but older IE versions will be able to style these elements too.</p>
+
+<div class="note">
+<p><strong>Note</strong>: See {{anch("IE conditional comments")}} for the best way to do this.</p>
+</div>
+
+<p>More complex elements like HTML <code><a href="/en-US/docs/Web/HTML/Element/video">&lt;video&gt;</a></code>, <code><a href="/en-US/docs/Web/HTML/Element/audio">&lt;audio&gt;</a></code>, and <code><a href="/en-US/docs/Web/HTML/Element/canvas">&lt;canvas&gt;</a></code> (and other features besides) have natural mechanisms for fallbacks to be added, which work on the same principle as described above. You can add fallback content in between the opening and closing tags, and non-supporting browsers will effectively ignore the outer element and run the nested content.</p>
+
+<p>For example:</p>
+
+<pre class="brush: html"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>video</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video<span class="punctuation token">"</span></span> <span class="attr-name token">controls</span> <span class="attr-name token">preload</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>metadata<span class="punctuation token">"</span></span> <span class="attr-name token">poster</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>img/poster.jpg<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>source</span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video/tears-of-steel-battle-clip-medium.mp4<span class="punctuation token">"</span></span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video/mp4<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token"> &lt;</span>source</span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video/tears-of-steel-battle-clip-medium.webm<span class="punctuation token">"</span></span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video/webm<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>source</span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video/tears-of-steel-battle-clip-medium.ogg<span class="punctuation token">"</span></span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video/ogg<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
+ <span class="comment token">&lt;!-- Flash fallback --&gt;</span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>object</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>application/x-shockwave-flash<span class="punctuation token">"</span></span> <span class="attr-name token">data</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>flash-player.swf?videoUrl<span class="punctuation token">=</span>video/tears-of-steel-battle-clip-medium.mp4<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>1024<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>576<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>param</span> <span class="attr-name token">name</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>movie<span class="punctuation token">"</span></span> <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>flash-player.swf?videoUrl<span class="punctuation token">=</span>video/tears-of-steel-battle-clip-medium.mp4<span class="punctuation token">"</span></span> <span class="punctuation token">/&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>param</span> <span class="attr-name token">name</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>allowfullscreen<span class="punctuation token">"</span></span> <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>true<span class="punctuation token">"</span></span> <span class="punctuation token">/&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>param</span> <span class="attr-name token">name</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>wmode<span class="punctuation token">"</span></span> <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>transparent<span class="punctuation token">"</span></span> <span class="punctuation token">/&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>param</span> <span class="attr-name token">name</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>flashvars<span class="punctuation token">"</span></span> <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>controlbar<span class="punctuation token">=</span>over&amp;amp;image<span class="punctuation token">=</span>img/poster.jpg&amp;amp;file<span class="punctuation token">=</span>flash-player.swf?videoUrl<span class="punctuation token">=</span>video/tears-of-steel-battle-clip-medium.mp4<span class="punctuation token">"</span></span> <span class="punctuation token">/&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>img</span> <span class="attr-name token">alt</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>Tears of Steel poster image<span class="punctuation token">"</span></span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>img/poster.jpg<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>1024<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>428<span class="punctuation token">"</span></span> <span class="attr-name token">title</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>No video playback possible, please download the video from the link below<span class="punctuation token">"</span></span> <span class="punctuation token">/&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>object</span><span class="punctuation token">&gt;</span></span>
+ <span class="comment token">&lt;!-- Offer download --&gt;</span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>a</span> <span class="attr-name token">href</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video/tears-of-steel-battle-clip-medium.mp4<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>Download MP4<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>a</span><span class="punctuation token">&gt;</span></span>
+<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>video</span><span class="punctuation token">&gt;</span></span></code></pre>
+
+<p>This example (taken from <a href="/en-US/docs/Web/Apps/Fundamentals/Audio_and_video_delivery/cross_browser_video_player">Creating a cross-browser video player</a>) includes not only a Flash video fallback for older IE versions, but also a simple link allowing you to download the video if even the Flash player doesn't work, so at least the user can still access the video.</p>
+
+<div class="note">
+<p><strong>Note</strong>: 3rd party libraries like <a href="http://videojs.com/">Video.js</a> and <a href="https://www.jwplayer.com/">JW Player</a> use such fallback mechanisms to provide cross-browser support.</p>
+</div>
+
+<p>HTML5 form elements also exhibit fallback qualities — HTML5 introduced some special <code><a href="/en-US/docs/Web/HTML/Element/input">&lt;input&gt;</a></code> types for inputting specific information into forms, such as times, dates, colors, numbers, etc. These are very useful, particularly on mobile platforms, where providing a pain-free way of entering data is very important for the user experience. Supporting platforms provide special UI widgets when these input types are used, such as a calendar widget for entering dates.</p>
+
+<p>The following example shows date and time inputs:</p>
+
+<pre class="brush: html">&lt;form&gt;
+ &lt;div&gt;
+ &lt;label for="date"&gt;Enter a date:&lt;/label&gt;
+ &lt;input id="date" type="date"&gt;
+ &lt;/div&gt;
+ &lt;div&gt;
+ &lt;label for="time"&gt;Enter a time:&lt;/label&gt;
+ &lt;input id="time" type="time"&gt;
+ &lt;/div&gt;
+&lt;/form&gt;</pre>
+
+<p>The output of this code is as follows:</p>
+
+<div class="hidden">
+<h6 id="Hidden_example">Hidden example</h6>
+
+<pre class="brush: css">label {
+ float: left;
+ width: 30%;
+ text-align: right;
+ }
+
+ input {
+ float: right;
+ width: 65%;
+ }
+
+ label, input {
+ margin-bottom: 20px;
+ }
+
+ div {
+ clear: both;
+ margin: 10px;
+ }
+
+ body {
+ width: 400px;
+ margin: 0 auto;
+ }</pre>
+
+<p> </p>
+
+<pre class="brush: html">&lt;form&gt;
+ &lt;div&gt;
+ &lt;label for="date"&gt;Enter a date:&lt;/label&gt;
+ &lt;input id="date" type="date"&gt;
+ &lt;/div&gt;
+ &lt;div&gt;
+ &lt;label for="time"&gt;Enter a time:&lt;/label&gt;
+ &lt;input id="time" type="time"&gt;
+ &lt;/div&gt;
+ &lt;/form&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_example', '100%', 150) }}</p>
+
+<div class="note">
+<p><strong>Note</strong>: You can also see this running live as <a href="http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/html-css/forms-test.html">forms-test.html</a> on GitHub (see the <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/html-css/forms-test.html">source code</a> also).</p>
+</div>
+
+<p>If you view the example on a supporting browser like desktop/Android Chrome or iOS Safari, you'll see the special widgets/features in action as you try to input data. On a non-supporting platform such as Firefox or Internet Explorer, the inputs will just fallback to normal text inputs, so at least the user can still enter some information.</p>
+
+<p>Note: Of course, this may not be a great solution for your project's needs — the difference in visual presentation is not great, plus it is harder to guarantee the data will be entered in the format you want it in. For cross browser forms, It is probably better to rely on simple form elements, or selectively using advanced form elements only in supporting browsers, or using a library that provides decent cross browser form widgets, such as <a href="http://jqueryui.com/">jQuery UI</a> or <a href="https://bootstrap-datepicker.readthedocs.io/en/latest/">Bootstrap datepicker</a>.</p>
+
+<h4 id="CSS_fallback_behaviour">CSS fallback behaviour</h4>
+
+<p>CSS is arguably better at fallbacks than HTML. If a browser encounters a declaration or rule it doesn't understand, it just skips it completely without applying it or throwing an error. This might be frustrating for you and your users if such a mistake slips through to production code, but at least it means the whole site doesn't come crashing down because of one error, and if used cleverly you can use it to your advantage.</p>
+
+<p>Let's look at an example — a simple box styled with CSS, which has some styling provided by various CSS3 features:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14141/blingy-button.png" style="display: block; margin: 0 auto;"></p>
+
+<div class="note">
+<p><strong>Note</strong>: You can also see this example running live on GitHub as <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/html-css/button-with-fallback.html">button-with-fallback.html</a> (also see the <a href="http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/html-css/button-with-fallback.html">source code</a>).</p>
+</div>
+
+<p>The button has a number of declarations that style, but the two we are most interested in are as follows:</p>
+
+<pre class="brush: css">button {
+ ...
+
+ background-color: #ff0000;
+ background-color: rgba(255,0,0,1);
+ box-shadow: inset 1px 1px 3px rgba(255,255,255,0.4),
+ inset -1px -1px 3px rgba(0,0,0,0.4);
+}
+
+button:hover {
+ background-color: rgba(255,0,0,0.5);
+}
+
+button:active {
+ box-shadow: inset 1px 1px 3px rgba(0,0,0,0.4),
+ inset -1px -1px 3px rgba(255,255,255,0.4);
+}</pre>
+
+<p>Here we are providing an <a href="/en-US/docs/Web/CSS/color_value#rgba()">RGBA</a> {{cssxref("background-color")}} that changes opacity on hover to give the user a hint that the button is interactive, and some semi-transparent inset {{cssxref("box-shadow")}} shades to give the button a bit of texture and depth. The trouble is that RGBA colors and box shadows don't work in IE versions older than 9 — in older versions the background just wouldn't show up at all so the text would be unreadable, no good at all!</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14135/unreadable-button.png" style="display: block; margin: 0 auto;"></p>
+
+<p>To sort this out, we have added a second <code>background-color</code> declaration, which just specifies a hex color — this is supported way back in really old browsers, and acts as a fallback if the modern shiny features don't work. What happens is a browser visiting this page first applies the first <code>background-color</code> value; when it gets to the second <code>background-color</code> declaration, it will override the initial value with this value if it supports RGBA colors. If not, it will just ignore the entire declaration and move on.</p>
+
+<div class="note">
+<p><strong>Note</strong>: The same is true for other CSS features like <a href="/en-US/docs/Web/CSS/Media_Queries/Using_media_queries">media queries</a>, <code><a href="/en-US/docs/Web/CSS/@font-face">@font-face</a></code> and <code><a href="/en-US/docs/Web/CSS/@supports">@supports</a></code> blocks — if they are not supported, the browser just ignores them.</p>
+</div>
+
+<h4 id="IE_conditional_comments">IE conditional comments</h4>
+
+<p>IE conditional comments are a modified proprietary HTML comment syntax, which can be used to selectively apply HTML code to different versions of IE. This has proven to be a very effective mechanism for fixing cross browser bugs. The syntax looks like this:</p>
+
+<pre class="brush: html"><span class="c">&lt;!--[if lte IE 8]&gt;
+ &lt;script src="ie-fix.js"&gt;&lt;/script&gt;</span>
+ &lt;link href="ie-fix.css" rel="stylesheet" type="text/css"&gt;
+<span class="c">&lt;![endif]--&gt;</span></pre>
+
+<p>This block will apply the IE-specific CSS and JavaScript only if the browser viewing the page is IE 8 or older. <code>lte</code> means "less than or equal to", but you can also use lt, gt, gte, <code>!</code> for NOT, and other logical syntax.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Sitepoint's <span class="l-d-i l-pa2 t-bg-white"><a href="https://www.sitepoint.com/web-foundations/internet-explorer-conditional-comments/">Internet Explorer Conditional Comments</a> provides a useful beginner's tutorial/reference that explains the conditional comment syntax in detail.</span></p>
+</div>
+
+<p>As you can see, this is especially useful for applying code fixes to old versions of IE. The use case we mentioned earlier (making modern semantic elements styleable in old versions of IE) can be achieved easily using conditional comments, for example you could put something like this in your IE stylesheet:</p>
+
+<pre class="brush: css">aside, main, article, section, nav, figure, figcaption {
+ display: block;
+}</pre>
+
+<p>It isn't that simple, however — you also need to create a copy of each element you want to style in the DOM via JavaScript, for them to be styleable; this is a strange quirk, and we won't bore you with the details here. For example:</p>
+
+<pre class="brush: js">var asideElem = document.createElement('aside');
+ ...</pre>
+
+<p>This sounds like a pain to deal with, but fortunately there is a {{glossary("polyfill")}} available that does the necessary fixes for you, and more besides — see <a href="https://github.com/aFarkas/html5shiv">HTML5Shiv</a> for all the details (see <a href="https://github.com/aFarkas/html5shiv#installation">manual installation</a> for the simplest usage).</p>
+
+<h4 id="Selector_support">Selector support</h4>
+
+<p>Of course, no CSS features will apply at all if you don't use the right <a href="/en-US/docs/Learn/CSS/Introduction_to_CSS/Selectors">selectors</a> to select the element you want to style! If you just write a selector incorrectly so the styling isn't as expected in any browser, you'll just need to troubleshoot and work out what is wrong with your selector. We find that it is helpful to inspect the element you are trying to style using your browser's dev tools, then look at the DOM tree breadcrumb trail that DOM inspectors tend to provide to see if your selector makes sense compared to it.</p>
+
+<p>For example, in the Firefox dev tools, you get this kind of output at the bottom of the DOM inspector:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14139/dom-breadcrumb-trail.png" style="display: block; height: 24px; margin: 0px auto; width: 448px;"></p>
+
+<p>If for example you were trying to use this selector, you'd be able to see that it wouldn't select the input element as desired:</p>
+
+<pre class="brush: css">form &gt; #date</pre>
+
+<p>(The <code>date</code> form input isn't directly inside the <code>&lt;form&gt;</code>; you'd be better off using a general descendant selector instead of a child selector).</p>
+
+<p>However, another issue that appears in versions of IE older than 9 is that none of the newer selectors (mainly pseudo-classes and pseudo-elements like <code><a href="/en-US/docs/Web/CSS/:nth-of-type">:nth-of-type</a></code>, <code><a href="/en-US/docs/Web/CSS/:not">:not</a></code>, <code><a href="/en-US/docs/Web/CSS/::selection">::selection</a></code>, etc.) work. If you want to use these in your CSS and you need to support older IE versions, a good move is to use Keith Clark's <a href="http://selectivizr.com/">Selectivizr</a> library — this is a small JavaScript library that works on top of an existing JavaScript library like <a href="http://jquery.com/">jQuery</a> or <a href="http://mootools.net/">MooTools</a>.</p>
+
+<ol>
+ <li>To try this example, make a local copy of <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/html-css/selectivizr-example-start.html">selectivizr-example-start.html</a>. If you look at this running live, you'll see that it contains two paragraphs, one of which is styled. We've selected the paragraph with <code>p:first-child</code>, which won't work in old versions of IE.</li>
+ <li>Now download <a href="http://mootools.net/">MooTools</a> and <a href="http://selectivizr.com/">Selectivizr</a>, and save them in the same directory as your sample HTML.</li>
+ <li>Put the following code into the head of your HTML document, just before the opening <code>&lt;style&gt;</code> tag:
+ <pre class="brush: html">&lt;script type="text/javascript" src="MooTools-Core-1.6.0.js"&gt;&lt;/script&gt;
+ &lt;!--[if (gte IE 6)&amp;(lte IE 8)]&gt;
+ &lt;script type="text/javascript" src="selectivizr-min.js"&gt;&lt;/script&gt;
+ &lt;![endif]--&gt;</pre>
+ </li>
+</ol>
+
+<p>If you try running this in an old version of IE, it should work fine.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14137/new-selector-ie7.png" style="border-style: solid; border-width: 1px; display: block; height: 516px; margin: 0px auto; width: 771px;"></p>
+
+<h4 id="Handling_CSS_prefixes">Handling CSS prefixes</h4>
+
+<p>Another set of problems comes with CSS prefixes — these are a mechanism orignally used to allow browser vendors to implement their own version of a CSS (or JavaScript) feature while the technology is in an experimental state, so they can play with it and get it right without conflicting with other browser's implementations, or the final unprefixed implementations. So for example:</p>
+
+<ul>
+ <li>Mozilla uses <code>-moz-</code></li>
+ <li>Chrome/Opera/Safari use <code>-webkit-</code></li>
+ <li>Microsoft uses <code>-ms-</code></li>
+</ul>
+
+<p>Here's some examples:</p>
+
+<pre class="brush: css">-webkit-transform: rotate(90deg);
+
+background-image: -moz-linear-gradient(left,green,yellow);
+background-image: -webkit-gradient(linear,left center,right center,from(green),to(yellow));
+background-image: linear-gradient(to right,green,yellow);
+</pre>
+
+<p>The first line shows a {{cssxref("transform")}} property with a <code>-webkit-</code> prefix — this was needed to make transforms work in Chrome, etc. until the feature was finalized and such browsers added a prefix-free version of the property (at the time of writing, Chrome supported both versions).</p>
+
+<p>The last three lines show three different versions of the <code><a href="/en-US/docs/Web/CSS/linear-gradient">linear-gradient()</a></code> function, which is used to generate a linear gradient in the background of an element:</p>
+
+<ol>
+ <li>The first one has a <code>-moz-</code> prefix, and shows a slightly older version of the syntax (Firefox)</li>
+ <li>The second one has a <code>-webkit-</code> prefix, and shows an even older, proprietary version of the syntax (this is actually from a really old version of the WebKit engine).</li>
+ <li>The third one has no prefix, and shows the final version of the syntax (included in the <a href="https://drafts.csswg.org/css-images-3/#linear-gradients">CSS Image Values and Replaced Content Module Level 3 spec</a>, which defines this feature).</li>
+</ol>
+
+<p>Prefixed features were never supposed to be used in production websites — they are subject to change or removal without warning, and cause cross browser issues. This is particularly a problem when developers decide to only use say, the <code>-webkit- </code>version of a property — meaning that the site won't work in other browsers. This actually happens so much that other browsers have started to implement <code>-webkit-</code> prefixed versions of various CSS properties, so they will work with such code. Usage of prefixes by browser vendors has declined recently precisely because of these types of problems, but there are still some that need attention.</p>
+
+<p>If you insist on using prefixed features, make sure you use the right ones. You can look up what browsers require prefixes on MDN reference pages, and sites like <a href="http://caniuse.com/">caniuse.com</a>. If you are unsure, you can also find out by doing some testing directly in browsers.</p>
+
+<p>Try this simple example:</p>
+
+<ol>
+ <li>Open up google.com, or another site that has a prominent heading or other block level element.</li>
+ <li>Right/Cmd + click on the element in question and choose Inspect/Inspect element (or whatever the option is in your browser) — this should open up the dev tools in your browser, with the element highlighted in the DOM inspector.</li>
+ <li>Look for a feature you can use to select that element. For example, at the time of writing, the main Google logo had an ID of <code>hplogo</code>.</li>
+ <li>Store a reference to this element in a variable, for example:
+ <pre class="brush: js">var test = document.getElementById('hplogo');</pre>
+ </li>
+ <li>Now try to set a new value for the CSS property you are interested in on that element; you can do this using the <a href="/en-US/docs/Web/API/HTMLElement/style">style</a> property of the element, for example try typing these into the JavaScript console:
+ <pre class="brush: js">test.style.transform = 'rotate(90deg)'
+test.style.webkitTransform = 'rotate(90deg)'</pre>
+ </li>
+</ol>
+
+<p>As you start to type the property name representation after the second dot (note that in JavaScript, CSS property names are written in lower camel case, not hyphenated), the JavaScript console should begin to autocomplete the names of the properties that exist in the browser and match what you've written so far. This is useful for finding out what versions of the property are implemented in that browser.</p>
+
+<p>At the time of writing, both Firefox and Chrome implemented <code>-webkit-</code> prefixed and non-prefixed versions of {{cssxref("transform")}}!</p>
+
+<p>Once you've found out which prefixes you need to support, you should write them all out in your CSS, for example:</p>
+
+<pre class="brush: css">-ms-transform: rotate(90deg);
+-webkit-transform: rotate(90deg);
+transform: rotate(90deg);</pre>
+
+<p>This ensures that all browsers that support any of the above forms of the property can make the feature work. It is worth putting the non-prefixed version last, because that will be the most up-to-date version, which you'll want browsers to use if possible. If for example a browser implements both the <code>-webkit-</code> version and the non-prefixed version,  it will first apply the <code>-webkit-</code> version, then override it with the non-prefixed version. You want it to happen this way round, not the other way round.</p>
+
+<p>Of course, doing this for lots of different CSS rules can get really tedious. It is better to use an automation tool to do it for you. And such tools exist:</p>
+
+<p>The <a href="http://leaverou.github.io/prefixfree/">prefix-free JavaScript library</a> can be attached to a page, and will automatically detect what capabilities are possessed by browsers viewing the page and add prefixes as appropriate. It is really easy and convenient to use, although it does have some downsides (see the link above for details), and it is arguable that parsing every stylesheet in your site and add prefixes at run time can be a drain on the computer's processing power for a large site.</p>
+
+<p>Another solution is to add prefixes automatically during development, and this (and other things besides) can be done using tools like <a href="https://github.com/postcss/autoprefixer">Autoprefixer</a> and <a href="http://postcss.org/">PostCSS</a>. These tools can be used in a variety of ways, for example Autoprefixer has an <a href="http://autoprefixer.github.io/">online version</a> that allows you to enter your non-prefixed CSS on the left, and gives you a prefix-added version on the right. You can choose which browsers you want to make sure you support using the notation outlined in <a href="https://github.com/postcss/autoprefixer#options">Autoprefixer options</a>; also see <a href="https://github.com/ai/browserslist#queries">Browserslist queries</a>, which this is based on, for more detail. As an example, the following query will select the last 2 versions of all major browsers and versions of IE above 9.</p>
+
+<pre>last 2 versions, ie &gt; 9</pre>
+
+<p>Autoprefixer can also be used in other, more convenient ways — see <a href="https://github.com/postcss/autoprefixer#usage">Autoprefixer usage</a>. For example you can use it with a task runner/build tool such as <a href="http://gulpjs.com/">Gulp</a> or <a href="https://webpack.github.io/">Webpack</a> to automatically add prefixes once development has been done. (Explaining how these work is somewhat beyond the scope of this article.)</p>
+
+<p>You can also use a plugin for a text editor such as Atom or Sublime text. For example, in Atom:</p>
+
+<ol>
+ <li>You can install it by going to <em>Preferences &gt; Install</em>, searching for <em>Autoprefixer</em>, then hitting install.</li>
+ <li>You can set a browser query by pressing the Autoprefixer <em>Settings</em> button and entering the query in the text field in the <em>Settings</em> section on the page.</li>
+ <li>In your code, you can select sections of CSS you want to add prefixes to, open the command pallette (<em>Cmd/Ctrl + Shift + P</em>), then type in Autoprefixer and select the Autoprefixer result that autocompletes.</li>
+</ol>
+
+<p>As an example, we entered the following code:</p>
+
+<pre class="brush: css">body {
+ display: flex;
+}</pre>
+
+<p>We highlighted it and ran the Autoprefixer command, and it replaced it with this:</p>
+
+<pre class="brush: css">body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+}</pre>
+
+<h3 id="Layout_issues">Layout issues</h3>
+
+<p>Another problem that might come up is differences in layouts between browsers. Historically this used to be much more of a problem, but recently, with modern browsers tending to support CSS more consistently, layout issues tend to be more commonly associated with:</p>
+
+<ul>
+ <li>Lack of (or differences in) support for modern layout features.</li>
+ <li>Layouts not looking good in mobile browsers (i.e. responsive design problems).</li>
+</ul>
+
+<div class="note">
+<p><strong>Note</strong>: Historically web developers used to use CSS files called resets, which removed all the default browser styling applied to HTML, and then applied their own styles for everything over the top — this was done to make styling on a project more consistent, and reduce possible cross browser issues, especially for things like layout. However, it has more recently been seen as overkill. The best equivalent we have in modern times is <a href="https://necolas.github.io/normalize.css/">normalize.css</a>, a neat bit of CSS that builds slightly on the default browser styling to make things more consistent and fix some layout issues. You are advised to apply normalize.css to all your HTML pages.</p>
+</div>
+
+<div class="note">
+<p><strong>Note</strong>:  When trying to track down a tricky layout issue, a good technique is to add a brightly colored {{cssxref("outline")}} to the offending element, or all the elements nearby. This makes it a lot easier to see where everything is placed. See <a href="http://www.otsukare.info/2016/10/05/debugging-css" rel="bookmark" title="Permalink to Debug your CSS with outline visualizations.">Debug your CSS with outline visualizations</a> for more details.</p>
+</div>
+
+<h4 id="Support_for_new_layout_features">Support for new layout features</h4>
+
+<p>Much of the layout work on the web today is done using <a href="/en-US/docs/Learn/CSS/CSS_layout/Floats">floats</a> — this is because floats are well-supported (way back to IE4, albeit with a number of bugs that would also need to be investigated if you were to try to support IE that far back). However, they are not really meant for layout purposes — using floats the way we do is really a hack — and they do have some serious limitations (e.g. see <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox#Why_Flexbox">Why Flexbox?</a>)</p>
+
+<p>More recently, dedicated layout mechanisms have appeared, like <a href="/en-US/docs/Learn/CSS/CSS_layout/Flexbox">Flexbox</a> and <a href="/en-US/docs/Learn/CSS/CSS_layout/Grids#Native_CSS_Grids_with_Grid_Layout">CSS Grids</a>, which make common layout tasks far easier and remove such shortcomings. These however are not as well-supported in browsers:</p>
+
+<ul>
+ <li>CSS grids are very new; at the time of writing, they were only <a href="http://gridbyexample.com/browsers/">supported</a> in the very newest versions of modern browsers.</li>
+ <li>Flexbox is <a href="/en-US/docs/Learn/CSS/CSS_layout/Flexbox#Cross_browser_compatibility">well-supported</a> in modern browsers, but provides problems in older browsers. IE 9 doesn't support it at all, and IE 10 and old versions of iOS/desktop Safari respectively support incompatible old versions of the flexbox spec. This results in some interesting browser prefix juggling if you want to try to use flexbox across all these browsers (see <a href="https://dev.opera.com/articles/advanced-cross-browser-flexbox/">Advanced Cross-Browser Flexbox</a> to get an idea).</li>
+</ul>
+
+<p>Layout features aren't as easy to provide graceful fallbacks for than simple colors, shadows, or gradients. If layout properties are ignored, your entire design will likely fall to pieces. Because of this, you need to use feature detection to detect whether visiting browsers support those layout features, and selectively apply different layouts depending on the result (we will cover feature detection in detail in a later article).</p>
+
+<p>For example, you could apply a flexbox layout to modern browsers, then instead apply a floated layout to older browsers that don't support flexbox.</p>
+
+<div class="note">
+<p><strong>Note</strong>: There is a fairly new feature in CSS called <code><a href="/en-US/docs/Web/CSS/@supports">@supports</a></code>, which allows you to implement native feature detection tests.</p>
+</div>
+
+<h4 id="Responsive_design_problems">Responsive design problems</h4>
+
+<p>Responsive design is the practice of creating web layouts that change to suit different device form factors — for example different screen widths, orientations (portrait or landscape), or resolutions. A desktop layout for example will look terrible when viewed on a mobile device, so you need to provide a suitable mobile layout using <a href="/en-US/docs/Web/CSS/Media_Queries">media queries</a>, and make sure it is applied correctly using <a href="/en-US/docs/Mozilla/Mobile/Viewport_meta_tag">viewport</a>. You can find a detailed account of such practices in <a href="/en-US/docs/Web/Apps/Progressive/Responsive/responsive_design_building_blocks">The building blocks of responsive design</a>.</p>
+
+<p>Resolution is a big issue too — for example, mobile devices are less likely to need big heavy images than desktop computers, and are more likely to have slower internet connections and possibly even expensive data plans that make wasted bandwidth more of a problem. In addition, different devices can have a range of different resolutions, meaning that smaller images could appear pixellated. There are a number of techniques that allow you to work around such problems, from simple <a href="/en-US/Apps/Progressive/Responsive/Mobile_first">mobile first media queries</a>, to more complex <a href="/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images#Resolution_switching_Different_sizes">responsive image techniques</a>.</p>
+
+<p>Another difficulty that can present problems is browser support for the features that make the above techniques possible. media queries are not supported in IE 8 or less, so if you want to use a mobile first layout and have the desktop layout then apply to old IE versions, you'll have to apply a media query {{glossary("polyfill")}} to your page, like <a href="https://code.google.com/archive/p/css3-mediaqueries-js/">css3-mediaqueries-js</a>, or <a href="https://github.com/scottjehl/Respond">Respond.js</a>.</p>
+
+<h2 id="Finding_help">Finding help</h2>
+
+<p>There are many other issues you'll encounter with HTML and CSS; the most important thing to know really is how to find answers online.</p>
+
+<p>Among the best sources of support information are the Mozilla Developer Network (that's where you are now!), <a href="http://stackoverflow.com/">stackoverflow.com</a>, and <a href="http://caniuse.com/">caniuse.com</a>.</p>
+
+<p>To use the Mozilla Developer Network (MDN), most people do a search engine search of the technology they are trying to find information on, plus the term "mdn", for example "mdn HTML5 video". MDN contains several useful types of content:</p>
+
+<ul>
+ <li>Reference material with browser support information for client-side web technologies, e.g. the <a href="/en-US/docs/Web/HTML/Element/video">&lt;video&gt; reference page</a>.</li>
+ <li>Other supporting reference material, e.g. <a href="/en-US/docs/Web/HTML/Supported_media_formats">Media formats supported by the HTML audio and video elements</a>.</li>
+ <li>Useful tutorials that solve specific problems, for example <a href="/en-US/docs/Web/Apps/Fundamentals/Audio_and_video_delivery/cross_browser_video_player">Creating a cross-browser video player</a>.</li>
+</ul>
+
+<p><a href="http://caniuse.com/">caniuse.com</a> provides support information, along with a few useful external resource links. For example, see <a href="http://caniuse.com/#search=video">http://caniuse.com/#search=video</a> (you just have to enter the feature you are searching for into the text box).</p>
+
+<p><a href="http://stackoverflow.com/">stackoverflow.com</a> (SO) is a forum site where you can ask questions and have fellow developers share their solutions, look up previous posts, and help other developers. You are advised to look and see if there is an answer to your question already, before posting a new question. For example, we searched for "cross browser html5 video" on SO, and very quickly came up with <a class="question-hyperlink" href="http://stackoverflow.com/questions/16212510/html5-video-with-full-cross-browser-compatibility">HTML5 Video with full cross browser compatibility</a>.</p>
+
+<p>Aside from that, try searching your favourite search engine for an answer to your problem. It is often useful to search for specific error messages if you have them — other developers will be likely to have had the same problems as you.</p>
+
+<h2 id="Summary">Summary</h2>
+
+<p>Now you should be familiar with the main types of cross browser HTML and CSS problems that you'll meet in web development, and how to go about fixing them.</p>
+
+<p>{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies","Learn/Tools_and_testing/Cross_browser_testing/JavaScript", "Learn/Tools_and_testing/Cross_browser_testing")}}</p>
+
+<p> </p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">Introduction to cross browser testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies">Strategies for carrying out testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS">Handling common HTML and CSS problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript">Handling common JavaScript problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility">Handling common accessibility problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection">Implementing feature detection</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing">Introduction to automated testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Setting up your own test automation environment</a></li>
+</ul>
+
+<p> </p>
diff --git a/files/ru/learn/tools_and_testing/cross_browser_testing/index.html b/files/ru/learn/tools_and_testing/cross_browser_testing/index.html
new file mode 100644
index 0000000000..bdb268acb6
--- /dev/null
+++ b/files/ru/learn/tools_and_testing/cross_browser_testing/index.html
@@ -0,0 +1,34 @@
+---
+title: Кросс-браузерное тестирование
+slug: Learn/Tools_and_testing/Cross_browser_testing
+translation_of: Learn/Tools_and_testing/Cross_browser_testing
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">Этот модуль фокусируется на тестировании веб-проектов в разных браузерах. Мы рассматриваем идентификацию вашей целевой аудитории (например о каких пользователях, браузерах и устройствах вам больше всего нужно беспокоиться?), Как пройти тестирование, основные проблемы, с которыми вам придется столкнуться с разными типами кода и способы смягчения их, какие инструменты наиболее полезны для помощи в тестировании и устранении проблем, а также о том, как использовать автоматизацию для ускорения тестирования.</p>
+
+<h2 id="Предпосылки">Предпосылки</h2>
+
+<p>Сначала вы должны изучить основы  <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>,<a href="/en-US/docs/Learn/JavaScript">JavaScript</a> языков  прежде чем пытаться использовать инструменты,  описанные здесь.</p>
+
+<h2 id="Руководства">Руководства</h2>
+
+<dl>
+ <dt><a href="/ru/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">Введение в кросс-браузерное тестирование</a></dt>
+ <dd>Этот модуль начинается с обзора темы кросс-браузерного тестирования и отвечает на такие вопросы, как «что такое кросс-браузерное тестирование?», «с какими наиболее распространенными типами проблем вы столкнетесь?» и «каковы основные подходы к тестированию, выявлению и устранению проблем?"</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies">Стратегии проведения тестирования</a></dt>
+ <dd>Затем мы углубимся в тестирование, рассматривая целевую аудиторию (например какие браузеры, устройства и другие сегменты должны проверяться), стратегии тестирования низкого уровня (получить себе множество устройств и некоторых виртуальных машин и делать специальные тесты, когда это необходимо), стратегии более высоких технологий (автоматизация, использование специальных тестовых приложений) и тестирование с помощью групп пользователей.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS">Рассмотрим общие проблемы HTML и CSS</a></dt>
+ <dd>С набором сценариев, мы теперь рассмотрим общие кроссбраузерные проблемы, которые вы найдете в коде HTML и CSS, и какие инструменты можно использовать для предотвращения возникновения проблем или устранения возникающих проблем. Это включает в себя листинг кода, передачу префиксов CSS, использование инструментов браузера dev tools для устранения проблем, использование полифилов для добавления поддержки в браузеры, решение проблем с отзывчивым дизайном и многое другое.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript">Рассмотрим общие проблемы JavaScript</a></dt>
+ <dd>Теперь мы рассмотрим общие проблемы JavaScript в браузере и как их исправить. Это включает в себя информацию об использовании инструментов браузера для отслеживания и устранения неполадок, используя полифилы и библиотеки для решения проблем, получения современных функций JavaScript, работающих в старых браузерах, и многое другое.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility">Рассмотрим общие проблемы доступности</a></dt>
+ <dd>Затем мы обращаем наше внимание на доступность, предоставляя информацию о распространенных проблемах, как сделать простое тестирование, и как использовать инструменты аудита/автоматизации для поиска проблем доступности.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection">Внедрение свойства обнаружения</a></dt>
+ <dd>Свойство выявления включает в себя разработку того, поддерживает ли браузер определенный блок кода, и работает ли другой код, зависящий от того, делает он (или нет), чтобы браузер всегда мог обеспечить рабочую силу, а также сбои / ошибки в некоторых браузерах. В этой статье описывается, как написать собственную простую функцию выявления, как использовать библиотеку для ускорения реализации и встроенные функции для обнаружения функций, такие как  <code>@supports</code>.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing">Введение в автоматизированное тестирование</a></dt>
+ <dd>Введение в автоматизированное тестирование<br>
+ Вручную запускать тесты на нескольких браузерах и устройствах, несколько раз в день, может стать утомительным и трудоемким. Чтобы эффективно справляться с этим, вы должны ознакомиться с инструментами автоматизации. В этой статье мы рассмотрим, что доступно, как использовать задачи, а также основы использования коммерческих приложений для автоматизации тестирования браузера, таких как Sauce Labs и Browser Stack.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Настройка собственной среды автоматизации тестирования</a></dt>
+ <dd>В этой статье мы научим вас, как установить свою собственную среду автоматизации и запустить собственные тесты с помощью Selenium / WebDriver и библиотеки тестирования, такой как selenium-webdriver для Node. Мы также рассмотрим, как интегрировать локальную тестовую среду с коммерческими приложениями, такими как те, которые обсуждались в предыдущей статье.</dd>
+</dl>
diff --git a/files/ru/learn/tools_and_testing/cross_browser_testing/introduction/index.html b/files/ru/learn/tools_and_testing/cross_browser_testing/introduction/index.html
new file mode 100644
index 0000000000..96d31f156c
--- /dev/null
+++ b/files/ru/learn/tools_and_testing/cross_browser_testing/introduction/index.html
@@ -0,0 +1,203 @@
+---
+title: Введение в кросс-браузерное тестирование
+slug: Learn/Tools_and_testing/Cross_browser_testing/Introduction
+tags:
+ - тестирование
+translation_of: Learn/Tools_and_testing/Cross_browser_testing/Introduction
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies", "Learn/Tools_and_testing/Cross_browser_testing")}}</div>
+
+<p class="summary">Эта статья начинает модуль с обзора темы кросс-браузерного тестирования, отвечая на такие вопросы как "что такое кросс-браузерное тестирование?", "с какими распространенными проблемами можно столкнуться?" и "какие основные подходы для тестирования, обнаружения и исправления проблем существуют?"</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые условия:</th>
+ <td>Знакомство с основами <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, и <a href="/en-US/docs/Learn/JavaScript">JavaScript</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Улучшить понимание идей кроссбраузерного тестирования.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Что_такое_кросс-браузерное_тестирование">Что такое кросс-браузерное тестирование?</h2>
+
+<p>Кросс-браузерное тестирование - это практика обеспечения уверенности в том, что веб-сайты и веб-приложения, которые вы создаете, работают в приемлемом количестве браузеров. Обязанность веб-разработчика быть уверенным, что проект работает не только у вас, а у всех ваших пользователей, независимо от браузера, устройства, или других вспомогательных инструментов, которые они используют. Вы должны думать о:</p>
+
+<ul>
+ <li>Других браузерах. Не тех нескольких, которые вы регулярно используете, а о довольно старых, которые некоторые люди могут использовать до сих пор, и которые не поддерживают современные возможности CSS и JavaScript.</li>
+ <li>Разных устройствах с разными возможностями, начиная от последних лучших планшетов, смартфонов и "умных" телевизоров, до дешевых устройств и самых старых смартфонов, в которых браузеры могут работать с ограниченными возможностями.</li>
+ <li>Людях с инвалидностью, которые используют Web с помощью вспомогательных технологий, таких как скринридеры, или не используют мышь (некоторые используют только клавиатуру).</li>
+</ul>
+
+<p>Поймите, что вы - не ваши пользователи — если ваш сайт работает на Macbook Pro или Galaxy Nexus, это не значит, что он будет работать так для всех пользователей —  нужно сделать много тестов!</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Статья <a href="https://hacks.mozilla.org/2016/07/make-the-web-work-for-everyone/">сделаем веб доступным для всех</a> предоставляет более полезную информацию о различных браузерах, которые используют люди, их доле рынка и связанных с этим проблемах совместимости браузеров.</p>
+</div>
+
+<p>Мы должны поговорить немного о терминологии. Для начала, когда мы говорим о сайтах, "работающих кросс-браузерно", на самом деле мы говорим о том, что они должны обеспечивать приемлимое удобство использования в разных браузерах. Это нормально, если сайт выглядит немного по-разному в разных браузерах, главное он должен обеспечивать полную функциональность.В современных браузерах вы можете сделать что-то анимированным или использовать 3D, тогда как в старых браузерах вы можете лишь показать плоскую картинку, предоставляющую ту же информацию. Если владелец сайта доволен, вы сделали свое дело.</p>
+
+<p>С другой стороны, плохо, когда сайт полноценно работает для обычных людей, но может быть совершенно недоступен для людей, имеющих проблемы со зрением, т.к. их приложения для чтения экрана не могут распознать информацию на сайте.</p>
+
+<p>Когда мы говорим "приемлимое количество браузеров", мы не говорим, что это должно быть 100% всех браузеров в мире — это почти невозможно. Вы можете собрать информацию о том, какими браузеры и устройства используют ваши пользователи (это мы обсудим во второй статье — см. <a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies#Gotta_test_%27em_all">Gotta test 'em all?</a>), но это ничего не гарантирует. Как веб-разработчик, вы должны определить для себя несколько браузеров и устройств, на которых код должен работать полностью, но кроме этого, вы должны писать код так, чтобы и другие браузеры были способны максимально использовать ваш сайт (defensive coding). Это одна из самых больших проблем веб-разработки.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Мы разберем defensive coding позже в этом модуле.</p>
+</div>
+
+<h2 id="Почему_возникают_кросс-браузерные_проблемы">Почему возникают кросс-браузерные проблемы?</h2>
+
+<p>Есть множество причин, почему возникают кросс-браузерные проблемы, и, заметьте, что сейчас мы говорим о проблемах, при которых некоторые вещи ведут себя по-разномув разных браузерах / устройствах / настройках просмотра. Прежде чем вы столкнетесь с проблемами браузера, вы должны исправить все ошибки в коде (см. <a href="/ru/docs/Learn/HTML/Введение_в_HTML/Debugging_HTML">Отладка HTML</a>, <a href="/ru/docs/Learn/CSS/Introduction_to_CSS/Отладка_CSS">Отладка CSS</a>, and <a href="/ru/docs/Learn/JavaScript/Первые_шаги/Что_пошло_не_так">Что пошло не так? Устранение ошибок JavaScript</a> из предыдущего раздела).</p>
+
+<p>Кросс-браузерные проблемы возникают потому-что:</p>
+
+<ul>
+ <li>иногда браузеры содержат баги, или реализуют возможности по-разному. В настоящее время это не такая частая проблема, но когда IE4 и Netscape 4 конкурировали за право быть доминирующим браузером в 90-е, компании-разработчики браузеров умышленно реализовывали возможности по-своему в попытке получить конкурентное преимущество, что делало жизнь веб-разработчикам адом. Сейчас же браузеры гораздо жестче соблюдают стандарты, но различия и баги все же иногда возникают.</li>
+ <li>браузеры имеют разную степень поддержи современных технологий. Это неизбежно, когда вы имеете дело с новейшими функциями, которые браузеры только начинают осваивать, или если вы вынуждены поддерживать очень старые браузеры, которые более не дорабатываются или которые могли быть заморожены (то есть в них не добавляют новый функционал) задолго до того, как придумали новые возможности. Например, если вы хотите использовать передовые возможности JavaScript на вашем сайте, то они могут не работать в старых браузерах. Если вам нужна поддержка старых браузеров, вы можете конвертировать ваш код под старый синтаксис, используя специальные компиляторы.</li>
+ <li>некоторые устройства могут иметь ограничения, из-за которых сайт работает медленно или отображается неверно. Например, если сайт был спроектирован для просмотра на десктопных устройствах, он возможно будет выглядеть мелко и трудночитаемо на мобильных устройствах. Если ваш сайт содержит множество больших анимаций, это может быть хорошо на высокопроизводительных планшетах, но может быть вялым или резким на устройствах меньшей производительности.</li>
+</ul>
+
+<p>а также другие причины.</p>
+
+<p>В статьях далее, мы выясним основные проблемы кросс-браузерности и посмотрим на их решения.</p>
+
+<h2 id="Инструменты_для_кросс-браузерного_тестирования">Инструменты для кросс-браузерного тестирования</h2>
+
+<p>Может показаться, что тестирование - это затратно и страшно, но это важно — вы должны спланировать и убедиться, что вы делаете тесты в нужных местах, чтобы не было неожиданных проблем. Если вы работаете над большим проектом, вы должны тестировать его регулярно, чтобы убеждаться, что новые возможности работают корректно для вашей целевой аудитории, и что новый код не ломает старый функционал.</p>
+
+<p>Если вы будете тестировать в конце проекта, любые не обнаруженные баги будут гораздо более затратными по времени для исправления, если бы вы их тестировали и обнаруживали своевременно.</p>
+
+<p>Рабочий процесс над тестированием и исправлением ошибок может быть разбит на следующие четыре фазы (очень грубое разделение - у разных людей этот процесс может очень сильно отличаться):</p>
+
+<p><strong>Начальное планирование &gt; Разработка &gt; Тестирование &gt; Исправление ошибок</strong></p>
+
+<p>Шаги 2-4 будут повторяться до тех пор, пока не будут реализованы все возможности. Мы рассмотрим различные элементы процесса тестирования более детально в следующих статьях, но пока давайте соберем то, что может происходить на каждом этапе.</p>
+
+<h3 id="Начальное_планирование">Начальное планирование</h3>
+
+<p>На этом этапе у вас, возможно, будет несколько встреч с владельцем/заказчиком сайта (это может быть ваш босс или кто-то из другой компании, для кого вы пишете сайт), чтобы точно определить, каким должен быть сайт - какой контент и функционал должен быть на сайте, как сайт должен выглядеть и т.д. На этом этапе вы также хотите знать сколько времени у вас есть на разработку и цену работы. Не хочется углубляться в детали, но такое планирование  оказывает большое влияние на кросс-браузерное тестирование.</p>
+
+<p>Once you've got an idea of the required featureset, and what technologies you will likely build these features with, you should start exploring the target audience — what browsers, devices, etc. will the target audience for this site be using? The client might already have data about this from previous research they've done, e.g. from other web sites they own, or from previous versions of the web site you are now working on. If not, you will be able to get a good idea by looking at other sources, such as usage stats for competitors, or countries the site will be serving. You can also use a bit of intuition.</p>
+
+<p>So for example, you might be building an e-commerce site that serves customers in North America. The site should work entirely in the last few versions of the most popular desktop and mobile (iOS, Android, Windows phone) browsers — this should include Chrome (and Opera as it is based on the same rendering engine as Chrome), Firefox, IE/Edge, and Safari. It should also provide an acceptable experience on IE 8 and 9, and be accessible with WCAG AA compliance.</p>
+
+<p>Now you know your target testing platforms, you should go back and review the required featureset and what technologies you are going to use. For example, if the e-commerce site owner wants a WebGL-powered 3D tour of each product built into the product pages, they will need to accept that this just won't work in IE versions before 11. You'd have to agree to provide a version of the site without this feature to users of older IE versions.</p>
+
+<p>You should compile a list of the potential problem areas.</p>
+
+<div class="note">
+<p><strong>Note</strong>: You can find browser support information for technologies by looking up the different features on MDN — the site you're on! You should also consult <a href="http://caniuse.com/">caniuse.com</a>, for some further useful details.</p>
+</div>
+
+<p>Once you've agreed on these details, you can go ahead and start developing the site.</p>
+
+<h3 id="Development">Development</h3>
+
+<p>Now on to the development of the site. You should split the different parts of the development into modules, for example you might split the different site areas up — home page, product page, shopping cart, payment workflow, etc. You might then further subdivide these — implement common site header and footer, implement product page detail view, implement persistent shopping cart widget, etc.</p>
+
+<p>There are multiple general strategies to cross browser development, for example:</p>
+
+<ul>
+ <li>Get all the functionality working as closely as possible in all target browsers. This may involve writing different code paths that reproduce functionality in different ways aimed at different browsers, or using a {{glossary("Polyfill")}} to mimic any missing support using JavaScript or other technologies, or using a library that allows you to write a single bit of code and then does different things in the background depending on what the browser supports.</li>
+ <li>Accept that some things aren't going to work the same on all browsers, and provide different (acceptable) solutions in browsers that don't support the full functionality. Sometimes this is inevitable due to device constraints — a cinema widescreen isn't going to give the same visual experience as a 4" mobile screen, regardless of how you program your site.</li>
+ <li>Accept that your site just isn't going to work in some older browsers, and move on. This is OK, provided your client/userbase is OK with it.</li>
+</ul>
+
+<p>Normally your development will involve a combination of the above three approaches. The most important thing is that you test each small part before committing it — don't leave all the testing till the end!</p>
+
+<h3 id="Testingdiscovery">Testing/discovery</h3>
+
+<p>After each implementation phase, you will need to test the new functionality. To start with, you should make sure there are no general issues with your code that are stopping your feature from working:</p>
+
+<ol>
+ <li>Test it in a couple of stable browsers on your system, like Firefox, Safari, Chrome, or IE/Edge.</li>
+ <li>Do some low fi accessibility testing, such as trying to use your site with only the keyboard, or using your site via a screen reader to see if it is navigable.</li>
+ <li>Test on a mobile platform, such as Android or iOS.</li>
+</ol>
+
+<p>At this point, fix any problems you find with your new code.</p>
+
+<p>Next, you should try expanding your list of test browsers to a full list of target audience browsers and start concentrating on weeding out cross browser issues (see the next article for more information on <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies#Gotta_test_%27em_all">determining your target browsers</a>). For example:</p>
+
+<ul>
+ <li>Try to test the latest change on all the modern desktop browsers you can — including Firefox, Chrome, Opera, IE, Edge, and Safari on desktop (Mac, Windows, and Linux, ideally).</li>
+ <li>Test it in common phone and tablet browsers (e.g. iOS Safari on iPhone/iPad, Chrome and Firefox on iPhone/iPad/Android),</li>
+ <li>Also do tests in any other browsers you have included inside your target list.</li>
+</ul>
+
+<p>The most low fi option is to just do all the testing you can by yourself (pulling in team mates to help out if you are working in a  team). You should try to test it on real physical devices where possible.</p>
+
+<p>If you haven't got the means to test all those different browser, operating system, and device combinations on physical hardware, you can also make use of emulators (emulate a device using software on your desktop computer) and virtual machines (software that allows you to emulate multiple operating system/software combinations on your desktop computer). This is a very popular choice, especially in some circumstances — for example, Windows doesn't let you have multiple versions of Windows installed simulataneously on the same machine, so using multiple virtual machines is often the only option here.</p>
+
+<p>Another option is user groups — using a group of people outside your development team to test your site. This could be a group of friends or family, a group of other employees, a class at a local university, or a professional user testing setup, where people are paid to test out your site and provide results.</p>
+
+<p>Finally, you can get smarter with your testing using auditing or automation tools; this is a sensible choice as your projects get bigger, as doing all this testing by hand can start to take a really long time. You can set up your own testing automation system (<a href="http://www.seleniumhq.org/">Selenium</a> being the popular app of choice) that could for example load your site in a number of different browsers, and:</p>
+
+<ul>
+ <li>see if a button click causes something to happen successfully (like for example, a map displaying), displaying the results once the tests are completed</li>
+ <li>take a screenshot of each, allowing you to see if a layout is consistent across the different browsers.</li>
+</ul>
+
+<p>You can also go further than this, if wished. There are commercial tools available such as <a href="https://saucelabs.com/">Sauce Labs</a>, <a href="https://www.browserstack.com/">Browser Stack</a>, <a href="https://www.lambdatest.com/">LambdaTest</a>, <a href="https://testingbot.com">TestingBot</a>, and <a href="https://crossbrowsertesting.com">CrossBrowserTesting</a> that do this kind of thing for you, without you having to worry about the setup, if you wish to invest some money in your testing. It is also possible to set up an environment that automatically runs tests for you, and then only lets you check in your changes to the central code repository if the tests still pass.</p>
+
+<h4 id="Testing_on_prerelease_browsers">Testing on prerelease browsers</h4>
+
+<p>It is often a good idea to test on prerelease versions of browsers; see the following links:</p>
+
+<ul>
+ <li><a href="https://www.mozilla.org/en-US/firefox/developer/">Firefox Developer Edition</a></li>
+ <li><a href="https://insider.windows.com/">Edge Insider Preview</a></li>
+ <li><a href="https://developer.apple.com/safari/technology-preview/">Safari Technology Preview</a></li>
+ <li><a href="https://www.google.com/chrome/browser/canary.html">Chrome Canary</a></li>
+ <li><a href="http://www.opera.com/computer/beta">Opera Developer</a></li>
+</ul>
+
+<p>This is especially prevalent if you are using very new technologies in your site, and you want to test against the latest implementations, or if you are coming across a bug in the latest release version of a browser, and you want to see if the browser's developers have fixed the bug in a newer version.</p>
+
+<h3 id="Fixesiteration">Fixes/iteration</h3>
+
+<p>Once you've discovered a bug, you need to try to fix it.</p>
+
+<p>The first thing to do is to narrow down where the bug occurs as much as possible. Get as much information as you can from the person reporting the bug — what platform(s), device(s), browser version(s), etc. Try it on similar configurations (e.g. the same browser version on different desktop platforms, or a few different versions of the same browser on the same platform) to see how widely the bug persists.</p>
+
+<p>It might not be your fault — if a bug exists in a browser, then hopefully the vendor will rapidly fix it. It might have already been fixed — for example if a bug is present in Firefox release 49, but it is no longer there in Firefox Nightly (version 52), then they have fixed it. If it is not fixed, then you may want to file a bug (see {{anch("Reporting bugs")}}, below).</p>
+
+<p>If it is your fault, you need to fix it! Finding out the cause of the bug involves the same strategy as any web development bug (again, see <a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/Debugging_HTML">Debugging HTML</a>, <a href="/en-US/docs/Learn/CSS/Introduction_to_CSS/Debugging_CSS">Debugging CSS</a>, and <a href="/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong">What went wrong? Troubleshooting JavaScript</a>). Once you've discovered what is causing your bug, you need to decide how to work around it in the particular browser it is causing problems in — you can't just change the problem code outright, as this may break the code in other browsers. The general approach is usually to fork the code in some way, for example use JavaScript feature detection code to detect situations in which a problem feature doesn't work, and run some different code in those cases that does work.</p>
+
+<p>Once a fix has been made, you'll want to repeat your testing process to make sure your fix is working OK, and hasn't caused the site to break in other places or in other browsers.</p>
+
+<h2 id="Reporting_bugs">Reporting bugs</h2>
+
+<p>Just to reiterate on what was said above, if you discover bugs in browsers, you should report them:</p>
+
+<ul>
+ <li><a href="https://bugzilla.mozilla.org/">Firefox Bugzilla</a></li>
+ <li><a href="https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/">EdgeHTML issue tracker</a></li>
+ <li><a href="https://bugs.webkit.org/">Safari</a></li>
+ <li><a href="https://bugs.chromium.org/p/chromium/issues/list">Chrome</a></li>
+ <li><a href="https://bugs.opera.com/wizard/desktop">Opera</a></li>
+</ul>
+
+<h2 id="Summary">Summary</h2>
+
+<p>This article should have given you a high-level understanding of the most important concepts you need to know about cross browser testing. Armed with this knowledge, you are now ready to move on and start learning about Cross browser testing strategies.</p>
+
+<p>{{NextMenu("Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies", "Learn/Tools_and_testing/Cross_browser_testing")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">Introduction to cross browser testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies">Strategies for carrying out testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS">Handling common HTML and CSS problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript">Handling common JavaScript problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility">Handling common accessibility problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection">Implementing feature detection</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing">Introduction to automated testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Setting up your own test automation environment</a></li>
+</ul>