Объединение элементов в селекторе CSS - PullRequest
1 голос
/ 04 февраля 2020

У меня уже есть макет CSS / HTML, который делает его похожим на обмен сообщениями WhatsApp, но только для разговоров между двумя людьми. Я хочу добавить функцию группового чата, которая означает имена.

Он основан на списке <dl>, поэтому HTML выглядит следующим образом:

.whatsapp {
  width: 100%;
  max-width: 320px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  display: table;
  margin: auto;
  background-image: url("https://raw.githubusercontent.com/Azdaema/AO3-Skin_Messaging/master/WhatsApp/images/WhatsApp_background.png");
  background-repeat: repeat-y;
  background-size: 100%;
}

.whatsapp dt {
  display: none;
}

.whatsapp dd {
  max-width: 65%;
  clear: both;
  position: relative;
  color: #000000;
  border-radius: 5px;
  padding: 5px;
  margin: 1px 15px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.2);
  z-index: 1;
}

.whatsapp dd:after {
  content: attr(time);
  font-size: 0.75em;
  color: #999;
  text-transform: uppercase;
  display: inline-block;
  float: right;
  line-height: 1.3em;
  padding-top: 0.5em;
  padding-left: 1.5em;
  margin: 0;
}

.whatsapp dd:last-child {
  margin-bottom: 10px;
}

.whatsapp dd:last-child:before {
  content: "";
  position: absolute;
  width: 25px;
  height: 14px;
  bottom: 5px;
  border-top: 9px solid;
  border-radius: 20px;
  z-index: -1;
}


/*
 * Outgoing texts
 */

.whatsapp .out dd {
  float: right;
  background: #DCF8C6;
}

.whatsapp .out dd:last-child:before {
  border-color: #DCF8C6;
  transform: rotate(240deg);
  right: -16px;
}


/*
 * Incoming texts
 */

.whatsapp .in dd {
  float: left;
  background: #FFFFFF;
}

.whatsapp .in dd:last-child:before {
  border-color: #FFFFFF;
  transform: rotate(-240deg);
  left: -16px;
}


/*
 * Timestamps
 */

.whatsapp .day,
.whatsapp dd sub {
  font-family: inherit;
  font-size: 0.75em;
  color: #999;
  text-transform: uppercase;
}

.whatsapp .day {
  width: 100px;
  background: #D4EAF4;
  border-radius: 5px;
  padding: 5px;
  margin: 10px auto;
  text-align: center;
  display: table;
}

.whatsapp dd sub {
  display: inline-block;
  float: right;
  line-height: 1.3em;
  padding-top: 0.5em;
  padding-left: 1.5em;
  margin: 0;
}


/* checkmarks */

.whatsapp .out dd sub:after {
  content: url("https://raw.githubusercontent.com/Azdaema/AO3-Skin_Messaging/master/WhatsApp/images/Checkmark_read.png");
  margin-left: 3px;
}

.whatsapp .out dd sub.received:after {
  content: url("https://raw.githubusercontent.com/Azdaema/AO3-Skin_Messaging/master/WhatsApp/images/Checkmark_received.png");
}

.whatsapp .out dd sub.notreceived:after {
  content: url("https://raw.githubusercontent.com/Azdaema/AO3-Skin_Messaging/master/WhatsApp/images/Checkmark_no-received.png");
}


/*
 * Big emojis
 */

.whatsapp dd.emoji1 {
  font-size: 2.5em;
}

.whatsapp dd.emoji2 {
  font-size: 2em;
}

.whatsapp dd.emoji3 {
  font-size: 1.5em;
}

.whatsapp dd.emoji1 sub,
.whatsapp dd.emoji2 sub,
.whatsapp dd.emoji3 sub {
  display: block;
  float: none;
  text-align: right;
  padding: 0 !important;
}

.whatsapp dd.emoji1 sub {
  font-size: 0.3em;
}

.whatsapp dd.emoji2 sub {
  font-size: 0.375em;
}

.whatsapp dd.emoji3 sub {
  font-size: 0.5em;
}


/*
 * Pictures
 */

.whatsapp .pic {
  padding: 3px;
}

.whatsapp .pic img {
  border-radius: 3px;
  width: 100%;
  display: block;
}


/* Timestamp white and in image corner */

.whatsapp .pic.solo sub {
  color: #ffffff;
  position: absolute;
  bottom: 2px;
  right: 5px;
}


/*
 * Contact header
 */

.whatsapp .contact {
  position: relative;
  background: #075E54;
  margin: 0;
  padding: 10px;
  font-family: inherit;
  color: #FFFFFF;
  font-size: 15px;
  font-weight: bold;
  text-transform: capitalize;
  text-align: left;
}


/* avatar circle */

.whatsapp .contact:before {
  content: "";
  float: left;
  width: 35px;
  height: 35px;
  background-image: url("https://t3.ftcdn.net/jpg/00/64/67/80/240_F_64678017_zUpiZFjj04cnLri7oADnyMH0XBYyQghG.jpg");
  background-size: 100%;
  border-radius: 100%;
  margin-right: 10px;
}


/* Online status */

.whatsapp .contact.online:after {
  content: "Online";
  display: block;
  padding-top: 5px;
  font-size: 13px;
  font-weight: normal;
}


/*
 * Group chat
 */

.whatsapp.grouptext .in dt {
  display: table !important;
  clear: both;
  font-weight: bold;
  padding-left: 15px;
}

.whatsapp.grouptext .in.p1 dt {
  color: #e54c51;
}

.whatsapp.grouptext .in.p2 dt {
  color: #ee7d37;
}

.whatsapp.grouptext .in.p3 dt {
  color: #dfa64f;
}

.whatsapp.grouptext .in.p4 dt {
  color: #58b042;
}

.whatsapp.grouptext .in.p5 dt {
  color: #58bfe8;
}

.whatsapp.grouptext .in.p6 dt {
  color: #367cdc;
}

.whatsapp.grouptext .in.p7 dt {
  color: #6f4bf5;
}

.whatsapp.grouptext .in.p8 dt {
  color: #ec68a1;
}
<dl class="whatsapp grouptext">
  <div class="out">
    <dt>Ciri</dt>
    <dd time="2:01 PM">Who's picking me up today?</dd>
  </div>

  <div class="in p1">
    <dt>Yennefer</dt>
    <dd>its tuesday</dd>
    <dd>so jaskier</dd>
  </div>

  <div class="in p2">
    <dt>Jasker</dt>
    <dd>no its geralts turn</dd>
    <dd>i swear its his turn</dd>
  </div>

  <div class="in p3">
    <dt>Geralt</dt>
    <dd>no, Yen is right: it's your turn</dd>
    <dd>it's tuesday</dd>
    <dd>Tuesday is always your turn</dd>
  </div>
</dl>

<hr>

<dl class="whatsapp">
  <h1 class="contact online">Mabel</h1>
  <h4 class="day">Today</h4>

  <div class="out">
    <dt>Dipper</dt>
    <dd>How's babysitting for Soos and Melody going?<sub>11:49 AM</sub>
    </dd>
  </div>

  <div class="in">
    <dt>Mabel</dt>
    <dd>So I made chicken nuggets for lunch<sub>1:07 PM</sub>
    </dd>
    <dd>And you remember how much we used to love chicken nuggets!!!!! but when I tried one now it was just kind of bland and gross<sub>1:07 PM</sub>
    </dd>
    <dd>How sad is that??!<sub>1:07 PM</sub>
    </dd>
    <dd>I feel like an adult and I hate it<sub>1:07 PM</sub>
    </dd>
  </div>

  <div class="out">
    <dt>Dipper</dt>
    <dd>Does it help if I say texting me to lament about chicken nuggets is super un-adult?<sub>1:08 PM</sub>
    </dd>
  </div>

  <div class="in">
    <dt>Mabel</dt>
    <dd>maybe a little<sub>1:08 PM</sub>
    </dd>
  </div>

  <div class="out">
    <dt>Dipper</dt>
    <dd>I bet we could make good chicken nuggets at home if we tried<sub>1:08 PM</sub>
    </dd>
  </div>

  <div class="in">
    <dt>Mabel</dt>
    <dd class="emoji1">?<sub>1:08 PM</sub>
    </dd>
  </div>

  <div class="out">
    <dt>Dipper</dt>
    <dd>I mean it's just bite-sized breaded chicken, right? You still like chicken and bread<sub>1:09 PM</sub>
    </dd>
  </div>

  <div class="in">
    <dt>Mabel</dt>
    <dd>loving this can-do spirit brobro<sub>1:09 PM</sub>
    </dd>
    <dd>Also it makes you sound like antoni on queer eye<sub>1:09 PM</sub>
    </dd>
  </div>

  <div class="out">
    <dt>Dipper</dt>
    <dd>Making An Effort ?<sub>1:10 PM</sub>
    </dd>
    <dd>and making chicken nuggets<sub>1:10 PM</sub>
    </dd>
  </div>

  <div class="in">
    <dt>Mabel</dt>
    <dd>:swoon:<sub>1:10 PM</sub>
    </dd>
    <dd>Oooooh can we make them dinasour shaped<sub>1:11 PM</sub>
    </dd>
  </div>

  <div class="out">
    <dt>Dipper</dt>
    <dd>I think the reason they can make the store bought ones shaped is because they're not actually made out of chicken, they're made out of paste<sub>1:11 PM</sub>
    </dd>
    <dd>wait<sub>1:11 PM</sub>
    </dd>
    <dd>Shit did I just destroy our childhood?<sub>1:11 PM</sub>
    </dd>
  </div>

  <div class="in">
    <dt>Mabel</dt>
    <dd>No<sub>1:11 PM</sub>
    </dd>
    <dd>Maybe a little<sub>1:12 PM</sub>
    </dd>
  </div>

  <div class="out">
    <dt>Dipper</dt>
    <dd>We could take real chicken and grind it up??<sub>1:13 PM</sub>
    </dd>
    <dd>It works for hamburgers. Mix in onion and stuff<sub>1:13 PM</sub>
    </dd>
  </div>

  <div class="in">
    <dt>Mabel</dt>
    <dd>I can't decide if onion would be good, or if it would be sacrilegious to the spirit of chicken nuggets<sub>1:13 PM</sub>
    </dd>
  </div>

  <div class="out">
    <dt>Dipper</dt>
    <dd>If they have onion but are dinosaur shaped, would that be a fair trade?<sub>1:14 PM</sub>
    </dd>
  </div>

  <div class="in">
    <dt>Mabel</dt>
    <dd>yes<sub>1:14 PM</sub>
    </dd>
    <dd class="emoji2">??<sub>1:14 PM</sub>
    </dd>
    <dd>ALL THE SHAPES!!<sub>1:14 PM</sub>
    </dd>
    <dd class="emoji3">???<sub>1:14 PM</sub>
    </dd>
  </div>

  <div class="out">
    <dt>Dipper</dt>
    <dd>That seems ambitious<sub>1:14 PM</sub>
    </dd>
  </div>

  <div class="in">
    <dt>Mabel</dt>
    <dd>Bread on the outside! Bread on the inside!<sub>1:15 PM</sub>
    </dd>
  </div>

  <div class="out">
    <dt>Dipper</dt>
    <dd>If the bread was on the inside the chicken would dry out<sub>1:15 PM</sub>
    </dd>
  </div>

  <div class="in">
    <dt>Mabel</dt>
    <dd>beef jerky is good<sub>1:15 PM</sub>
    </dd>
  </div>

  <div class="out">
    <dt>Dipper</dt>
    <dd>Fair poin<sub>1:16 PM</sub>t</dd>
  </div>

  <div class="in">
    <dt>Mabel</dt>
    <dd>CHICKEN NUGGET CINNAMON ROLLS!!!<sub>1:16 PM</sub>
    </dd>
    <dd>bread on the inside AND the outside<sub>1:16 PM</sub>
    </dd>
  </div>

  <div class="out">
    <dt>Dipper</dt>
    <dd>To what ends?<sub>1:16 PM</sub>
    </dd>
  </div>

  <div class="in">
    <dt>Mabel</dt>
    <dd>Defying chicken-bread roles<sub>1:17 PM</sub>
    </dd>
    <dd>why does the bread always have to be on the outside, shielding the chicken from the drying heat of the oven?? Doesn't bread deserve to be protected sometimes too<sub>1:17 PM</sub>
    </dd>
  </div>

  <div class="out">
    <dt>Dipper</dt>
    <dd>Can't argue with that<sub>1:17 PM</sub>
    </dd>
    <dd>Wait so were you actually serious about making chicken nuggets?? I'm at the store now, should I buy some chicken?<sub>3:47 PM</sub>
    </dd>
  </div>

  <div class="in">
    <dt>Mabel</dt>
    <dd>yes get chicken<sub>4:11 PM</sub>
    </dd>
  </div>

  <div class="out">
    <dt>Dipper</dt>
    <dd>Mabel we've talked about this<sub>4:12 PM</sub>
    </dd>
    <dd>When I say "I'm at the store NOW" you can't reply half an hour later still asking for stuff<sub>4:12 PM</sub>
    </dd>
    <dd>but yeah I got chicken<sub>4:16 PM</sub>
    </dd>
  </div>

  <div class="in">
    <dt>Mabel</dt>
    <dd class="emoji1">?<sub>4:16 PM</sub>
    </dd>
  </div>

</dl>

Просмотр в CodePen

В групповом чате WhatsApp имя отображается в верхней строке первого текста, который человек посылает серию.

Что я хочу:

enter image description here

Сначала я просто попытался это сделать, чтобы освободить место, и затем перевели имя на место.

.whatsapp.grouptext .incoming dt+dd {
  padding-top: 1.5em;
}

Но если кто-то просто скажет «нет» или что-то еще, тогда текстовый пузырь будет настолько узким, и он недостаточно широк для имени. И имена, и тексты могут различаться по длине, и я бы действительно не стал жестко кодировать ни фиксированный размер пикселя, ни что-то еще.

Что я действительно хочу, так это объединить их в один элемент или превратить содержимое <dt> в :before для <dd>. Есть ли способ сделать это?

(И да, я мог бы просто обернуть эти две верхние в <div> или как угодно. Но есть ли другой способ ??)

Ответы [ 2 ]

0 голосов
/ 04 февраля 2020

Изменено <div> на <ul> и каждое текстовое сообщение на <li>. Каждый <li> имеет:

  • Значения по умолчанию, назначенные как CSS переменных [1]

    --variableName: value
    ...
    property: var(--variableName);
    


  • Различные background свойства были использованы для изображения аватара [3].

  • Пользовательские стили были назначены для указания c #id [6].

Демонстрация

Примечание: Первоначальный фрейм, предоставленный для отображения демонстрации, не отображается для любых реалий c размеров. Чтобы правильно просмотреть демо, нажмите на ссылку Full page, расположенную справа.

/* [1] Defaults */
:root {
  /* Default avatar */
  --img: url(https://i.ibb.co/Br95K5G/wa0000000.png);
  /* Default background colors */
  --grn: rgba(12, 128, 8, 0.6);
  --lav: rgba(8, 12, 128, 0.6);
}

:root,
body {
  width: 100%;
  height: 100%;
  padding: 0;
  font: 700 3vw/1.45 Arial;
  overflow-y: hidden;
}

main {
  position: relative;
  height: 90vh;
  margin: 0 auto;
  overflow-y: scroll;
}

header {
  position: fixed;
  top: 0;
  width: 100%;
  height: 15%;
  padding-bottom: 0;
  border-bottom: 5px ridge #000;
  background-color: #fff;
}

h1 {
  margin: 0 0 8px 0;
  padding-bottom: 15px;
}

h1::before {
  /* [2] Group name */
  content: attr(data-group);
  font-size: 1.5rem;
  font-variant: small-caps;
  letter-spacing: 0.2rem;
}

.text {
  padding: 4rem 0;
}

li {
  margin: 0 0 0.5rem 0;
  padding: 1.25rem 1.25rem 1.25rem 3.75rem;
  border: 0;
  border-radius: 8px;
  /* [3] Avatar */
  list-style: none;
  background-image: var(--img);
  background-repeat: no-repeat;
  background-position: 0.5rem center;
  background-size: 2.5rem;
}

li::before {
  /* [4] User name */
  content: attr(data-user)': ';
  border: 0;
  border-radius: 5px;
  margin: 0 5px 0 -5px;
  padding: 4px 0 2px 10px
}

.outgoing li,
.incoming li::before {
  background-color: var(--grn)
}

.incoming li,
.outgoing li::before {
  background-color: var(--lav)
}

time {
  display: block;
  margin-left: 75%;
  margin-bottom:-15px;
}

time::before {
  /* [5] Timestamp */
  content: attr(datetime);
}

/* [6] Custom styles by user #id */
#wa2813224 {
  background-image: url(https://i.ibb.co/Hdyh0V0/wa2813224.png);
  background-color: #000;
  color: gold
}

#wa1248791 {
  background-image: url(https://i.ibb.co/d6bK0fZ/wa12248791.png)
}

footer {
  position: fixed;
  bottom: 0;
  padding-top: 0;
  width: 100%;
  border-top: 5px ridge #000;
  background-color: #000;
}

#ui * {
  font: inherit
}

fieldset {
  display: flex;
  justify-content: center;
  padding: 0;
  border: 0;
  background-color: #000;
}

#message {
  width: 80vw;
  min-height: 100%;
  padding: 3px 5px;
  border-top: 5px inset #333;
  border-bottom: 5px inset #333;
  border-left: 5px inset #333;
  border-top-left-radius: 8px;
  border-bottom-left-radius: 8px;
  resize: vertical;
}

#send {
  min-height: 100%;
  background-color: var(--lav);
  font-size: 1.25rem;
  font-variant: small-caps;
  color: #fff;
  border: 0;
  border-top-right-radius: 8px;
  border-bottom-right-radius: 8px;
  cursor: pointer;
}

@media only screen and (max-width: 600px) {
  :root,
  body {
    font: 700 4vw/1.45 Arial;
  }
  
  header {
    height: max-content
  }
  
  h1 {    
    margin: -8px 0;
  }
  
  time {
    margin-left: 65%;
  }
  
  #send {
    width: 10%;
    padding: 1px 3.5%;
    font-size: 0.75rem;  
    text-transform: uppercase;
    line-height: 1;
    word-break: break-word;
  }
}
<main class='whatsapp group'>
  <header>
    <h1 data-group='Carpool'></h1>
  </header>
  <section class="text">
    <ul class="outgoing">
      <li id='wa1275966' data-user='Ciri'>Who's picking me up today?<time datetime='10:21 PM'></time></li>
    </ul>
    <hr>
    <ul class="incoming">
      <li id='wa0000000' data-user='default'>Hello world!<time datetime='10:26 PM'></time></li>
      <li id='wa2813224' data-user='zer00ne'>Not me.<time datetime='10:31 PM'></time></li>
      <li id='wa1248791' data-user='Aza Azdaema'>It's Tuesday...it's your turn.<time datetime='10:35 PM'></time></li>
      <li id='wa2813224' data-user='zer00ne'>I don't have enough gas.<time datetime='10:45 PM'></time></li>
      <li id='wa2813224' data-user='zer00ne'>Plus I'm not scheduled for Tuesdays. In fact I don't even work Tuesdays.<time datetime='10:46 PM'></time></li>
    </ul>
  </section>
  <footer>
    <form id='ui'>
      <fieldset>
        <textarea id='message' rows='1' cols='50'></textarea>
        <button id='send' type='submit'>Send</button>
      </fieldset>
    </form>
  </footer>
</main>
0 голосов
/ 04 февраля 2020

Насколько я понимаю,

  1. Вам нужно полное имя + текст, чтобы прийти в один пузырь. Для этого вы можете задавать фон и стили для div .in и .out. То же самое касается и указывающей стрелки.

  2. Вам нужно иметь некоторую ширину, чтобы у пузыря была некоторая ширина. Для этого удалите поплавок влево / вправо, заданный для dd.

Остальные можно исправить, используя поля и отступы.

...