«Хочу как Дуров»: пишем простой мессенджер
Знание того, как устроен мессенджер, может сильно вам пригодиться, ведь они становятся всё популярнее. Прочитав эту статью, вы сможете его получить.
В последнее время растёт популярность приложений для обмена сообщениями. Пользователи предпочитают мессенджеры, потому что они позволяют взаимодействовать в режиме реального времени. В этой статье мы разберём процесс создания простого приложения для обмена мгновенными сообщениями. Не будем сильно углубляться в нюансы разработки: мы напишем рабочий мессенджер, который в дальнейшем можно будет улучшить.
Статья подойдёт состоявшимся программистам и тем, кто только интересуется, как войти в IT.
Используемые технологии и инструменты
- Стек MEAN (Mongo, Express, Angular, Node).
- Сокеты для прямого обмена сообщениями.
- AJAX для регистрации и входа.
Подготовка
Структура будущего приложения выглядит примерно так:
Установите Node.js и MongoDB. Кроме того, нам понадобится библиотека AngularJS, скачайте её и скопируйте в папку lib каталога Client.
Чтобы сделать пользовательский интерфейс приложения привлекательнее, вы можете воспользоваться любой CSS-библиотекой. Скачайте её и скопируйте в lib .
Серверная часть
Шаг 1. Запуск проекта
Перейдите в каталог Server и выполните команду:
npm init
Она запустит новый проект.
Укажите все необходимые сведения. В результате будет создан файл package.json примерно следующего вида:
< "name": "chat", "version": "1.0.0", "description": "Chat application", "main": "server.js", "scripts": < "test": "echo \"Error: no test specified\" && exit 1" >, "author": "Your name", "license": "ISC" >
Шаг 2. Установка зависимостей
- socket.io — JavaScript-библиотека, которая предоставляет двустороннюю связь клиента и сервера в режиме реального времени;
- express — фреймворк Node.js, предоставляющий набор функций для разработки мобильных и веб-приложений. Позволяет отвечать на HTTP-запросы, используя промежуточное ПО, а также отображать HTML-страницы.
Выполнение этих команд установит необходимые зависимости и добавит их в package.json :
npm install --save socket.io npm install --save express
Выглядеть они будут примерно так:
"dependencies":
Шаг 3. Создание сервера
Создадим сервер, который обслуживает порт 3000 и возвращает HTML-файл при вызове. Для инициализации нового соединения сокету нужно передать HTTP-объект. Событие connection будет прослушивать входящие сокеты, каждый сокет будет выпускать событие disconnect, которое будет вызвано при отключении клиента. Мы будем использовать следующие функции:
- socket.on(. ) — ожидает событие, и когда оно происходит, то выполняет функцию обратного вызова.
- io.emit(. ) — используется для отправки сообщения всем подключенным сокетам.
socket.on('event', function(msg)<>) io.emit('event', 'message')
Создайте сервер с именем server.js . Он должен:
- Выводить сообщение в консоль при подключении пользователя.
- Слушать событие chat message и транслировать полученное сообщение на все подключенные сокеты.
- Когда пользователь отключается, выводить сообщение в консоль.
В результате ваш сервер будет выглядеть примерно так:
var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); app.get('/', function(req, res)< res.sendfile('index.html'); >); io.on('connection', function(socket)< console.log('user connected'); socket.on('chat message', function(msg)< io.emit('chat message', msg); >); socket.on('disconnect', function()< console.log('user disconnected'); >); >); http.listen(3000, function()< console.log('listening on *:3000'); >);
Клиентская часть
Создайте файлы index.html в каталоге Client, style.css в каталоге CSS и app.js в каталоге js.
Client/index.html
Пусть это будет простой HTML-код, который получает и отображает наши сообщения.
Включите скрипты socket.io-client и angular.js в ваш HTML:
socket.io служит для нас клиентом. Он по умолчанию подключается к хосту, обслуживающему страницу.
В результате index.html должен выглядеть примерно так:
Как сделать мессенджер на html
Добавь plugin A Messenger Chat на сайт HTML без написания кода и без головной боли

Если ваш веб-сайт HTML запущен и работает, вы преодолели первую серьезную проблему на пути к расширению присутствия своего бизнеса в интернете. поздравляю!
Но дальше идет a tough question: как entice, captivate, turn и поддержать больше посетителей?

Добавление Messenger Chat plugin — это proven метод увеличения взаимодействия с пользователем и конверсии , который часто proposed веб-профессионалами считается лучшим методом для amplifying

Некоторые компании сначала take a stab at делают все своими руками (diy) Messenger Chat или имеют «computer guru», который утверждает, что он / она может построить a Messenger Chat in ‘no time’.
Другие пытаются найти приложения с открытым исходным кодом Messenger Chat или companies abroad, которые allegedly предлагают Messenger Chat приложения at rock-bottom prices.
Кроме того, настройка и обновление Messenger Chat требует еще больше времени и может вызвать новые проблемы или ошибки.
По мере роста вашей компании вы, вероятно, столкнетесь с проблемами безопасности, поскольку хакеры могут попытаться использовать Messenger Chat уязвимости в системе безопасности.
По мере роста посещаемости сайта повышенная нагрузка может вызвать проблемы с отображением Messenger Chat. Нет ничего хуже, чем Messenger Chat that stops working на видном месте, как и ваш трафик soars благодаря кампании thriving!

Поскольку веб-технологии advance, пользовательские и собственные Messenger Chat приложения потребуют больше времени и средств от keeping вашего «веб-мастера», чтобы обновить ваш сайт и сохранить его running.
Вот почему большинство серьезных компаний выбирают профессиональные hosting service Messenger Chat решения, такие как powr.
Для начала powr Messenger Chat для website предлагает интуитивно понятную настройку, которая может быть выполнена без кода. Запатентованный редактор powr editor позволяет настраивать wysiwyg (то, что вы видите, то и получаете), позволяя вам делать Messenger Chat обновления в реальном времени на вашей действующей странице hosting service.
Легко настраиваемый
Каждая деталь, такая как шрифты, цвета, границы и интервалы, может modified сделать ваш бренд индивидуальным stand out.
Мобильный Отзывчивый
Дизайн автоматически адаптируется и выглядит fantastic на любом мобильном устройстве, планшете или в веб-браузере.
Кодирование не требуется
Просто скопируйте и вставьте его на свой HTML веб-сайт.

Поскольку powr рассчитан на масштабирование, он имеет самые передовые встроенные средства безопасности и доступные возможности большого объема.

and to top it off, доступна служба поддержки at all times, and so is the справочный центр .
Кроме того, наша команда опытных инженеров работает круглосуточно, чтобы приложения powr, такие как ваш HTML Messenger Chat, работали на вас.
Встраивание приложения Messenger Chat на ваш сайт HTML никогда не было проще
Создайте свое собственное приложение Messenger Chat HTML, подберите стиль и цвета своего веб-сайта и добавьте Messenger Chat на свою страницу HTML, пост, боковую панель, нижний колонтитул или где угодно на своем сайт.


most importantly, powr Messenger Chat имеет time-tested результатов. тематические исследования показали, что конверсии от powr Messenger Chat до maximize превышают 30%!
Доверие миллионов
Мы обеспечиваем качество, о чем свидетельствуют более 12 387 отзывов.
1200348
Установок a Messenger Chat
8230145
ПЛАГИНЫ НА САЙТАХ


Просто
Легко ориентироваться для нетехнического человека, как я. перепробовал так много приложений, и это лучшее сочетание отличных функций для любого магазина.
Пасар Сегар | Свежий рынок в Form Builder

Это приложение было бесшовным
Это помогло мне привлечь трафик на мой сайт и привлечь больше платформ! я очень рекомендую всем!

Это приложение было бесшовным
Я был удивлен, что shopify не имеет встроенной функции для чего-то подобного, но рад, что ваше приложение отвечает всем требованиям.
Если вы все еще have questions, то take a look at то, что есть у rbia shades, компании по производству солнцезащитных очков, creates ручной работы в деревянных рамах, been able to create.

За a small amount of time подписку с помощью всплывающего окна powr они смогли boost расширить свои контакты более чем на 250% (более 600 реальных контактов) и constantly расширили свои социальные сети до более 6000 подписчиков, использующих powr social кормить на их сайте. они added powr slider как визуальный способ быстро показать своим клиентам, поскольку они являются landing on домашней страницей, как продукты выглядят в реальной жизни. он хорошо демонстрирует их продукты и беспрепятственно дает клиентам отличный опыт работы на месте. фактически они reported, что посетители, которые взаимодействовали с приложениями powr на их сайте, были вовлечены в 2,5 раза дольше, чем любой другой человек на их сайте.
Через несколько месяцев после publicizing своего бизнеса на местных ярмарках и ремесленных выставках rbia shades искала способ продавать товары в интернете. они wanted, чтобы показать посетителям качество своего продукта, свой легкий и эргономичный дизайн в привлекательной визуальной форме. их hosting service не предоставили для этого адекватного решения. они попробовали many different options, прежде чем нашли powr slider, и ни один из них не выглядел как часть сайта, был неуклюжим и трудным в использовании.
Чат / Мессенджер JavaScript шаблон
Вы можете свободно редактировать и изменять шаблон под собственные требования или использовать его в качестве примера для изучения принципов и логики построения UI интерфейса при помощи библиотеки Webix.

Скачать Чат / Мессенджер JavaScript шаблон
Все пользователи библиотеки Webix могут воспользоваться данным шаблоном. Чтобы скачать исходный код, нажмите на ссылку ниже.
* Для работы с шаблонами нашей библиотеки Вам понадобится исходный код самой библиотеки Webix. Скачать его можно на этой странице.
Условия распространения
Этот шаблон распространяется под лицензией: MIT License (MIT) Copyright (c) 2021 XBSoftware.
Если у Вас есть вопросы, Вы можете уточнить их, связавшись с нами через контактную форму.
Разработка настоящих компонентов: блок сообщения Facebook Messenger
Смесь любопытства и тяги к исследованиям снова привели меня к системе обмена сообщениями Facebook. Я уже изучал компоненты Facebook и писал об этом. Сейчас я обратил внимание на то, что в одни только блоки для вывода сообщений чата вложена огромная работа. На первый взгляд может показаться, что разработка компонента, реализующего чат — это просто, что у составных частей такого компонента будет не особенно много вариаций.
Если же вникнуть в тему работы с сообщениями, то окажется, что один только интерфейс чата — это такая штука, при создании которой нужно учесть невероятное количество деталей. Особенно — если это чат некоей платформы, сравнимой по масштабам с Facebook.

В этой статье я расскажу об устройстве компонента, представляющего собой блок сообщения Facebook Messenger, покажу варианты его стилизации, поделюсь некоторыми интересными находками.
Предварительные сведения
Для того чтобы было понятнее — сразу показываю блок сообщения, о котором пойдёт речь.

Блок сообщения
Кажется, что всё тут устроено довольно просто. Но если задуматься о различных вариантах такого компонента, получится, что это совсем не так. Я, чтобы лучше понять ход мыслей дизайнеров Facebook, воссоздал разные варианты блока сообщений в Figma.

Разновидности блоков сообщений
Написание HTML- и CSS-кода для подобного компонента — это нетривиальная (но очень интересная) задача. В данном случае компонент чата должен быть динамическим для того чтобы справиться с выводом самого разного содержимого и служебной информации, для поддержки тем оформления и вывода текстов на разных языках.
Я, чтобы избежать путаницы, не буду хвататься сразу за всё. Вместо этого расскажу об анатомии блока сообщений.
Анатомия блока сообщений
Я употребил тут слово «анатомия» из-за того, что мне нравится, так сказать, «препарировать» пользовательские интерфейсы. Я в такие моменты прямо-таки вижу, как я, в лаборатории, за микроскопом, исследую устройство компонентов.
Для начала мне хотелось бы обратить ваше внимание на то, что структура отправленных и полученных сообщений различается.

Окно чата, LTR-язык
Если вы пишете слева направо (LTR, Left-To-Right), как, например, принято в английском языке, тогда блок с вашими сообщениями, синий, будет справа, а блок собеседника (серый) — слева.
Если же вы пользуетесь RTL-языком (Right-To-Left, справа налево), например — арабским, тогда блоки поменяются местами.

Окно чата, RTL-язык
Учитывая это — рассмотрим структуру компонента, реализующего блок сообщения.

Внешний контейнер (Outer container), внутренний контейнер (Inner container), аватар пользователя (Avatar), разделитель (Spacer), меню действий (Actions Menu), область вывода сообщения (Bubble), область вывода состояния сообщения (Status)
Блок сообщения чата состоит из следующих частей:
- Внешний контейнер, включающий в себя область вывода состояния сообщения, внутренний контейнер, аватар.
- Внутренний контейнер, в состав которого входят такие элементы, как область вывода сообщения, меню действий, разделитель.

Внешний и внутренний контейнеры блока сообщения
Возможно, вы обратите внимание на то, что область для вывода аватара очень мала. А где сам аватар? Это — хороший вопрос.
Выше показана структура сообщения в том виде, в котором его видит тот, кто это сообщение отправил. Если же речь идёт о принятом сообщении, то оно будет выведено в блоке, представляющим собой, по большей части, зеркальное отражение вышерассмотренного блока. Я, исследуя возможность создания этого «зеркального» блока без необходимости разработки отдельного компонента, кое-что выяснил.
А именно, положение первого и последнего элементов блока (аватара и состояния сообщения) не зависит от того, кто отправил сообщение. Они «отражаются» лишь в том случае, если меняется направление вывода текста (LRT на RTL или наоборот). Вот ещё некоторые наблюдения:
- Место для аватара зарезервировано даже в том случае, если аватар в нём не выводится. Если вы отправляете сообщение — это место будет пустым.
- Но если кто-то отправляет сообщение вам — в месте для аватара будет выведено соответствующее изображение.
- «Отражается» лишь внутренняя часть блока сообщения (внутренний контейнер), которая содержит поле для вывода содержимого сообщения, меню и разделитель.

Блоки отправленного и принятого сообщений
У такого решения есть одна ценная особенность: он отлично подходит и для LTR макетов, пример которого рассмотрен выше, и для RTL-макетов. Обратите внимание на то, что весь внешний контейнер автоматически «переворачивается» при использовании RTL-макетов.

LTR- и RTL-макеты блока отправленного сообщения
А вот — сводная схема, где показаны принятые и отправленные сообщения в LTR и RTL-исполнении.

LTR- и RTL-макеты блока отправленных и принятых сообщений
Выше я старался рассказывать об устройстве блока сообщений так, чтобы меня понял бы и тот, кто ничего не знает об HTML и CSS. В следующих разделах я расскажу о том, как реализовать все эти структуры в коде, уделив внимание их различным вариантам.
Базовый HTML- и CSS-код
Вот как выглядит базовая структура блока сообщения в HTML:
Вот базовые стили:
.message__outer < display: flex; >.message__inner
Ниже показан результат визуализации этого кода (я, чтобы внести предельную ясность в повествование, выделил границы элементов).

Базовый блок сообщения
Теперь можно заняться стилизацией внутренних областей блока. А именно, речь идёт об области для вывода сообщения, о меню и о разделителе.
.message__actions < width: 67px; padding-right: 5px; >.message__spacer

Стилизация внутренней части блока сообщения
Полагаю, то, что меню назначена фиксированная ширина, объясняется следующими причинами:
- Резервирование пространства для предотвращения сдвига макета.
- Улучшение возможностей управления внутренней частью макета. Например, при стилизации области вывода сообщения нужно использовать свойство max-width . Может понадобиться вычесть ширину области меню из ширины области вывода сообщения.
- Необходимо рассчитывать на то, что может возникнуть ситуация, когда элемент-разделитель, из-за нехватки места, придётся сжать.
- Нужно предотвратить уменьшение размеров области меню в маленьких областях просмотра.
- Нужно избежать чрезмерного растягивания блока вывода сообщения путём разбиения очень длинных слов.
.message__bubble < max-width: calc(100% - 67px); overflow-wrap: break-word; >.message__actions
Теперь поговорим о стилизации области вывода состояния сообщения и области вывода аватара (прямых потомков внешнего контейнера).
Работа с RTL- и LTR-текстами
Стоит упомянуть, что область вывода сообщения поддерживает представление текстов, написанных на RTL- и LTR-языках, благодаря использованию HTML-атрибута dir со значением auto .
Если в сообщении сначала был введён текст на RTL-языке (на арабском, например), то, даже если потом ввести текст на LTR-языке, он будет выровнен по правому краю.
И, аналогично, если сначала в поле был введён текст на LTR-языке (например — на английском), а потом — на RTL-языке, он будет выровнен по левому краю.

Выравнивание текстов в сообщениях, где одновременно используются RTL- и LTR-языки
Стилизация области вывода состояния сообщения
Область, используемая для вывода состояния сообщения, представляет собой элемент-обёртку, в котором могут выводиться различные значки.

Область вывода состояния сообщения
В данном контейнере могут выводиться различные элементы, указывающие, например, на то, что сообщение отправлено, доставлено или прочитано.

Различные значки, указывающие на состояние сообщения
Вот как выглядит HTML-разметка этого элемента:
Здесь, для выравнивания дочернего элемента по нижнему краю контейнера, использован Flexbox-макет. Обратите внимание на то, что свойству flex-direction назначено значение column .
.message__status
При таком подходе дочерний элемент всегда будет прижат к нижней части контейнера. Даже тогда, когда высота блока вывода сообщения очень велика. Это важно для тех случаев, когда выводятся сообщения, содержащие очень длинные предложения, сообщения, состоящие из нескольких строк, или содержащие изображения.

Высокие сообщения и область вывода состояния сообщения
Если вы пользуетесь Facebook, то вы, возможно, обратили внимание на то, как действует значок, указывающий на то, что сообщение прочитано. А именно, когда отправленное сообщение видит адресат, выводится аватар. При отправке другого сообщения место для вывода состояния сообщения остаётся пустым, но другие элементы его не занимают.

Значки, указывающие на состояние сообщения
Стилизация области вывода аватара отправителя сообщения
У элемента-обёртки для вывода аватара, по умолчанию, настроены свойства, задающие его горизонтальные поля, что позволяет зарезервировать место для аватара. Этот элемент оказывается пустым в том случае, если сообщение отправляете вы. А вот если сообщение отправляют вам — в этом элементе будет аватар отправителя.
.message__avatar
Когда обёртка аватара пуста, её ширина будет составлять 14px (сумма размеров полей 6px и 8px ).

Пустой элемент-обёртка для вывода аватара
Если же речь идёт о просмотре принятого сообщения — в элементе-обёртке будет выведено изображение аватара размером 28×28.

Элемент-обёртка с аватаром
Для того чтобы всё было бы предельно ясно — на следующем рисунке показаны элементы-обёртки аватара отправленного и полученного сообщения.

Отправленное и полученное сообщения
Стилизация меню
С каждым сообщением может быть связан набор действий, представленных командами меню, выводимого при наведении указателя мыши на соответствующую область:
- Работа с эмотиконами.
- Ответ на сообщение или его цитирование.
- Пересылка материалов сообщений (для сообщений с изображениями или видео).
- Дополнительные команды меню (три точки).
- У него есть правое поле в том случае, если речь идёт об области для вывода отправленного сообщения. В противном случае у него имеется левое поле.
- Оно, для получателя сообщения, представлено в отражённом виде с помощью flex-direction: row-reverse . Стандартный порядок его вывода применяется при выводе собственных сообщений у отправителя этих сообщений.
Вот схема «отражения» области вывода меню при просмотре собственных и полученных сообщений.

Область вывода меню в собственном и полученном сообщении
Если сообщение очень длинное, а так же — при отправке изображений или видео, меню должно быть центровано по вертикали. Этого можно добиться с использованием Flexbox-инструментов для выравнивания материалов.
.message__actions

Выравнивание меню при выводе длинных сообщений
Как так получается? Дело в том, что если в сообщении имеется длинный текст или изображение — элемент .message__actions растянется так, чтобы соответствовать высоте родительского элемента. Это — стандартное поведение Flexbox-макетов. Мы можем этим воспользоваться для того чтобы отцентровать меню по вертикали.
Теперь, когда мы разобрались с базовым блоком сообщений — поговорим о вариациях таких блоков.
Вывод нескольких блоков сообщений
Если отправить кому-то подряд несколько сообщений — для вывода блоков сообщений будут использоваться элементы, углы которых скруглены по-разному, причём, эти блоки ещё и по-разному выглядят для отправленных и принятых сообщений.

LTR- и RTL-макеты и различные блоки для вывода нескольких сообщений, отправленных или полученных друг за другом
Более того — области вывода сообщений меняются местами в LTR- и RTL-макетах. Хотелось бы мне, чтобы логические свойства border-radius пользовались бы достаточно хорошей поддержкой браузеров, позволяющей применять их в продакшне. Пока логические значения для свойств border-radius поддерживаются в браузере Chrome 89 (вышел 1 марта 2021 года).
Если бы эти свойства пользовались широкой поддержкой браузеров, то нашу задачу с их помощью можно было бы решить примерно так:
/* Отправитель, сообщения с синим фоном */ /* Первое сообщение */ .message--first .message__bubble < border-end-end-radius: 4px; >/* Сообщение, находящееся в середине набора сообщений */ .message--middle .message__bubble < border-start-end-radius: 4px; border-end-end-radius: 4px; >/* Последнее сообщение */ .message--last .message__bubble
Знаю, что «двойные» переменные, в названиях которых есть нечто вроде end-end , могут, на первый взгляд, показаться непонятными. Поэтому попробую раскрыть их смысл с помощью следующего рисунка.
Итак, у нас есть две оси (Block и Inline), каждая из них имеет значения start и end .

Если речь идёт о RTL-макете, то Start и End оси Inline меняются местами. При таком подходе нам не нужно переназначать значение для радиуса и менять направление. Обратите внимание на то, что на следующем рисунке, если сравнить его с предыдущим, Inline Start и Inline End поменялись местами.

Если вы хотите лучше разобраться с логическими CSS-свойствами — вот моя статья на эту тему.
Поддержка вывода изображений

Отправленное и принятое сообщения, содержащие изображения
Может показаться, что организовать поддержку вывода изображений разных размеров и обладающих различным соотношением сторон — это просто. Возможно, нужно всего лишь воспользоваться свойством max-width: 100% — и всё готово. Была у вас такая мысль? Но в случае с Facebook Messenger всё гораздо интереснее.
Когда пользователь выгружает изображение — его ширина задаётся во встроенном CSS-коде. Там ещё имеется и свойство padding-bottom: 56.66% для обеспечения отзывчивости изображения (это — так называемый «padding hack»).
.image < display: block; border-radius: 18px; border: 1px solid #0006; overflow: hidden; >.image__main < max-width: 480px; >.image__element < max-width: 100%; position: relative; >.image__aspectRatio < position: relative; >.image__wrapper < position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%; >.image__wrapper img
Все изображения должны подчиняться следующим правилам:
- Максимальная ширина изображения — 480px .
- Максимальная высота изображения — 200px .
- Соотношение сторон изображения не должно меняться при изменении его размеров.
- Если размеры изображения меньше вышеозначенных значений — оно должно выводиться в своём исходном состоянии.

Вывод изображений с разным соотношением сторон
Более того, важно помнить о том, что Flexbox-макет не сжимает изображения до размеров, которые меньше минимальных размеров содержимого такого макета. То есть — если довести ширину окна браузера до определённого значения — Flex-элемент не станет меньше, чем минимальные размеры его содержимого. Для того чтобы это исправить, нужно свойство min-width: 0 .

Макет, который нуждается в доработке
В моём демонстрационном коде Flex-элемент является прямым потомком message__outer , в нашем случае это — message__row .
.message__row < min-width: 0; /* другие стили */ >
Вот как всё должно выглядеть в том случае, если всё работает так, как должно работать.

Доработанный макет
Может, у кого-то возникнет мысль о том, что тут можно было бы дать изображению фиксированную ширину и воспользоваться встроенным CSS. Но надо понимать, что за каждым решением, даже небольшим, принятым разработчиками, стоит некая веская причина. Полагаю, что в данном случае всё дело в загружаемом изображении. Если бы не был задан фиксированный размер изображения — мы столкнулись бы со сдвигами макета.
Вывод нескольких изображений
Если пользователь отправляет в чате сразу несколько изображений, соотношения их сторон не учитываются. Вместо этого каждое изображение размещается в квадратной области, а волшебное свойство object-fit позволяет не искажать и не растягивать изображения.

Вывод нескольких изображений
.gallery < display: flex; flex-wrap: wrap; flex: 1; /* Отрицательное поле позволяет выровнять галерею с элементами того же уровня. */ margin: -2px; >.gallery__item < /* Добавить смещение размером 2px вокруг каждого изображения, что даст 4px для двух смежных изображений. */ padding: 2; >.gallery__item--third < flex: 33.33%; >.gallery__item--half
Вот что здесь происходит:
- Сетка для вывода изображений построена с использованием CSS Flexbox.
- Ширина изображения составляет треть или половину ширины Flexbox-контейнера, что зависит от количества изображений.
- Расстояние между изображениями регулируется путём настройки полей родительских элементов изображений.
- Чтобы не оставлять ненужных пустых пространств вокруг границ галереи, во Flex-контейнере должно быть использовано отрицательное значение свойства padding .
Если вы хотите углубиться в тему настройки расстояния между элементами с помощью CSS — взгляните на эту мою статью.
Цитирование сообщений

Процитированное сообщение и текст обычного сообщения
При выводе процитированного сообщения используются три основных элемента:
- Заголовок, показывающий, кто кому ответил (например — «You replied to Ahmad»).
- Процитированное сообщение, выведенное с использованием особого стиля.
- Текст сообщения.
Устроено оно просто и понятно — блок такого сообщения очень похож на блок обычного сообщения, но у него нет дополнительных элементов вроде меню и области для вывода состояния сообщения.
У сообщения (выведено серым) установлено большое значение свойства padding-bottom и отрицательное значение margin-bottom , что позволяет переместить текст процитированного сообщения выше, чем текст обычного сообщения. И наконец — его правый нижний угол не скруглён.
.message--washed
А вот — стиль для текста, где настраивается свойство padding-bottom .
.message--washed__text

Процитированное сообщение
То же самое касается и цитат в виде изображений.

Процитированное сообщение с изображением
Так же цитируются и вложения (вроде голосовых сообщений и видеозаписей).

Процитированное изображение с вложением
Реакции
«Реакция» это когда пользователь реагирует на сообщение, пользуясь эмотиконами. Эти «реакции» выводятся ниже сообщения. Вот пример.

«Реакция», выведенная под сообщением
2
Элемент, который накладывается на другой элемент, это — содержимое «реакции», а не родительский элемент.
.reaction__content
Кроме того, для того чтобы расположить элементы там, где находится начало родительского элемента, нужно выровнять их по Flexbox родительского уровня. Тут речь идёт о LTR-макетах, а в RTL-макетах всё делается с точностью до наоборот.
.msg-bubble-wrapper.with-reaction
Я заметил, что для того чтобы аватар оставался бы выровненным по нижней части сообщения, используется элемент , высота которого равняется 18px , играющий роль разделителя.

Размещение «реакций» в LTR и RTL-макетах
Или, если речь идёт о сообщении отправителя, используется следующая разметка.
Разметка списков сообщений
Разметка, используемая для оформления списков сообщений — это интересная тема. Тут имеется элемент с role=»grid» и с aria-label=»Messages in conversation with Ahmad Shadeed» .
В этом контейнере находятся элементы-строки с role=»row» , а внутри каждого такого элемента имеется главный элемент с role=»gridcell» .
Вот разметка, о которой идёт речь.
Но это ещё не всё. В каждом сообщении имеется визуально скрытый элемент с текстом You sent или Person sent , в зависимости от того, кто отправил сообщение.
You sent
Тут я обратил внимание на то, что одно из CSS-свойств, используемых для визуального скрытия текста — это clip-path: inset(50%) .
Вот — полный код стилизации:
.sr-only
Расстояние между сообщениями
Теперь, когда вы знаете о том, как выглядит разметка строк, в которых выводятся сообщения, поговорим о том, как настраивается расстояние между сообщениями. Делается это с помощью компонентов-разделителей, а не с помощью отступов или чего-то другого.
Каждая строка с сообщением имеет элемент-разделитель высотой 2px или 7px , или, в некоторых случаях, и тот и другой. На следующем рисунке розовые элементы — это разделители высотой 7px , а жёлтые — это разделители высотой 2px .

Элементы-разделители
Контейнер верхнего уровня каждого сообщения — это Flex-контейнер с flex-direction: column .
Вот, например, изображение процитированного сообщения. Тут имеются разделители обоих видов. Кроме того, используемый здесь родительский элемент верхнего уровня — это Flexbox-контейнер с flex-direction: column .

Разделители двух видов
Разделители блоков сообщений, содержащие сведения о времени
Разделитель блоков сообщений может содержать текст или сведения о времени. Тут я расскажу о тех, которые содержат сведения о времени.
Когда пообщаешься с кем-то, а потом снова возвращаешься в чат — там можно заметить отцентрованный элемент со сведениями о дне недели и времени.

Разделитель блоков сообщений
Для создания подобных элементов используется довольно-таки интересная разметка.
October 28 at 6:12 PM
Первый элемент предназначен исключительно для средств чтения с экрана. Понять это можно благодаря классу sr-only (подсказка: дизайнеры Facebook пользуются вспомогательными классами, я добавил тут класс sr-only только ради понятности изложения). Второй элемент скрыт от средств для чтения с экрана, он предназначен для пользователя. Интересно — правда?
Пользовательская стилизация фона блоков сообщений
Хотя мне эта возможность мессенджера и кажется бесполезной, я всё же о ней расскажу. Пользователь может настроить фон блоков сообщений с использованием градиентных цветов.

Градиентные цвета блоков сообщений
Когда пользователь прокручивает сообщения, всё выглядит так, будто их градиентная окраска анимирована.
Прокрутка списка сообщений с градиентной окраской
На первый взгляд может показаться, что это делается с помощью JavaScript, что у каждого сообщения имеется особое фоновое изображение, которое меняет позицию при прокрутке списка. Но на самом деле всё не так. Это — чистый CSS. Сейчас я расскажу о том, как достигнут подобный эффект.
Градиент, который мы видели, устанавливается для фона элемента-контейнера, содержащего список сообщений. То есть — окрашивается весь тот белый фон на котором расположены сообщения. Взгляните на следующий рисунок.
.messages-parent

Градиентный фон
Следующий шаг — убрать фоновый цвет и отключить скругление углов элементов, в которых выводятся сообщения (да, именно так всё и делается).

Настройка элементов, в которых выводятся сообщения
Далее — нужно задать белый фон буквально для всего, что имеется в интерфейсе — за исключением блоков, в которых выводятся сообщения (и это делается именно так).
.message__actions, .message__status, .spacer-xs, .spacer-lg, .message__spacer, .message__avatar

Продолжение работы над градиентным фоном
Может, эти рассуждения выглядят необычно. Я, чтобы доказать, что ничего не выдумал, привожу запись процесса исследования интерфейса Facebook Messenger.
Исследование интерфейса
Обратите внимание на то, что после того, как я включил градиентный фон, это повлияло на множество элементов. Все эти элементы, чтобы перекрыть градиент там, где его не должно быть видно, необходимо окрасить в белый цвет.
Теперь, когда мы изолировали блоки сообщений, подумаем о том, как снова скруглить их углы. В этом деле нам помогут псевдоэлементы.
.custom-theming .message__bubble < position: relative; border-radius: 0; background: transparent; >.custom-theming .message__bubble::after
Этот ход позволяет нам выйти на следующий результат.

Продолжение стилизации блоков сообщений
Теперь нужно отредактировать углы. Как сделать внутренний закруглённый угол? Оказалось, что для этого можно воспользоваться следующей формулой:
внутренний радиус = border-radius - border-width
То есть — если даже добавить к вышеприведённым стилям border-radius: 36px , на угол это не повлияет. При использовании обычной стилизации, без градиента, свойство border-radius имеет значение 18px . Для того чтобы отразить это на внутреннем радиусе, нужно увеличить значение свойства border-radius псевдоэлемента.
внутренний радиус = = 54px - 36px = 18px
Вот отредактированные стили:
.custom-theming .message__bubble < position: relative; border-radius: 0; background: transparent; >.custom-theming .message__bubble::after

Скруглённые углы
И наконец — нужно заключить псевдоэлемент в пределы элемента-обёртки блока сообщения.
.custom-theming .message__bubble

Ограничение псевдоэлемента рамками элемента-обёртки блока сообщения
Наш последний шаг заключается в изменении цвета границы (свойства border-color ) на белый, после чего всё будет сделано как нужно.
Если вам интересно узнать о механизме анимации фона сообщений при прокрутке — знайте, что делается это посредством свойства background-attachment: fixed . И тут ещё используется граница элемента толщиной 2px белого цвета. Думаю, сделано так не без причины, а с прицелом на работу с пользовательским фоном.
.messages-parent
Итоги
Мне было интересно исследовать структуру блока сообщений Facebook Messenger. Мне очень понравился этот процесс. Вот мои основные выводы:
- CSS Flexbox — это лучшее, что случилось с дизайном интерфейсов.
- Не стоит судить о сложности разработки некоего компонента, глядя лишь на один из его вариантов.
- Честно говоря — я не ожидал, что напишу об этом такую длинную статью. Когда я начал работу, я думал, что у меня получится небольшая заметка. Я ошибался — и мне это нравится.
- Компромиссы — это неотъемлемая часть работы дизайнера. Например, всю пользовательскую стилизацию блоков сообщений можно реализовать с помощью JavaScript. Но команда разработчиков из Facebook решила сделать всё исключительно средствами CSS. Полагаю — из соображений производительности.
- При работе над проектом, которым будут пользоваться жители разных стран, нужно учитывать то, что он должен поддерживать вывод текстов на разных языках, что эта возможность должна быть заложена в него с самого начала. Мне очень понравилось то, что Facebook Messenger — это именно такой проект, особенно учитывая то, что я написал руководство по RTL-стилизации.

- Блог компании RUVDS.com
- Веб-разработка
- CSS
- Дизайн
- Социальные сети и сообщества
Предыдущая запись
