Skip to content

Commit

Permalink
Дополняет доку <output> (#4702)
Browse files Browse the repository at this point in the history
* Дополняет текст

* Причёсывет демку

* Делает дополнения, улучшает демо

* Добавляет новую демку

* Изменяет высоту демки

* Добавляет начертание

* Добавляет `aria-controls`
  • Loading branch information
TatianaFokina authored Oct 3, 2023
1 parent 5384b46 commit 32c8b72
Show file tree
Hide file tree
Showing 3 changed files with 255 additions and 42 deletions.
83 changes: 51 additions & 32 deletions html/output/demos/form-rating/index.html
Original file line number Diff line number Diff line change
@@ -1,41 +1,52 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<title>Пример использования — <output> — Дока</title>
<title>Пример использования <output> <output> — Дока</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto&display=swap">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap">
<style>
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
box-sizing: border-box;
}

html {
height: 100%;
color-scheme: dark;
font-size: 18px;
}

body {
margin: 0;
padding: 20px;
min-height: 100vh;
padding: 50px;
display: flex;
align-items: center;
justify-content: center;
background-color: #18191C;
color: #ffffff;
font-size: 18px;
color: #FFFFFF;
font-family: "Roboto", sans-serif;
}

p {
margin-bottom: 12px;
text-align: center;
.form-row {
display: flex;
align-items: center;
justify-content: space-between;
}

.form-rating {
max-width: 260px;
margin-right: auto;
margin-left: auto;
.form-rating__item {
width: 450px;
display: flex;
align-items: center;
}

.form-rating__item-title {
margin-right: 55px;
font-size: 24px;
font-weight: 500;
line-height: 1;
}

.form-rating__output {
Expand All @@ -44,34 +55,42 @@
align-items: center;
width: 32px;
height: 32px;
margin-right: 12px;
border: 1px solid currentColor;
margin-left: 12px;
border: 1px solid #FF8630;
border-radius: 4px;
font-size: 16px;
font-size: 0.9rem;
line-height: 1;
color: #ffffff;
}

.form-rating__controls {
display: inline-flex;
align-items: center;
}

.form-rating__range {
.form-rating__item-range {
width: 100%;
margin-right: 8px;
margin-left: 8px;
accent-color: #FF8630;
}

@media (max-width: 768px) {
body {
padding: 30px;
}

.form-rating__item {
width: 100%;
}
}
</style>
</head>
<body>

<p>Оцените удобство пользования сервисом:</p>
<form class="form-rating" oninput="rating.value = parseInt(rating_range.value)">
<output name="rating" for="serviceRating" class="form-rating__output">10</output>
<div class="form-rating__controls">
<span>0</span><input type="range" name="rating_range" id="serviceRating" min="0" max="10" value="10" class="form-rating__range"><span>10</span>
<form class="form-rating" oninput="rating.value = parseInt(rating__range.value)">
<div class="form-row">
<div class="form-rating__item">
<label class="form-rating__item-title" for="serviceRating">Удобство сервиса:</label>
<span>0</span>
<input type="range" name="rating__range" id="serviceRating" min="0" max="10" value="10" class="form-rating__item-range">
<span>10</span>
</div>
<output role="status" name="rating" for="serviceRating" class="form-rating__output">10</output>
</div>
</form>

</body>
</html>
171 changes: 171 additions & 0 deletions html/output/demos/toast-notification/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<title>Всплывающее уведомление (тост) — <output> — Дока</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap">
<style>
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}

html {
color-scheme: dark;
font-size: 18px;
}

body {
min-height: 100vh;
padding: 50px;
display: flex;
align-items: center;
justify-content: center;
background-color: #18191C;
color: #FFFFFF;
font-family: "Roboto", sans-serif;
}

.container {
display: flex;
flex-direction: column;
align-items: center;
max-width: 480px;
width: 100%;
}

.button {
display: block;
width: 210px;
border: 2px solid transparent;
border-radius: 6px;
padding: 9px 15px;
color: #000000;
font-size: 1rem;
font-weight: 300;
font-family: inherit;
transition: background-color 0.2s linear;
}

.toast__button {
display: block;
position: absolute;
right: 0;
top: 0;
bottom: 0;
margin: auto;
padding: 10px 10px;
color: #000000;
border: 0;
border-left: 2px solid #FFFFFF;
font-size: 1rem;
font-weight: 300;
font-family: inherit;
transition: background-color 0.2s linear;
z-index: 1;
}

.button-orange {
background-color: #FF8630;
}

.button:hover, .toast__button:hover {
background-color: #FFFFFF;
cursor: pointer;
transition: background-color 0.2s linear;
}

.button:focus-visible, .toast__button:focus-visible {
border: 2px solid #FFFFFF;
outline: none;
}

.button:focus, .toast__button:focus {
border: 2px solid #FFFFFF;
outline: none;
}

.toast {
position: fixed;
bottom: .4em;
left: 0;
right: 0;
max-width: 500px;
margin: auto;
padding: 10px 40px;
text-align: left;
font-size: calc(1rem - 2px);
color: #000000;
background-color: #FFFFFF;
opacity: 0;
transform: translateY(0);
transition:
transform .2s ease-in-out,
opacity .2s ease-in-out;
}

.toast.toast--open {
opacity: 1;
transform: translateY(-4em);
}

@media (max-width: 768px) {
body {
padding: 30px;
}

.toast {
max-width: 100%;
}
}
</style>
</head>
<body>
<div class="container">
<button class="button button-orange" onclick="show()" aria-controls="message">Сохранить</button>
<div class="toast">
<output role="status" id="message"></output>
<button class="toast__button button-orange" onclick="dismiss()" aria-label="Закрыть">X</button>
</div>
</div>
<script>
const toastContainer = document.querySelector('.toast')
const toastMessage = toastContainer.querySelector('output')
const showedToastMessage = 'toast--open'
let timer = undefined
let init

const show = function () {
if (typeof timer === 'number') {
clear()
}
init = event.target
toastMessage.innerHTML = '<p>' + 'Документ успешно сохранён.' + '</p>'
toastContainer.classList.add(showedToastMessage)
timer = setTimeout(autoDismiss, 5000)
}

const clear = function () {
window.clearTimeout(timer)
}

const dismiss = function ( ) {
init.focus()
autoDismiss()
}

const autoDismiss = function () {
toastContainer.classList.remove(showedToastMessage)

timer = setTimeout(function () {
toastMessage.innerHTML = ''
timer = undefined
}, 1000)
}
</script>
</body>
</html>
43 changes: 33 additions & 10 deletions html/output/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ title: "`<output>`"
description: "Элемент для вывода результатов вычислений или действий пользователя."
authors:
- webdb81
contributors:
- tatianafokina
keywords:
- вывод результата
- поле вывода
- live regions
- интерактивная область
- живая область
related:
- js/query-selector
- a11y/role-status
- html/form
- js/element-innertext
tags:
Expand All @@ -18,14 +23,23 @@ tags:

Тег `<output>` позволяет выводить результаты вычислений или действий пользователя. Относится к элементам семантической вёрстки.

У тега есть встроенная роль [`status`](/a11y/role-status/). Благодаря ей [скринридеры](/a11y/screenreaders/) и другие вспомогательные технологии автоматически зачитывают содержимое тега, когда оно обновляется. Это делает часть страницы интерактивной или «живой» областью.

## Пример

```html
<form>
<p>Для скольких людей надо приготовить яичницу:</p>
<input type="number" name="peoples" oninput="eggs.value = (parseInt(peoples.value) * 2)">
<label for="people-num">
Для скольких людей приготовить яичницу:
</label>
<input
type="number"
id="people-num"
name="people"
oninput="eggs.value = (parseInt(people.value) * 2)"
>
<p>Необходимое количество яиц:</p>
<output name="eggs"></output>
<output role="status" name="eggs" for="people-num"></output>
</form>
```

Expand All @@ -34,16 +48,25 @@ tags:
Элемент `<output>` используется в тех случаях, когда пользователю надо показать результат работы программы в реальном времени, например:

- информация, которую пользователь вводит или изменяет в форме;
- вывод расчётов по данным, которые указал пользователь (калькулятор, гороскоп и тому подобное).
- вывод расчётов по данным, которые указал пользователь (калькулятор, гороскоп и тому подобное);
- всплывающие уведомления — тосты.

## Как пишется

**[`for`](/html/for/)** — значением может быть один или несколько ID, разделённых пробелом. Указывает на связь перечисленных элементов ввода (например, [`<input>`](/html/input/)) с элементом `<output>`.
**`form`** — указывается ID формы в этом же документе, с которой связывается поле вывода.
**`name`** — имя поля вывода. Используется для подписи результата при отправке формы.
- [`for`](/html/for/) — значением может быть один или несколько ID, разделённые пробелом. Указывает на связь перечисленных элементов ввода (например, [`<input>`](/html/input/)) с элементом `<output>`.
- `form` — указывается ID формы в этом же документе, с которой связывается поле вывода.
- `name` — имя поля вывода. Используется для подписи результата при отправке формы.

Чтобы тег работал во всех браузерах и со всеми скринридерами корректно, рекомендуют явно задавать ему `role="status"`.

Тег `<output>` парный. Допустимо вставлять пустой тег в разметку и _класть_ выводимое значение внутрь него при помощи JavaScript.
`<output>` парный тег. Допустимо вставлять пустой тег в разметку и _класть_ выводимое значение внутрь него при помощи JavaScript.

К тегу `<output>` также применяются все [глобальные атрибуты](/html/global-attrs/).

<iframe title="Пример использования в форме с рейтингом" src="demos/form-rating/" height="140"></iframe>
`<output>` можно связать с рейтингом, чтобы увидеть числовой результат.

<iframe title="Пример использования в форме с рейтингом" src="demos/form-rating/" height="200"></iframe>

Также тег можно использовать для вывода всплывающих уведомлений.

<iframe title="Пример всплывающего уведомления" src="demos/toast-notification/" height="350"></iframe>

0 comments on commit 32c8b72

Please sign in to comment.