Нужно расположить блоки в виде чата, как на картинке. Помогите, пожалуйста, что я делаю не так и как это сделать правильнее, чище? Спасибо!
.text-align-center {
text-align: center;
}
.item:nth-child(even) {
direction: rtl;
}
.item {
position: relative;
margin: auto;
white-space: nowrap;
}
div {
display: block;
}
.person {
display: inline-block;
overflow: hidden;
position: relative;
vertical-align: middle;
}
.text {
display: inline-block;
vertical-align: middle;
font-size: 30px;
direction: ltr;
}
.all-chat {
width: 500px;
}
<!DOCTYPE html>
<html>
<head>
<title>homework 5</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="hw.css">
</head>
<body>
<h1 class="text-align-center">Chat</h1>
<div class="all-chat">
<div class="item">
<div class="person">
<img src="http://placekitten.com/40/50" alt="photo" class="image">
<div class="text">
<div class="data">9:03</div>
<div class="message">Hi</div>
</div>
</div>
</div>
<div class="item">
<div class="person">
<img src="http://placekitten.com/40/50" alt="photo" class="image">
<div class="text">
<div class="data">9:05</div>
<div class="message">Hello!</div>
</div>
</div>
</div>
</div>
</body>
</html>
Даю общие советы и перехожу к деталями вашего кода:
При вёрстке интересуйтесь предназначением CSS-свойств. То есть довод использования — просто потому что "так работает" используйте в последнюю очередь (если всё остальное не работает).
К примеру, вы используете свойство direction
. Это свойство предназначено для указания направления текста. В большинстве языков текст пишется слева направо (значение ltr
по умолчанию), но на арабском и иврите текст пишется справа налево и для этого текста указывается direction: rtl;
. Получается, что вы используете это свойство не по назначению.
Осмотрительней используйте абсолютное позиционирование. В идеале его использовать только когда нужно чтобы элементы перекрывали другие и элемент извлёкся из потока отображения. К примеру, модальные окна, выпадающие списки с более сложным отображением, чем стандартный select
и т.д. Также используется для в некоторых рецептах вроде поместить иконку внутри текстового поля. Но в данном случае не вижу в потребности в абсолютном позиционировании.
С большой осторожностью используйте псевдоселекторы (к примеру, first-child;
, only-child
, nth-child
и т.д.). Потому что псевдоселекторы
display: none
, он всё равно будет учитываться при применении псевдоселектора..item:nth-child(even)
работате так "выбрать каждого чётного ребёнка, у которого есть класс item
", а не так "выбрать каждый чётный элемент с классом item
". Иллюстрирую примером:.item:nth-child(even) {
background-color: red;
}
<div class="container">
<div class="not-item">
One (not item)
</div>
<div class="item">
Two (item)
</div>
<div class="item">
Three (item)
</div>
<div class="not-item">
Four (not item)
</div>
<div class="item">
Five (item)
</div>
<div class="item">
Six (item)
</div>
</div>
Если вы добавите элементы рядом с .item
, вёрстка может сломаться.
Поэтому рекомендую посмотреть, может стоит задавать отдельные классы для особых типов элементов.
В данном случае, я полагаю также, что чат означает, что может быть несколько сообщений подряд от одного пользователя. Поэтому применение стилей только к чётным элементам, кажется неверным.
Изучите flexbox. Расположение элементов с помощью float
, clear
, vertical-align
не обладает такой мощью и не такое гибкое и сопровождаемое.
Изучите CSS-методологию. BEM или SMACSS. Для того, чтобы вы могли легко менять вёрстку, а также если такие же блоки или подобные нужны на других страницах вы бы их без проблем добавляли и меняли. В примере, я буду использовать BEM.
Не используйте безликие или неоднозначные имена вроде .item
. Это же может быть что угодно. Применение этого класса зависит от того, кто в нём родитель и что рядом находится. А это значит, что если где-то добавится блок .item
, то те же стили для него и применятся, что, возможно, будет нежелательно. Относитесь к селекторам также как к переменным. У них должно быть строго определённое предназначение. Если вы назовёте, к примеру, chat-item
, то уже более ясно значение этого блока.
Относитесь к вёрстке как к программированию, для которого важна легкость восприятия, гибкость и сопровождаемость. Также не менее важно соответствие стандартов. Вёрстку портят дублирования кода, старайтесь их избегать. Использование современных препроцессоров с переменными, циклами, условиями делает вёрстку почти неотличимой от программирования.
Для каждой серии сообщений создал блок .chat-item
, где будет находиться аватар и одно или несколько сообщений от пользователя.
Для того, чтобы применять стили для инвертирования расположение (для отвечающего) колонки я задал flex-direction: row-reverse;
, что инвертирует порядок расположения элементов.
Здесь использована методология BEM.
Для того, чтобы не создавать дополнительные классы для вложенных элементов при инвертировании я пожертвовал чистотой BEM и добавил селекторы с вложенностью (.chat__item--responder .chat__message
, .chat__item--responder .chat__message-content
). По самой методологии (в идеале) следует использовать только классы без вложенности.
В результате код может выглядеть так:
.chat__header {
text-align: center;
}
.chat__item {
display: flex;
align-items: flex-start;
}
.chat__person-avatar {
border-radius: 50%;
}
.chat__messages {
margin-left: 10px;
}
.chat__message {
display: flex;
align-items: center;
margin-right: 10px;
}
.chat__message-content {
border-radius: 5px;
padding: 7px;
background-color: #ccc;
display: inline-block;
margin-left: 5px;
}
.chat__item--responder {
flex-direction: row-reverse;
}
.chat__item--responder .chat__message {
flex-direction: row-reverse;
}
.chat__item--responder .chat__message-content {
margin-left: 0;
margin-right: 5px;
}
<div class="chat">
<h1 class="chat__header">Chat</h1>
<div class="chat__content">
<div class="chat__item">
<img src="http://placekitten.com/40/50" alt="photo" class="chat__person-avatar">
<div class="chat__messages">
<div class="chat__message">
<div class="chat__message-time">9:03</div>
<div class="chat__message-content">Hi</div>
</div>
<div class="chat__message">
<div class="chat__message-time">9:03</div>
<div class="chat__message-content">How are you?</div>
</div>
</div>
</div>
<div class="chat__item chat__item--responder">
<img src="http://placekitten.com/40/50" alt="photo" class="chat__person-avatar">
<div class="chat__messages">
<div class="chat__message">
<div class="chat__message-time">9:05</div>
<div class="chat__message-content">Hello</div>
</div>
<div class="chat__message">
<div class="chat__message-time">9:07</div>
<div class="chat__message-content">I'm fine. Let's have a dinner today.</div>
</div>
<div class="chat__message">
<div class="chat__message-time">9:07</div>
<div class="chat__message-content">What do you think about it? </div>
</div>
</div>
</div>
</div>
Обратите внимание на изменение порядка элементов при помощи order
, в остальном — всё стандартно.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.chat {
padding: 40px;
}
.message {
width: 100%;
display: flex;
flex-wrap: wrap;
align-items: center;
}
.message--user-1 + .message--user-2,
.message--user-2 + .message--user-1 {
margin-top: 1em;
}
.message--user-1 + .message--user-1,
.message--user-2 + .message--user-2 {
margin-top: .5em;
}
.message__time {
font-size: 10px;
color: #ccc;
width: 100%;
margin: 0 0 5px 50px;
}
.message__author-pic {
margin: 0 10px 0 0;
}
.message__text {
padding: 10px;
border-radius: 10px;
border: 1px solid #69b4f3;
background-color: #bfe2ff;
max-width: 70%;
}
.message--user-2 {
justify-content: flex-end;
}
.message--user-2 .message__time {
text-align: right;
margin: 0 50px 5px 0;
}
.message--user-2 .message__author-pic {
order: 1;
margin: 0 0 0 10px;
}
.message--user-2 .message__text {
background-color: #69b4f3;
}
<section class="chat">
<div class="message message--user-1">
<time class="message__time">21.02.2017 21:12:07</time>
<figure class="message__author-pic">
<img src="http://pipsum.com/40x40.jpg">
</figure>
<div class="message__text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis at purus nibh. Cras metus nulla, vestibulum in auctor ac, fermentum vitae tellus.</p>
</div>
</div>
<div class="message message--user-2">
<time class="message__time">21.02.2017 21:12:07</time>
<figure class="message__author-pic">
<img src="https://placeimg.com/40/40/people">
</figure>
<div class="message__text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis at purus nibh. Cras metus nulla, vestibulum in auctor ac, fermentum vitae tellus.</p>
</div>
</div>
<div class="message message--user-2">
<time class="message__time">21.02.2017 21:12:07</time>
<figure class="message__author-pic">
<img src="https://placeimg.com/40/40/people">
</figure>
<div class="message__text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis at purus nibh. Cras metus nulla, vestibulum in auctor ac, fermentum vitae tellus.</p>
</div>
</div>
<div class="message message--user-1">
<time class="message__time">21.02.2017 21:12:07</time>
<figure class="message__author-pic">
<img src="http://pipsum.com/40x40.jpg">
</figure>
<div class="message__text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis at purus nibh. Cras metus nulla, vestibulum in auctor ac, fermentum vitae tellus.</p>
</div>
</div>
</section>
Я к примеру сделал так, правда не самый лучший вариант. Но советую воспользоваться каким-нибудь фреймворков для таких затей.
.text-align-center {
text-align: center;
}
.item:nth-child(even) {
direction: rtl;
}
.item {
position: absolute;
margin: auto;
white-space: nowrap;
}
.item-2 {
position: absolute;
margin: auto;
white-space: nowrap;
right: 0;
top: 200px;
}
div {
display: block;
}
.person {
display: inline-block;
overflow: hidden;
position: relative;
vertical-align: middle;
margin-right: 50px; /* Отступ справа */
margin-left: 50px; /* Отступ слева*/
}
.text {
display: inline-block;
vertical-align: middle;
font-size: 30px;
direction: ltr;
background: #cccccc; /* Цвет фона под заголовком */
color: black; /* Цвет текста */
padding: 2px; /* Поля вокруг текста */
}
.all-chat {
width: 500px;
}
.date{
background: #cccccc; /* Цвет фона под заголовком */
color: black; /* Цвет текста */
padding: 2px; /* Поля вокруг текста */
}
<!DOCTYPE html>
<html>
<head>
<title>homework 5</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="hw.css">
</head>
<body>
<h1 class="text-align-center">Chat</h1>
<div class="all-chat">
<div class="item">
<div class="person">
<img src="http://placekitten.com/40/50" alt="photo" class="image">
<div class="text">
<div class="date">9:03</div>
<div class="text">Hi</div>
</div>
</div>
</div>
<div class="item-2">
<div class="person">
<img src="http://placekitten.com/40/50" alt="photo" class="image-2">
<div class="text">
<div class="date">9:05</div>
<div class="text">Hello!</div>
</div>
</div>
</div>
</div>
</body>
</html>
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Имеется HID-клавиатура (на пульте ДУ)Требуется определять, какие HID-коды она посылает на USB-порт
Подскажите как поменять текст при нажатий на кнопку в Unity3d? Я создал картинку и на ней текст
Не срабатывает свойство IsSelected у ComboBoxItemВ чем причина?
У меня есть четыре TextBox и один ComboBoxВ зависимости от выбранного элемента в ComboBox, нужно включить/выключить (Enabled) TextBox