diff options
| author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
|---|---|---|
| committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
| commit | 074785cea106179cb3305637055ab0a009ca74f2 (patch) | |
| tree | e6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/learn/tools_and_testing | |
| parent | da78a9e329e272dedb2400b79a3bdeebff387d47 (diff) | |
| download | translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2 translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip | |
initial commit
Diffstat (limited to 'files/ru/learn/tools_and_testing')
8 files changed, 1799 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><script src="html5shiv.min.js"></script></pre> + </li> + <li>Посмотрите ваши примеры CSS-файлов - вы увидите, что <code>basic-styling.css</code> обрабатывает все стили, которые мы хотим дать каждому браузеру, тогда как два других CSS-файла содержат CSS, который мы хотим выборочно применять к браузеру в зависимости от их уровни поддержки. Вы можете посмотреть на различные эффекты этих двух файлов, вручную изменив CSS-файл, на который ссылается второй элемент {{htmlelement("link")}}, но давайте вместо этого реализуем некоторый JavaScript, чтобы автоматически заменять их при необходимости.</li> + <li>Сначала удалите содержимое атрибута <code>href</code> второго элемента <code><link></code> . Мы будем заполнять это динамически позже.</li> + <li>Затем добавьте элемент <code><script></script></code> внизу вашего контекста (непосредственно перед закрывающим тегом <code></body></code>).</li> + <li>Дайте ему следующее содержание: + <pre class="brush: js">const conditional = document.querySelector('.conditional'); +const testElem = document.createElement('div'); +if (testElem.style.flex !== undefined && testElem.style.flexFlow !== undefined) { + conditional.setAttribute('href', 'flex-layout.css'); +} else { + conditional.setAttribute('href', 'float-layout.css'); +}</pre> + </li> +</ol> + +<p>Здесь мы берем ссылку на второй элемент <code><link></code> и создаем элемент <code><div></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><input></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"><<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>></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"><link href="modernizr-css.css" rel="stylesheet"></pre> + </li> + <li>Над этим элементом <code><link></code> добавьте элемент {{htmlelement ("script")}}, чтобы применить библиотеку Modernizr к странице, как показано ниже. Это должно быть применено к странице перед любым CSS (или JavaScript), который может ее использовать. + <pre class="brush: html"><script src="modernizr-custom.js"></script></pre> + </li> + <li>Теперь отредактируйте открывающий тег <code><html></code>, чтобы он выглядел так: + <pre class="brush: html"><html class="no-js"></pre> + </li> +</ol> + +<p>На этом этапе попробуйте загрузить свою страницу, и вы получите представление о том, как Modernizr работает с функциями CSS. Если вы посмотрите на инспектор DOM инструментов разработчика вашего браузера, вы увидите, что Modernizr обновил значение вашего <code><html></code> <code>class</code> следующим образом:</p> + +<pre><html class="js no-htmlimports sizes flash transferables applicationcache blobconstructor +blob-constructor cookies cors ...AND LOADS MORE VALUES!></pre> + +<p>Теперь он содержит большое количество классов, которые указывают на состояние поддержки различных функций. Например, если браузер вообще не поддерживает flexbox, <code><html></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><html></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><script></code> , как мы делали в предыдущих демонстрациях. Поместите его над существующим элементом <code><script></code> который прикрепляет API Google Maps к странице.</li> + <li>Затем заполните текст-заполнитель <code>YOUR-API-KEY</code> во втором элементе <code><script></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><script></code> внизу тела HTML (непосредственно перед тегом <code></body></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 > Preferences...</em> on Mac, or <em>File > 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"><video></a></code>, <code><a href="/en-US/docs/Web/HTML/Element/audio"><audio></a></code>, and <code><a href="/en-US/docs/Web/HTML/Element/canvas"><canvas></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"><</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">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</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">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"> <</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">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</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">></span></span> + <span class="comment token"><!-- Flash fallback --></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</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">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</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">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</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">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</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">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</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;image<span class="punctuation token">=</span>img/poster.jpg&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">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</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">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>object</span><span class="punctuation token">></span></span> + <span class="comment token"><!-- Offer download --></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</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">></span></span>Download MP4<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>a</span><span class="punctuation token">></span></span> +<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>video</span><span class="punctuation token">></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"><input></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"><form> + <div> + <label for="date">Enter a date:</label> + <input id="date" type="date"> + </div> + <div> + <label for="time">Enter a time:</label> + <input id="time" type="time"> + </div> +</form></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"><form> + <div> + <label for="date">Enter a date:</label> + <input id="date" type="date"> + </div> + <div> + <label for="time">Enter a time:</label> + <input id="time" type="time"> + </div> + </form></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"><!--[if lte IE 8]> + <script src="ie-fix.js"></script></span> + <link href="ie-fix.css" rel="stylesheet" type="text/css"> +<span class="c"><![endif]--></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 > #date</pre> + +<p>(The <code>date</code> form input isn't directly inside the <code><form></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><style></code> tag: + <pre class="brush: html"><script type="text/javascript" src="MooTools-Core-1.6.0.js"></script> + <!--[if (gte IE 6)&(lte IE 8)]> + <script type="text/javascript" src="selectivizr-min.js"></script> + <![endif]--></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 > 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 > 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"><video> 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>Начальное планирование > Разработка > Тестирование > Исправление ошибок</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> diff --git a/files/ru/learn/tools_and_testing/index.html b/files/ru/learn/tools_and_testing/index.html new file mode 100644 index 0000000000..a032697166 --- /dev/null +++ b/files/ru/learn/tools_and_testing/index.html @@ -0,0 +1,48 @@ +--- +title: Tools and testing +slug: Learn/Tools_and_testing +tags: + - Accessibility + - Automation + - Beginner + - CSS + - CodingScripting + - HTML + - JavaScript + - Landing + - Learn + - NeedsTranslation + - Testing + - Tools + - Topic + - TopicStub + - cross browser + - user testing +translation_of: Learn/Tools_and_testing +--- +<div>{{LearnSidebar}}</div> + +<p class="summary">Once you've started to become comfortable programming with core web technologies (like HTML, CSS, and JavaScript), and you start to get more experience, read more resources, and learn more tips and tricks, you'll start to come across all kind of tools, from ready-rolled CSS and JavaScript, to testing and automation apps, and more besides. As your web projects become larger and more complex, you'll want to start taking advantage of some of these tools, and working out reliable testing plans for your code. This part of the learning area aims to give you what you need get started and make informed choices.</p> + +<p>The web industry is an exciting place to work, but it is not without its complications. The core technologies we use to build web sites are fairly stable now, but new features are being added all the time, and new tools — that facilitate working with, and are built on top of these technologies — are constantly appearing. On top of that, we still need to keep cross-browser support in the forefront of our minds, and make sure that our code follows best practices that allow our projects to work across different browsers and devices that our users are using to browse the Web, and be usable by people with disabilities.</p> + +<p>Working out what tools you should be using can be a difficult process, so we have written this set of articles to inform you of what types of tool are available, what they can do for you, and how to make use of the current industry favourites.</p> + +<div class="note"> +<p><strong>Note</strong>: Because new tools appear and old ones go out of fashion all the time, we have deliberately written this material to be as neutral as possible — we want to focus first and foremost on the general types of tasks these tools will help you accomplish, and keep prescribing specific tools to a minimum. We obviously need to show tool usage to demonstrate specific techniques, but be clear that we do not necessarily recommend these tools as the best or only way to do things — in most cases there are other ways, but we want to provide you with a clear methodology that works.</p> +</div> + +<h2 id="Learning_pathway">Learning pathway</h2> + +<p>You should really learn the basics of the core <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, and <a href="/en-US/docs/Learn/JavaScript">JavaScript</a> languages first before attempting to use the tools detailed here. For example, you'll need to know the fundamentals of these languages before you start debugging problems in complex web code, or making effective use of JavaScript libraries, or writing tests and running them against your code using test runners, etc.</p> + +<p>You need a solid foundation first.</p> + +<h2 id="Modules">Modules</h2> + +<dl> + <dt>Real world web development tools (TBD)</dt> + <dd>In this module, we explore the different kinds of web development tools available. This includes reviewing the most common kinds of tasks you may be called on to solve, how they can fit together in a workflow, and the best tools currently avaiable for carrying out those tasks.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing">Cross browser testing</a></dt> + <dd>This module looks specifically at the area of testing web projects across different browsers. Here we look identifying your target audience (e.g. what users, browsers and devices do you most need to worry about?), how to go about doing testing, the main issues that you'll face with different types of code and how to fix/mitigate those, what tools are most useful in helping you test and fix problems, and how to use automation to speed up testing.</dd> +</dl> diff --git a/files/ru/learn/tools_and_testing/гитхаб/index.html b/files/ru/learn/tools_and_testing/гитхаб/index.html new file mode 100644 index 0000000000..f78ac2a27c --- /dev/null +++ b/files/ru/learn/tools_and_testing/гитхаб/index.html @@ -0,0 +1,84 @@ +--- +title: Гит и ГитХаб +slug: Learn/Tools_and_testing/ГитХаб +tags: + - Веб + - Начинающий + - гит +translation_of: Learn/Tools_and_testing/GitHub +--- +<div>{{LearnSidebar}}</div> + +<p class="summary">Все разработчики используют ту или иную <strong>систему контроля версий (СКВ, VCS)</strong>, инструмент, позволяющий им взаимодействовать с другими разработчиками на проекте без угрозы того, что кто-то перезапишет чужую работу, а также вернуться к предыдущим версиям кода при обнаружении проблем позднее.</p> + +<p class="summary">Самая популярная СКВ (по крайней мере, среди веб-разработчиков) являюся <strong>Гит (Git)</strong>, а также <strong>ГитХаб (GItHub) </strong>- сайт, обеспечивающий размещение ваших репозиториев и включащий инструменты для работы с ними. Цели этого модуля - дать вам необходимые знания о каждой из упомянутых СКВ.</p> + +<h2 id="Обзор">Обзор</h2> + +<p>СКВ являются основой для разработки программного обеспечения:</p> + +<ul> + <li>Редко, когда вы работаете с проектом полностью самостоятельно. Как только вы начинаете работать с другими людьми, возникает риск конфликта. Речь идет о ситуации, когда несколько человек пытается в одно и то же время обновить одну и ту же часть кода. Нужен определенный механизм, позволяющий управлять событиями и тем самым избежать потери результатов общей работы.</li> + <li>Работая с проектому в одиночку или с другими, вы захотите иметь возможность иметь резервную копию кода на случай поломки вашего компьютера.</li> + <li>Также у вас может возникнуть необходимость откатить изменения к более ранним версиям, если проблема обнаружена позднее. Конечно, это начать делать самостоятельно, сохраняя различные версии одного и того же файла, например <code>myCode.js</code>, <code>myCode_v2.js</code>, <code>myCode_v3.js</code>, <code>myCode_final.js</code>, <code>myCode_really_really_final.js</code>, и так далее, но это на самом деле ненадежный и порождающий ошибки способ.</li> + <li>Различные члены команды могут захотеть создать собственные версии кода (в Гит такие версии именуются <strong>ветками</strong>), работать над новой фичей в этой версии, а затем контролируемо объединить эту версию (в ГитХабе используются <strong>пул реквесты</strong> - запросы на принятие изменений) с главной версией.</li> +</ul> + +<p>СКВ обеспечивают инструменты для решения всех вышеуказанных задач. <a href="https://git-scm.com/">Гит</a> является примером СКВ, а <a href="https://github.com/">ГитХаб</a> - это сайт, обеспечивающий веб-интерфейс для работы с гит, а также множество полезных инструментов для работы с гит-репозиториями лично или в командах, такие как фиксация проблем с кодом, инструменты для проверки кода, инструменты для управления созданием продукта, например назначение задач и их статусов, и т.д.</p> + +<div class="blockIndicator note"> +<p><strong>Важно</strong>: ГИТ на самом деле - распределенная система контроля версий, это значит что полная копия репозитория, содержащая всю кодовую базу сохраняется на твой компьютер (и кого-либо еще). Ты вносишь изменения в свою копию и затем отправляешь эти изменения обратно на сервер, на котором администратор решит соединять ли твои измеения с оригиналом. </p> +</div> + +<h2 id="Подготовка">Подготовка</h2> + +<p>Для использования Git и GitHub тебе необходимо:</p> + +<ul> + <li>Компьютер с установленной версией Git (посмотри <a href="https://git-scm.com/downloads">страницу загрузки Git</a>).</li> + <li>Приложения для работы с Git. В зависимости от того как ты предпочитаешь работать, можешь использовать <a href="https://git-scm.com/downloads/guis/">Git-кленты с графическим интерфейсом</a> (мы рекомендуем GitHub Desktop, SourceTree или Git Kraken) или просто продолжай использовать окно терминала. Если честно, будет весьма полезно для тебя узнать основы использования git-команд в терминале, даже если ты собираешься работать через графический интерфейс.</li> + <li><a href="https://github.com/join">Аккаунт на GitHub</a>. Если у тебя еще его нет, зарегистрируйся сейчас по указанной ссылке.</li> +</ul> + +<p>Что касается предварительных знаний, вам не нужно разбираться в веб-разработке, Git / GitHub или VCS, чтобы приступить к этому модулю. Тем не менее, рекомендуется, чтобы вы разбирались в состоавлении кода, могли его писать и читать, а также сохранили пару строчек кода в своих репозиториях!</p> + +<p>Также желательно, чтобы у вас были некоторые базовые знания о терминале, например, перемещение между каталогами, создание файлов и изменение системного <code>PATH</code>.</p> + +<div class="blockIndicator note"> +<p><strong>Важно</strong>: Github не единственный сайт / инструментарий который ты можешь использовать с Git. Есть и альтернативы, такие как <a href="https://about.gitlab.com/">GitLab</a>, которые ты можешь попробовать, а также ты моежшь попробовать настроить свой собственный сервер Git и использовать вместо GitHub. Мы в этом курсе останвились на GitHub, чтобы показать один из рабочих способов.</p> +</div> + +<h2 id="Guides">Guides</h2> + +<p>Note that the links below take you to resources on external sites. Eventually we will are aiming to have our own dedicated Git/GitHub course, but for now, these will help you get to grips with the subject in hand.</p> + +<dl> + <dt><a href="https://guides.github.com/activities/hello-world/">Hello World (from GitHub)</a></dt> + <dd>This is a good place to start — this practical guide gets you to jump right into using GitHub, learning the basics of Git such as creating repositories and branches, making commits, and opening and merging pull requests.</dd> + <dt><a href="https://guides.github.com/introduction/git-handbook/">Git Handbook (from GitHub)</a></dt> + <dd>This Git Handbook goes into a little more depth, explaining what a VCS is, what a repository is, how the basic GitHub model works, Git commands and examples, and more.</dd> + <dt><a href="https://guides.github.com/activities/forking/">Forking Projects (from GitHub)</a></dt> + <dd>Forking projects is essential when you want to contribute to someone else's code. This guide explains how.</dd> + <dt><a href="https://help.github.com/en/articles/about-pull-requests">About Pull Requests (from GitHub)</a></dt> + <dd>A useful guide to managing pull requests, the way that your suggested code changes are delivered to people's repositories for consideration.</dd> + <dt><a href="https://guides.github.com/features/issues/">Mastering issues (from GitHub)</a></dt> + <dd>Issues are like a forum for your GitHub project, where people can ask questions and report problems, and you can manage updates (for example assigning people to fix issues, clarifying the issue, letting people know things are fixed). This articles gives you what you need to know about issues.</dd> +</dl> + +<div class="blockIndicator note"> +<p><strong>Note</strong>: There is <strong>a lot more</strong> that you can do with Git and GitHub, but we feel that the above represents the minimum you need to know to start using Git effectively. As you get deeper into Git, you'll start to realise that it is easy to go wrong when you start using more complicated commands. Don't worry, even professional web developers find Git confusing sometimes, and often solve problems by searching for solutions on the web, or consulting sites like <a href="https://github.com/k88hudson/git-flight-rules">Flight rules for Git</a> and<a href="https://dangitgit.com/"> Dangit, git!</a></p> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="https://guides.github.com/introduction/flow/">Understanding the GitHub flow</a></li> + <li><a href="https://git-scm.com/docs">Git command list</a></li> + <li><a href="https://guides.github.com/features/mastering-markdown/">Mastering markdown</a> (the text format you write in on PR, issue comments, and <code>.md</code> files).</li> + <li><a href="https://guides.github.com/features/pages/">Getting Started with GitHub Pages</a> (how to publish demos and websites on GitHub).</li> + <li><a href="https://learngitbranching.js.org/">Learn Git branching</a></li> + <li><a href="https://github.com/k88hudson/git-flight-rules">Flight rules for Git</a> (a very useful compendium of ways to achieve specific things in Git, including how to correct things when you went wrong).</li> + <li> + <p><a href="https://dangitgit.com/">Dangit, git!</a> (another useful compendium, specifically of ways to correct things when you went wrong).</p> + </li> +</ul> diff --git a/files/ru/learn/tools_and_testing/фронтенд_javascript_фреймворки/index.html b/files/ru/learn/tools_and_testing/фронтенд_javascript_фреймворки/index.html new file mode 100644 index 0000000000..08fb977bb5 --- /dev/null +++ b/files/ru/learn/tools_and_testing/фронтенд_javascript_фреймворки/index.html @@ -0,0 +1,137 @@ +--- +title: Понимание JavaScript-фреймворков для фронтенда +slug: Learn/Tools_and_testing/Фронтенд_JavaScript_фреймворки +translation_of: Learn/Tools_and_testing/Client-side_JavaScript_frameworks +--- +<div>{{LearnSidebar}}<br> +JavaScript-ф<span>реймворки </span>являются неотъемлемой частью современной веб-разработки,</div> + +<div>предоставляя разработчикам проверенные и протестированные</div> + +<div>инструменты для создания масштабируемых и интерактивных веб-приложений. Многие</div> + +<div>современные компании используют фреймворки для своих решений, поэтому многие задачи связанные с разработкой клиентской части веб-приложений теперь требуют опыта работы с ними.<br> + </div> + +<p class="summary">Начинающему разработчику веб-интерфесов, может быть трудно понять, с чего начать изучение фреймворков - их выбор разнообразен, а новые появляются постоянно. В основном же они работают аналогичным образом, но делают некоторые вещи по-разному, также есть некоторые специфичные вещи, которые следует соблюдать при использовании фреймворков.</p> + +<p class="summary">Этим набором статей мы постараемся дать вам удобную отправную точку, чтобы помочь вам начать изучать основы. Мы не стремимся научить вас всему, что вам нужно знать о React / ReactDOM, или Vue, или какой-то другой конкретной среде; Документация этих фреймворков отлично выполняют эту работу. Вместо этого мы хотим сделать шаг назад и сначала ответить на более фундаментальные вопросы, такие как:</p> + +<ul> + <li class="summary">Почему я должен использовать фреймворк? Какие проблемы он решит?</li> + <li class="summary">Какие вопросы я должен задать себе при выборе определённого фреймворка?<br> + Нужен ли мне какой-либо из них вовсе?</li> + <li class="summary">Какими возможностями обладают фреймворки? Как они работают в целом и в чём отличия их имплементаций этих возможностей?</li> + <li class="summary">Как они связаны с "ванильным" JavaScript, или HTML?</li> +</ul> + +<p class="summary">После этого мы предоставим некоторые учебные пособия, охватывающие основы некоторых фреймворков, чтобы предоставить вам достаточно контекста, чтобы вы могли начать углубляться в этой теме. Мы хотим, чтобы вы изучали фреймворки прагматично, не забывая о фундаментальных практиках веб-разработки, таких как, например, доступность.</p> + +<p class="summary"><strong><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction">Начните прямо сейчас с "Введение в фронтенд фрейворки"</a></strong></p> + +<h2 id="Prerequisites">Prerequisites</h2> + +<p>You should really learn the basics of the core web languages first before attempting to move on to learning client-side frameworks — <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, and especially <a href="/en-US/docs/Learn/JavaScript">JavaScript</a>.</p> + +<p>Your code will be richer and more professional as a result, and you'll be able to troubleshoot problems with more confidence if you understand the fundamental web platform features that the frameworks are building on top of.</p> + +<h2 id="Introductory_guides">Introductory guides</h2> + +<dl> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction">1. Introduction to client-side frameworks</a></dt> + <dd>We begin our look at frameworks with a general overview of the area, looking at a brief history of JavaScript and frameworks, why frameworks exist and what they give us, how to start thinking about choosing a framework to learn, and what alternatives there are to client-side frameworks.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features">2. Framework main features</a></dt> + <dd>Each major JavaScript framework has a different approach to updating the DOM, handling browser events, and providing an enjoyable developer experience. This article will explore the main features of “the big 4” frameworks, looking at how frameworks tend to work from a high level, and the differences between them.</dd> +</dl> + +<h2 id="React_tutorials">React tutorials</h2> + +<div class="blockIndicator note"> +<p><strong>Note</strong>: React tutorials last tested in May 2020, with React/ReactDOM 16.13.1 and create-react-app 3.4.1.</p> + +<p>If you need to check your code against our version, you can find a finished version of the sample React app code in our <a href="https://github.com/mdn/todo-react">todo-react repository</a>. For a running live version, see <a href="https://mdn.github.io/todo-react-build/">https://mdn.github.io/todo-react-build/</a>.</p> +</div> + +<dl> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started">1. Getting started with React</a></dt> + <dd>In this article we will say hello to React. We'll discover a little bit of detail about its background and use cases, set up a basic React toolchain on our local computer, and create and play with a simple starter app, learning a bit about how React works in the process.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning">2. Beginning our React todo list</a></dt> + <dd>Let's say that we’ve been tasked with creating a proof-of-concept in React – an app that allows users to add, edit, and delete tasks they want to work on, and also mark tasks as complete without deleting them. This article will walk you through putting the basic <code>App</code> component structure and styling in place, ready for individual component definition and interactivity, which we'll add later.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components">3. Componentizing our React app</a></dt> + <dd>At this point, our app is a monolith. Before we can make it do things, we need to break it apart into manageable, descriptive components. React doesn’t have any hard rules for what is and isn’t a component – that’s up to you! In this article we will show you a sensible way to break our app up into components.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_events_state">4. React interactivity: Events and state</a></dt> + <dd>With our component plan worked out, it's now time to start updating our app from a completely static UI to one that actually allows us to interact and change things. In this article we'll do this, digging into events and state along the way.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_filtering_conditional_rendering">5. React interactivity: Editing, filtering, conditional rendering</a></dt> + <dd>As we near the end of our React journey (for now at least), we'll add the finishing touches to the main areas of functionality in our Todo list app. This includes allowing you to edit existing tasks, and filtering the list of tasks between all, completed, and incomplete tasks. We'll look at conditional UI rendering along the way.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_accessibility">6. Accessibility in React</a></dt> + <dd>In our final tutorial article, we'll focus on (pun intended) accessibility, including focus management in React, which can improve usability and reduce confusion for both keyboard-only and screenreader users.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_resources">7. React resources</a></dt> + <dd>Our final article provides you with a list of React resources that you can use to go further in your learning.</dd> +</dl> + +<h2 id="Ember_tutorials">Ember tutorials</h2> + +<div class="blockIndicator note"> +<p><strong>Note</strong>: Ember tutorials last tested in May 2020, with Ember/Ember CLI version 3.18.0.</p> + +<p>If you need to check your code against our version, you can find a finished version of the sample Ember app code in the <a href="https://github.com/NullVoxPopuli/ember-todomvc-tutorial/tree/master/steps/00-finished-todomvc/todomvc">ember-todomvc-tutorial repository</a>. For a running live version, see <a href="https://nullvoxpopuli.github.io/ember-todomvc-tutorial/">https://nullvoxpopuli.github.io/ember-todomvc-tutorial/</a> (this also includes a few additional features not covered in the tutorial).</p> +</div> + +<dl> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_getting_started">1. Getting started with Ember</a></dt> + <dd>In our first Ember article we will look at how Ember works and what it's useful for, install the Ember toolchain locally, create a sample app, and then do some initial setup to get it ready for development.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_structure_componentization">2. Ember app structure and componentization</a></dt> + <dd>In this article we'll get right on with planning out the structure of our TodoMVC Ember app, adding in the HTML for it, and then breaking that HTML structure into components.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_interactivity_events_state">3. Ember interactivity: Events, classes and state</a></dt> + <dd>At this point we'll start adding some interactivity to our app, providing the ability to add and display new todo items. Along the way, we'll look at using events in Ember, creating component classes to contain JavaScript code to control interactive features, and setting up a service to keep track of the data state of our app.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_conditional_footer">4. Ember Interactivity: Footer functionality, conditional rendering</a></dt> + <dd>Now it's time to start tackling the footer functionality in our app. Here we'll get the todo counter to update to show the correct number of todos still to complete, and correctly apply styling to completed todos (i.e. where the checkbox has been checked). We'll also wire up our "Clear completed" button. Along the way, we'll learn about using conditional rendering in our templates.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_routing">5. Routing in Ember</a></dt> + <dd>In this article we learn about routing, or URL-based filtering as it is sometimes referred to. We'll use it to provide a unique URL for each of the three todo views — "All", "Active", and "Completed".</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources">6. Ember resources and troubleshooting</a></dt> + <dd>Our final Ember article provides you with a list of resources that you can use to go further in your learning, plus some useful troubleshooting and other information.</dd> +</dl> + +<h2 id="Vue_tutorials">Vue tutorials</h2> + +<div class="blockIndicator note"> +<p><strong>Note</strong>: Vue tutorials last tested in May 2020, with Vue 2.6.11.</p> + +<p>If you need to check your code against our version, you can find a finished version of the sample Vue app code in our <a href="https://github.com/mdn/todo-vue">todo-vue repository</a>. For a running live version, see <a href="https://mdn.github.io/todo-vue/dist/">https://mdn.github.io/todo-vue/dist/</a>.</p> +</div> + +<dl> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started">1. Getting started with Vue</a></dt> + <dd>Now let's introduce Vue, the third of our frameworks. In this article we'll look at a little bit of Vue background, learn how to install it and create a new project, study the high-level structure of the whole project and an individual component, see how to run the project locally, and get it prepared to start building our example.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component">2. Creating our first Vue component</a></dt> + <dd>Now it's time to dive deeper into Vue, and create our own custom component — we'll start by creating a component to represent each item in the todo list. Along the way, we'll learn about a few important concepts such as calling components inside other components, passing data to them via props, and saving data state.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_rendering_lists">3. Rendering a list of Vue components</a></dt> + <dd><span class="author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qoxwoxz78zz83zz84zz69z2z80zgwxsgnz83zfkt5e5tz70zz68zmsnjz122zz71z">At this point we've got a fully working component; we're now ready to add multiple <code>ToDoItem</code> components to our App. In this artcle we'll look at adding a set of todo item data to our <code>App.vue</code> component, which we'll then loop through and display inside <code>ToDoItem</code> components using the <code>v-for</code> directive. </span></dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_methods_events_models">4. Adding a new todo form: Vue events, methods, and models</a></dt> + <dd>We now have sample data in place, and a loop that takes each bit of data and renders it inside a <code>ToDoItem</code> in our app. What we really need next is the ability to allow our users to enter their own todo items into the app, and for that we'll need a text <code><input></code>, an event to fire when the data is submitted, a method to fire upon submission to add the data and rerender the list, and a model to control the data. This is what we'll cover in this article.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_styling">5. Styling Vue components with CSS</a></dt> + <dd>The time has finally come to make our app look a bit nicer. In this article we'll explore the different ways of styling Vue components with CSS.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_computed_properties">6. Using Vue computed properties</a></dt> + <dd>In this article we'll add a counter that displays the number of completed todo items, using a feature of Vue called computed properties. These work similarly to methods, but only re-run when one of their dependencies changes.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_conditional_rendering">7. Vue conditional rendering: editing existing todos</a></dt> + <dd>Now it is time to add one of the major parts of functionality that we're still missing — the ability to edit existing todo items. To do this, we will take advantage of Vue's conditional rendering capabilities — namely <code>v-if</code> and <code>v-else</code> — to allow us to toggle between the existing todo item view, and an edit view where you can update todo item labels. We'll also look at adding functionality to delete todo items.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_refs_focus_management">8. Focus management with Vue refs</a></dt> + <dd>We are nearly done with Vue. The last bit of functionality to look at is focus management, or put another way, how we can improve our app's keyboard accessibility. We'll look at using Vue refs to handle this — an advanced feature that allows you to have direct access to the underlying DOM nodes below the virtual DOM, or direct access from one component to the internal DOM structure of a child component.</dd> + <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_resources">9. Vue resources</a></dt> + <dd>Now we'll round off our study of Vue by giving you a list of resources that you can use to go further in your learning, plus some other useful tips.</dd> +</dl> + +<h2 id="Which_frameworks_did_we_choose">Which frameworks did we choose?</h2> + +<p>We are publishing our initial set of articles with guides focusing on three of the major frameworks out there — React/ReactDOM, Ember, and Vue. There is a variety of reasons for this:</p> + +<ul> + <li>They are popular choices that will be around for a while — like with any software tool, it is good to stick with actively-developed choices that are likely to not be discontinued next week, and which will be desirable additions to your skillset when looking for a job.</li> + <li>They have strong communities and good documentation. It is very important to be able to get help with learning a complex subject, especially when you are just starting out.</li> + <li>We don't have the resources to cover <em>all</em> modern frameworks. That list would be very difficult to keep up-to-date anyway, as new ones appear all the time.</li> + <li>As a beginner, trying to choose what to focus on out of the huge number of choices available is a very real problem. Keeping the list short is therefore helpful.</li> +</ul> + +<p>We want to say this up front — we've <strong>not</strong> chosen the frameworks we are focusing on because we think they are the best, or because we endorse them in any way. We just think they score highly on the above criteria.</p> + +<p>Note that we were hoping to have more frameworks included upon intial publication, but we decided to release the content and then add more framework guides later, rather than delay it longer. If your favourite framework is not represented in this content and you'd like to help change that, feel free to discuss it with us! Get in touch with us via <a href="https://wiki.mozilla.org/Matrix">Matrix</a>, or <a href="https://discourse.mozilla.org/c/mdn">Discourse</a>, or drop us a mail on the <a href="mailto:mdn-admins@mozilla.org">mdn-admins list</a>.</p> diff --git a/files/ru/learn/tools_and_testing/фронтенд_javascript_фреймворки/react_getting_started/index.html b/files/ru/learn/tools_and_testing/фронтенд_javascript_фреймворки/react_getting_started/index.html new file mode 100644 index 0000000000..9a898b282a --- /dev/null +++ b/files/ru/learn/tools_and_testing/фронтенд_javascript_фреймворки/react_getting_started/index.html @@ -0,0 +1,462 @@ +--- +title: Начало работы с React +slug: Learn/Tools_and_testing/Фронтенд_JavaScript_фреймворки/React_getting_started +translation_of: >- + Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}</div> + +<p class="summary">В этой статье мы скажем привет React. Мы узнаем немного подробностей о его происхождении и сценариях использования, настроим базовый набор инструментов на нашем локальном компьютере, а также создадим и поиграем с простым приложением для начинающих, и в процессе узнаем немного о том, как React работает .</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Что нужно знать:</th> + <td> + <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>, быть знакомым с <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line">терминалом/коммандной строкой</a>.</p> + + <p>React использует синтаксис HTML-in-JavaScript под названием JSX (JavaScript и XML). Знание HTML и JavaScript поможет вам изучить JSX и лучше определить, связаны ли ошибки в вашем приложении с JavaScript или с более специфической областью React.</p> + </td> + </tr> + <tr> + <th scope="row">Задача:</th> + <td> + <p>Настроить локальную среду разработки React, создать стартовое приложение и понять основы его работы.</p> + </td> + </tr> + </tbody> +</table> + +<h2 id="Привет_Реакт">Привет Реакт</h2> + +<p>Как гласит официальный слоган, <a href="https://ru.reactjs.org/">React</a> - это библиотека для создания пользовательских интерфейсов. React не является фреймворком – он даже не рассчитан исключительно для web. Он используется для визуализации и в связке с другими библиотеками. Например, <a href="https://reactnative.dev/">React Native</a> можно использовать для создания мобильных приложений; <a href="https://facebook.github.io/react-360/">React 360</a> можно использовать для создания приложений виртуальной реальности; помимо того есть и другие <a href="https://github.com/chentsulin/awesome-react-renderer">варианты</a>.</p> + +<p>Для создания веб-приложений разработчики используют React в тандеме с <a href="https://reactjs.org/docs/react-dom.html">ReactDOM</a>. React and ReactDOM часто обсуждаются в том же пространстве и используются для решения тех же проблем, что и другие настоящие фреймворки для веб-разработки. Когда мы ссылаемся на React как на «фреймворк», мы подразумеваем это разговорное понимание.</p> + +<p>Основная цель React - минимизировать ошибки, возникающие при разработке пользовательских интерфейсов. Это достигается за счет использования компонентов - автономных логических фрагментов кода, которые описывают часть пользовательского интерфейса. А уже эти компоненты объединяются для создания полноценного пользовательского интерфейса. React абстрагирует большую часть работы по визуализации, оставляя вам возможность сосредоточиться на дизайне.</p> + +<h2 id="Когда_использовать">Когда использовать</h2> + +<p>В отличие от других платформ, рассматриваемых в этом модуле, React не обязывает к строгим правилам в отношении соглашений о коде или организации файлов. Это позволяет командам договариваться, что для них более подходит, и структурировать React проект соответствующим образом. React может отвечать за одну кнопку, несколько частей или же весь пользовательский интерфейс приложения.</p> + +<p>Хотя React <em>можно</em> использовать для <a href="https://ru.reactjs.org/docs/add-react-to-a-website.html">небольших частей интерфейса</a>, «зайти» в него не так просто, как, к примеру, в jQuery, или даже во Vue. Куда легче это сделать создав всё приложения с помощью React.</p> + +<p>Кроме того, такие преимущества React-приложения, как написание интерфейсов с помощью JSX, требуют процесса компиляции. Добавление на сайт компилятора Babel приводит к более медленному выполнению кода, поэтому такие инструменты обычно настраиваются для процесса сборки. Да, возможно, у React есть серьезные требования к инструментарию, но этому можно освоить.</p> + +<p>В этой статье основное внимание будет уделено использованию React для создания всего пользовательского интерфейса с помощью <a href="https://create-react-app.dev/">create-react-app</a>, предоставляемого Facebook.</p> + +<h2 id="Как_React_использует_JavaScript">Как React использует JavaScript?</h2> + +<p>React utilizes features of modern JavaScript for many of its patterns. Its biggest departure from JavaScript comes with the use of <a href="https://reactjs.org/docs/introducing-jsx.html">JSX</a> syntax. JSX extends JavaScript's syntax so that HTML-like code can live alongside it. For example:</p> + +<pre class="brush: js notranslate">const heading = <h1>Mozilla Developer Network</h1>;</pre> + +<p>This heading constant is known as a <strong>JSX expression</strong>. React can use it to render that <code><a href="/en-US/docs/Web/HTML/Element/Heading_Elements"><h1></a></code> tag in our app.</p> + +<p>Suppose we wanted to wrap our heading in a <code><a href="/en-US/docs/Web/HTML/Element/header"><header></a></code> tag, for semantic reasons? The JSX approach allows us to nest our elements within each other, just like we do with HTML:</p> + +<pre class="brush: js notranslate">const header = ( + <header> + <h1>Mozilla Developer Network</h1> + </header> +);</pre> + +<div class="blockIndicator note"> +<p><strong>Note</strong>: The parentheses in the previous snippet aren't unique to JSX, and don’t have any effect on your application. They're a signal to you (and your computer) that the multiple lines of code inside are part of the same expression. You could just as well write the header expression like this:</p> + +<pre class="brush: js notranslate">const header = <header> + <h1>Mozilla Developer Network</h1> +</header></pre> + +<p>However, this looks kind of awkward, because the <code><a href="/en-US/docs/Web/HTML/Element/header"><header></a></code> tag that starts the expression is not indented to the same position as its corresponding closing tag.</p> +</div> + +<p>Of course, your browser can't read JSX without help. When compiled (using a tool like <a href="https://babeljs.io/">Babel</a> or <a href="https://parceljs.org/">Parcel</a>), our header expression would look like this:</p> + +<pre class="brush: js notranslate">const header = React.createElement("header", null, + React.createElement("h1", null, "Mozilla Developer Network") +);</pre> + +<p>It's <em>possible</em> to skip the compilation step and use <code><a href="https://reactjs.org/docs/react-api.html#createelement">React.createElement()</a></code> to write your UI yourself. In doing this, however, you lose the declarative benefit of JSX, and your code becomes harder to read. Compilation is an extra step in the development process, but many developers in the React community think that the readability of JSX is worthwhile. Plus, popular tooling makes JSX-to-JavaScript compilation part of its setup process. You don't have to configure compilation yourself unless you want to.</p> + +<p>Because JSX is a blend of HTML and JavaScript, some developers find it intuitive. Others say that its blended nature makes it confusing. Once you're comfortable with it, however, it will allow you build user interfaces more quickly and intuitively, and allow others to better understand your code base at a glance.</p> + +<p>To read more about JSX, check out the React team's <a href="https://reactjs.org/docs/jsx-in-depth.html">JSX In Depth</a> article.</p> + +<h2 id="Настройка_вашего_первого_React_приложения">Настройка вашего первого React приложения</h2> + +<p>There are many ways to use React, but we're going to use the command-line interface (CLI) tool create-react-app, as mentioned earlier, which expedites the process of developing a React application by installing some packages and creating some files for you, handling the tooling described above.</p> + +<p>It's possible to <a href="https://reactjs.org/docs/add-react-to-a-website.html">add React to a website without create-react-app</a> by copying some <code><a href="/en-US/docs/Web/HTML/Element/script"><script></a></code> elements into an HTML file, but the create-react-app CLI is a common starting point for React applications. Using it will allow you spend more time building your app, and less time fussing with setup.</p> + +<h3 id="Requirements">Requirements</h3> + +<p>In order to use create-react-app, you need to have <a href="https://nodejs.org/en/">Node.js</a> installed. It's recommended that you use the long-term support (LTS) version. Node includes npm (the node package manager), and npx (the node package runner).</p> + +<p>You may also use the Yarn package manager as an alternative, but we'll assume you are using npm in this set of tutorials. See <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Package_management">Package management basics</a> for more information on npm and yarn.</p> + +<p>If you're using Windows, you will need to install some software to give you parity with Unix/macOS terminal in order to use the terminal commands mentioned in this tutorial. <strong>Gitbash</strong> (which comes as part of the <a href="https://gitforwindows.org/">git for Windows toolset</a>) or <strong><a href="https://docs.microsoft.com/en-us/windows/wsl/about">Windows Subsystem for Linux</a></strong> (<strong>WSL</strong>) are both suitable. See <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line">Command line crash course</a> for more information on these, and on terminal commands in general.</p> + +<p>Also bear in mind that React and ReactDOM produce apps that only work on a fairly modern set of browsers — IE9+ by way of some polyfills. It is recommended that you use a modern browser like Firefox, Safari, or Chrome when working through these tutorials.</p> + +<p>Also see the following for more information:</p> + +<ul> + <li><a href="https://nodejs.org/en/knowledge/getting-started/npm/what-is-npm/">"What is npm" on nodejs.org</a></li> + <li><a href="https://blog.npmjs.org/post/162869356040/introducing-npx-an-npm-package-runner">"Introducing npx" on the npm blog</a></li> + <li><a href="https://create-react-app.dev/">The create-react-app documentation</a></li> +</ul> + +<h3 id="Initializing_your_app">Initializing your app</h3> + +<p>create-react-app takes one argument: the name you'd like to give your app. create-react-app uses this name to make a new directory, then creates the necessary files inside it. Make sure you <code>cd</code> to the place you'd like your app to live on your hard drive, then run the following in your terminal:</p> + +<pre class="brush: bash notranslate">npx create-react-app moz-todo-react</pre> + +<p>This creates a <code>moz-todo-react</code> directory, and does several things inside it:</p> + +<ul> + <li>Installs some npm packages essential to the functionality of the app.</li> + <li>Writes scripts for starting and serving the application.</li> + <li>Creates a structure of files and directories that define the basic app architecture.</li> + <li>Initializes the directory as a git repository, if you have git installed on your computer.</li> +</ul> + +<div class="blockIndicator note"> +<p><strong>Note</strong>: if you have the yarn package manager installed, create-react-app will default to using it instead of npm. If you have both package managers installed and explicitly want to use NPM, you can add the flag <code>--use-npm</code> when you run create-react-app:</p> + +<pre class="brush: bash notranslate">npx create-react-app moz-todo-react --use-npm</pre> +</div> + +<p>create-react-app will display a number of messages in your terminal while it works; this is normal! This might take a few minutes, so now might be a good time to go make a cup of tea.</p> + +<p>When the process is complete, <code>cd</code> into the <code>moz-todo-react</code> directory and run the command <code>npm start</code>. The scripts installed by create-react-app will start being served at a local server at localhost:3000, and open the app in a new browser tab. Your browser will display something like this:</p> + +<p><img alt="Screenshot of Firefox MacOS, open to localhost:3000, showing the default create-react-app application" src="https://mdn.mozillademos.org/files/17203/default-create-react-app.png" style="border-style: solid; border-width: 1px; height: 980px; width: 1600px;"></p> + +<h3 id="Application_structure">Application structure</h3> + +<p>create-react-app gives us everything we need to develop a React application. Its initial file structure looks like this:</p> + +<pre class="notranslate">moz-todo-react +├── README.md +├── node_modules +├── package.json +├── package-lock.json +├── .gitignore +├── public +│ ├── favicon.ico +│ ├── index.html +│ └── manifest.json +└── src + ├── App.css + ├── App.js + ├── App.test.js + ├── index.css + ├── index.js + ├── logo.svg + └── serviceWorker.js</pre> + +<p>The <strong><code>src</code></strong> directory is where we'll spend most of our time, as it's where the source code for our application lives.</p> + +<p>The <strong><code>public</code></strong> directory contains files that will be read by your browser while you're developing the app; the most important of these is <code>index.html</code>. React injects your code into this file so that your browser can run it. There's some other markup that helps create-react-app function, so take care not to edit it unless you know what you're doing. You very much should change the text inside the <code><a href="/en-US/docs/Web/HTML/Element/title"><title></a></code> element in this file to reflect the title of your application. Accurate page titles are important for accessibility!</p> + +<p>The <code>public</code> directory will also be published when you build and deploy a production version of your app. We won’t cover deployment in this tutorial, but you should be able to use a similar solution to that described in our <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Deployment">Deploying our app</a> tutorial.</p> + +<p>The <code>package.json</code> file contains information about our project that Node.js/npm uses to keep it organized. This file is not unique to React applications; create-react-app merely populates it. You don't need to understand this file at all to complete this tutorial, however, if you'd like to learn more about it, you can read <a href="https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/">What is the file `package.json`? on NodeJS.org</a>; we also talk about it in our <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Package_management">Package management basics</a> tutorial.</p> + +<h2 id="Изучаем_наш_первый_React_компонент_—_<App>">Изучаем наш первый React компонент — <code><App/></code></h2> + +<p>In React, a <strong>component</strong> is a reusable module that renders a part of our app. These parts can be big or small, but they are usually clearly defined: they serve a single, obvious purpose.</p> + +<p>Let's open <code>src/App.js</code>, since our browser is prompting us to edit it. This file contains our first component, <code>App</code>, and a few other lines of code:</p> + +<pre class="brush: js notranslate">import React from 'react'; +import logo from './logo.svg'; +import './App.css'; + +function App() { + return ( + <div className="App"> + <header className="App-header"> + <img src={logo} className="App-logo" alt="logo" /> + <p> + Edit <code>src/App.js</code> and save to reload. + </p> + <a + className="App-link" + href="https://reactjs.org" + target="_blank" + rel="noopener noreferrer" + > + Learn React + </a> + </header> + </div> + ); +} +export default App;</pre> + +<p>The <code>App.js</code> file consists of three main parts: some <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/import">import</a></code> statements at the top, the <code>App</code> component in the middle, and an <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/export">export</a></code> statement at the bottom. Most React components follow this pattern.</p> + +<h3 id="Import_statements">Import statements</h3> + +<p>The <code>import</code> statements at the top of the file allow <code>App.js</code> to use code that has been defined elsewhere. Let's look at these statements more closely.</p> + +<pre class="brush: js notranslate">import React from 'react'; +import logo from './logo.svg'; +import './App.css';</pre> + +<p>The first statement imports the React library itself. Because React turns the JSX we write into <code>React.createElement()</code>, all React components must import the <code>React</code> module. If you skip this step, your application will produce an error.</p> + +<p>The second statement imports a logo from <code>'./logo.svg'</code>. Note the <code>./</code> at the beginning of the path, and the <code>.svg</code> extension at the end — these tell us that the file is local and that it is not a JavaScript file. Indeed, the <code>logo.svg</code> file lives in our source directory.</p> + +<p>We don't write a path or extension when importing the <code>React</code> module — this is not a local file; instead, it is listed as a dependency in our <code>package.json</code> file. Be careful of this distinction as you work through this lesson!</p> + +<p>The third statement imports the CSS related to our App component. Note that there is no variable name and no <code>from</code> directive. This particular import syntax is not native to JavaScript module syntax – it comes from Webpack, the tool create-react-app uses to bundle all our JavaScript files together and serve them to the browser.</p> + +<h3 id="The_App_component">The <code>App</code> component</h3> + +<p>After the imports, we have a function named <code>App</code>. Whereas most of the JavaScript community prefers camel-case names like <code>helloWorld</code>, React components use pascal-case variable names, like <code>HelloWorld</code>, to make it clear that a given JSX element is a React component, and not a regular HTML tag. If you were to rename the <code>App</code> function to <code>app</code>, your browser would show you an error.</p> + +<p>Let's look at App more closely.</p> + +<pre class="brush: js notranslate">function App() { + return ( + <div className="App"> + <header className="App-header"> + <img src={logo} className="App-logo" alt="logo" /> + <p> + Edit <code>src/App.js</code> and save to reload. + </p> + <a + className="App-link" + href="https://reactjs.org" + target="_blank" + rel="noopener noreferrer" + > + Learn React + </a> + </header> + </div> + ); +}</pre> + +<p>The <code>App</code> function returns a JSX expression. This expression defines what your browser ultimately renders to the DOM.</p> + +<p>Some elements in the expression have attributes, which are written just like in HTML, following a pattern of <code>attribute="value"</code>. On line 3, the opening <code><a href="/en-US/docs/Web/HTML/Element/div"><div></a></code> tag has a <code>className</code> attribute. This the same as the <code><a href="/en-US/docs/Web/HTML/Global_attributes/class">class</a></code> attribute in HTML, but because JSX is JavaScript, we can't use the word <code>class</code> – it's reserved, meaning JavaScript already uses it for a specific purpose and it would cause problems here in our code. A few other HTML attributes are written differently in JSX than they are in HTML too, for the same kind of reason. We'll cover them as we encounter them.</p> + +<p>Take a moment to change the <code><a href="/en-US/docs/Web/HTML/Element/p"><p></a></code> tag on line 6 so that it reads "Hello, world!", then save your file. You'll notice that this change is immediately rendered in the development server running at <code>http://localhost:3000</code> in your browser. Now delete the <code><a href="/en-US/docs/Web/HTML/Element/a"><a></a></code> tag and save; the "Learn React" link will be gone.</p> + +<p>Your <code>App</code> component should now look like this:</p> + +<pre class="brush: js notranslate">function App() { + return ( + <div className="App"> + <header className="App-header"> + <img src={logo} className="App-logo" alt="logo" /> + <p> + Hello, World! + </p> + </header> + </div> + ); +}</pre> + +<h3 id="Export_statements">Export statements</h3> + +<p>At the very bottom of the <code>App.js</code> file, the statement <code>export default App</code> makes our <code>App</code> component available to other modules.</p> + +<h2 id="Interrogating_the_index">Interrogating the index</h2> + +<p>Let’s open <code>src/index.js</code>, because that's where the <code>App</code> component is being used. This file is the entry point for our app, and it initially looks like this:</p> + +<pre class="brush: js notranslate">import React from 'react'; +import ReactDOM from 'react-dom'; +import './index.css'; +import App from './App'; +import * as serviceWorker from './serviceWorker'; + +ReactDOM.render(<App />, document.getElementById('root')); + +// If you want your app to work offline and load faster, you can change +// unregister() to register() below. Note this comes with some pitfalls. +// Learn more about service workers: https://bit.ly/CRA-PWA +serviceWorker.unregister();</pre> + +<p>As with <code>App.js</code>, the file starts by importing all the JS modules and other assets it needs to run. <code>src/index.css</code> holds global styles that are applied to our whole app. We can also see our <code>App</code> component imported here; it is made available for import thanks to the <code>export</code> statement at the bottom of <code>App.js</code>.</p> + +<p>Line 7 calls React’s <code>ReactDOM.render()</code> function with two arguments:</p> + +<ul> + <li>The component we want to render, <code><App /></code> in this case.</li> + <li>The DOM element inside which we want the component to be rendered, in this case the element with an ID of <code>root</code>. If you look inside <code>public/index.html</code>, you'll see that this is a <code><div></code> element just inside the <code><body></code>.</li> +</ul> + +<p>All of this tells React that we want to render our React application with the <code>App</code> component as the root, or first component.</p> + +<div class="blockIndicator note"> +<p><strong>Note</strong>: In JSX, React components and HTML elements must have closing slashes. Writing just <code><App></code> or just <code><img></code> will cause an error.</p> +</div> + +<p><a href="/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers">Service workers</a> are interesting pieces of code that help application performance and allow features of your web applications to work offline, but they’re not in scope for this article. You can delete line 5, as well as lines 9 through 12.</p> + +<p>Your final <code>index.js</code> file should look like this:</p> + +<pre class="brush: js notranslate">import React from 'react'; +import ReactDOM from 'react-dom'; +import './index.css'; +import App from './App'; + +ReactDOM.render(<App />, document.getElementById('root'));</pre> + +<h2 id="Переменные_и_свойства">Переменные и свойства</h2> + +<p>Next, we'll use a few of our JavaScript skills to get a bit more comfortable editing components and working with data in React. We'll talk about how variables are used inside JSX, and introduce props, which are a way of passing data into a component (which can then be accessed using variables).</p> + +<h3 id="Variables_in_JSX">Variables in JSX</h3> + +<p>Back in <code>App.js</code>, let’s focus on line 9:</p> + +<pre class="brush: js notranslate"><img src={logo} className="App-logo" alt="logo" /></pre> + +<p>Here, the <code><img /></code> tag's <code>src</code> attribute value is in curly braces. This is how JSX recognizes variables. React will see <code>{logo}</code>, know you are referring to the logo import on line 2 of our app, then retrieve the logo file and render it.</p> + +<p>Let's try making a variable of our own. Before the return statement of <code>App</code>, add <code>const subject = 'React';</code>. Your <code>App</code> component should now look like this:</p> + +<pre class="brush: js notranslate">function App() { + const subject = "React"; + return ( + <div className="App"> + <header className="App-header"> + <img src={logo} className="App-logo" alt="logo" /> + <p> + Hello, World! + </p> + </header> + </div> + ); +}</pre> + +<p>Change line 8 to use our <code>subject</code> variable instead of the word "world", like this:</p> + +<pre class="brush: js notranslate">function App() { + const subject = "React"; + return ( + <div className="App"> + <header className="App-header"> + <img src={logo} className="App-logo" alt="logo" /> + <p> + Hello, {subject}! + </p> + </header> + </div> + ); +}</pre> + +<p>When you save, your browser should display "Hello, React!" instead of "Hello, world!"</p> + +<p>Variables are convenient, but the one we've just set doesn’t make great use of React's features. That's where props come in.</p> + +<h3 id="Component_props">Component props</h3> + +<p>A <strong>prop</strong> is any data passed into a React component. Props are written inside component calls, and use the same syntax as HTML attributes — <code>prop="value"</code>. Let’s open <code>index.js</code> and give our <code><App/></code> call its first prop.</p> + +<p>Add a prop of <code>subject</code> to the <code><App/></code> component call, with a value of <code>Clarice</code>. When you are done, your code should look something like this:</p> + +<pre class="brush: js notranslate">ReactDOM.render(<App subject="Clarice" />, document.getElementById('root'));</pre> + +<p>Back in <code>App.js</code>, let's revisit the App function itself, which reads like this (with the <code>return</code> statement shortened for brevity):</p> + +<pre class="brush: js notranslate">function App() { + const subject = "React"; + return ( + // return statement + ); +}</pre> + +<p>Change the signature of the <code>App</code> function so that it accepts <code>props</code> as a parameter. Just like any other parameter, you can put <code>props</code> in a <code>console.log()</code> to read it out to your browser's console. Go ahead and do that after your <code>subject</code> constant but before the <code>return</code> statement, like so:</p> + +<pre class="brush: js notranslate">function App(props) { + const subject = "React"; + console.log(props); + return ( + // return statement + ); +}</pre> + +<p>Save your file and check your browser's JavaScript console. You should see something like this logged:</p> + +<pre class="brush: js notranslate">Object { subject: "Clarice" }</pre> + +<p>The object property <code>subject</code> corresponds to the <code>subject</code> prop we added to our <code><App /></code> component call, and the string <code>Clarice</code> corresponds to its value. Component props in React are always collected into objects in this fashion.</p> + +<p>Now that <code>subject</code> is one of our props, let's utilize it in <code>App.js</code>. Change the <code>subject</code> constant so that, instead of defining it as the string <code>React</code>, you are reading the value of <code>props.subject</code>. You can also delete your <code>console.log()</code> if you want.</p> + +<pre class="brush: js notranslate">function App(props) { + const subject = props.subject; + return ( + // return statement + ); +}</pre> + +<p>When you save, the the app should now greet you with "Hello, Clarice!". If you return to <code>index.js</code>, edit the value of <code>subject</code>, and save, your text will change.</p> + +<h2 id="Резюме">Резюме</h2> + +<p>This brings us to the end of our initial look at React, including how to install it locally, creating a starter app, and how the basics work. In the next article we'll start building our first proper application — a todo list. Before we do that, however, let's recap some of the things we’ve learned.</p> + +<p>In React:</p> + +<ul> + <li>Components can import modules they need, and must export themselves at the bottom of their files.</li> + <li>Component functions are named with <code>PascalCase</code>.</li> + <li>You can read JSX variables by putting them between curly braces, like <code>{so}</code>.</li> + <li>Some JSX attributes are different to HTML attributes, so that they don't conflict with JavaScript reserved words. For example, <code>class</code> in HTML translates to <code>className</code> in JSX. Note that multi-word attributes are camel-cased.</li> + <li>Props are written just like attributes inside component calls, and are passed into components.</li> +</ul> + +<p>{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}</p> + +<h2 id="В_этом_модуле">В этом модуле</h2> + +<ul> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction">Introduction to client-side frameworks</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features">Framework main features</a></li> + <li>React + <ul> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started">Getting started with React</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning">Beginning our React todo list</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components">Componentizing our React app</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_events_state">React interactivity: Events and state</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_filtering_conditional_rendering">React interactivity: Editing, filtering, conditional rendering</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_accessibility">Accessibility in React</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_resources">React resources</a></li> + </ul> + </li> + <li>Ember + <ul> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_getting_started">Getting started with Ember</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_structure_componentization">Ember app structure and componentization</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_interactivity_events_state">Ember interactivity: Events, classes and state</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_conditional_footer">Ember Interactivity: Footer functionality, conditional rendering</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_routing">Routing in Ember</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources">Ember resources and troubleshooting</a></li> + </ul> + </li> + <li>Vue + <ul> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started">Getting started with Vue</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component">Creating our first Vue component</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_rendering_lists">Rendering a list of Vue components</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_methods_events_models">Adding a new todo form: Vue events, methods, and models</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_styling">Styling Vue components with CSS</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_computed_properties">Using Vue computed properties</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_conditional_rendering">Vue conditional rendering: editing existing todos</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_refs_focus_management">Focus management with Vue refs</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_resources">Vue resources</a></li> + </ul> + </li> +</ul> |
