Задание сверстать упрощенную страницу Aviasales и реализовать основной функционал отложенной загрузки предложений авиабилетов, фильтрации по кол-ву пересадок и изменения цены билета в выбранной валюте.
От себя добавил простую анимацию на спиннер:
и иконку на ничего не найдено:
- Используя React/Redux/JS написал приложение, которое рендерит предложения по авиаперевозкам
- Написал фильтр по количеству перелетов
- Написал логику переключения валюты контракта
- Сделал что json файл с данными по предложениям подтягивался асинхронно с локального сервера при инициализации (с небольшой задержкой)
- Добавил запрос к внешнему апи для получения данных о свежих курсах валют
- Добавил css спиннер для анимации ожидания загрузки предложений
- Добавил svg-смайлик при отсуствии билетов (например если снять галочки со всех вариантов перелетов)
- Вверху добавил логотип шара с ракетой (как на макете), из Sketch убрал с нее тени и переимпортировал в svg
Самое большое время заняло рисование блочка выбора валюты - pixel-perfect на css. Как видно на макетах, граница внутри выделенной области имеет толщину 1 пиксель - квадратной формы.
Если делать в лоб бордерами - то получаются двойные границы:
Таким образом необходимо делать border
между опциями - 1 px - одним border'ом.
Второй вариант - который я попробовал - это прозрачный цвет рамки - но тогда получается уголки
Третий вариант на которым я работал несколько часов - был без прозрачных границ. Дело в том что структура html выглядит так
<input type="radio">
<div>Первый</div>
<input type="radio">
<div>Второй</div>
<input type="radio">
<div>Третий</div>
Она обусловлена тем - что работа со стилями выбранного чекбокса ведется из css. То есть чтобы сделать выделенными div
"Первый" - если перед ним выбран чекбокс можно в css написать input:checked + div {}
- и таким образом со стилями работать
только из css.
Но данная структура сложна для стайлинга из-за того что очень сложно оперировать существующими css
селекторами.
Фактически нет способа например при hover'e на втором div'e сказать подсветить правую сторону предыдущего дива.
Во-первых, нет такого селектора, а во-вторых предыдущий див находится не рядом, а через <input>
от него.
Долго работая на стайлингом border'ов - наконец получилось договориться с css - получилось так:
Ссылка на код
В данном случае - сначала я пытался сделать так чтобы центральный элемент не имел правой и левой границы, а их имели только левый и правый элементы. Соответственно при hover'e на центральный элемент - нужно было подсвечивать правую границу левого блока и левую границу правого блока... и если границу правого блока было возможно подсветить - то границу левого блока - практически не возможно.
Помучившись с селекторами порядочно - я попробовал поменять подход. Теперь центральный элемент имеет все 4 границы, а левый и правый элементы не имею правых и левых рамок соответственно. Этот вариант подошел, но пришлось - добавлять правило - что при ховере над всем блоком - если это не второй див и ховер на нем -то подсвечивать правую границу(что это если не хак?).
Получилось достойно - но как видно - опять получилось - рамочка - с выпадающим пикселем. Теперь пиксель выпадал не внутри, а снаружи.
Соответственно - последний вариант, который мог подойти - это сделать рамки на псевдо элементах :before
.
Помучившись с ними некоторое время - мне кажется результат удовлетворительным. Понятно что при расширении кол-ва вариантов валют -
его придется пересматривать - тем не менее в текущем исполнении - он мне представляется pixel-perfect.
Кроме того - если валюты 3 - то кажется - логичным использовать такую радио-кнопку, если же их больше - то кажется семантичней и симпатичней - использовать селект (как сейчас это делается на aviasales.ru).
Финальная реализация - подразумевает отсутствие внутренних рамок между div
'ами. Рамки задаются псевоблоками на :before.
По этой причине - их возможно (с некоторыми трудностями) выбирать через css
. Левая граница это блок :before, а права рамка - это
идущий следом блок, который можно выбрать через ~
.
Из-за того что левая граница теперь не предыдущий div
(который невозможно выбрать css-селектором), а свой элемент :before
,
стала возможной текущая реализация.