Docs
Search

Chat

This page is currently under construction
Lism UI (@lism-css/ui) is still in preparation.

An example of a UI that displays content in a chat conversation style. It is built with Lism primitives and a small amount of CSS (b--chat).

Overview

Preview
Taro

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation.

Resize
<Grid class="b--chat b--chat--speak" data-chat-dir="start">
<Frame class="b--chat_avatar" aria-hidden="true">
<img src="https://cdn.lism-css.com/img/avatar/EkABPzB34XR7.webp" alt="" width="60" height="60" decoding="async" />
</Frame>
<Lism class="b--chat_name">Taro</Lism>
<Lism class="b--chat_body">
<Decorator class="b--chat_deco" util="cbox" isSkipFlow />
<Flow class="b--chat_content" util="cbox">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation.
</p>
</Flow>
</Lism>
</Grid>

Styles

The Chat base styles are defined in the following CSS. Copy this CSS into your project to use it.

If you copy it with the @layer lism-block wrapper as is, it fits into the core CSS layer order and can be overridden from the lism-custom layer.

chat.css
@layer lism-block {
  .b--chat {
    --cbox-bgPct: 8%;
    --keycolor: var(--gray);
    gap: 0 calc(var(--deco-size) + 1px);
    grid-template-areas: 'avatar name' 'avatar body';
    grid-template-columns: auto 1fr;
    grid-template-rows: minmax(1.5rem, auto) auto;
    justify-items: start;
    --avator-size: clamp(48px, 32px + 5cqw, 64px); /* @320px:40px ~ @640:64px */
    --deco-size: calc(min(var(--avator-size), 80px) / 4 + 0.25rem);
    --deco-mask: none;
    --deco-t: 0;
    --deco-scale: 1;
    --deco-inset-x: 0;
  }

  .b--chat_avatar {
    grid-area: avatar;
    width: var(--avator-size);
    aspect-ratio: 1/1;
    border-radius: var(--bdrs--99);
    background-color: var(--base);
  }
  .b--chat_name {
    grid-area: name;
    align-self: end;
    padding-block: var(--s5);
    padding-inline: var(--s10);
    color: var(--text-2);
    font-size: var(--fz--2xs);
    font-style: italic;
    --hl: 0px;
  }
  .b--chat_body {
    grid-area: body;
    position: relative;
  }
  .b--chat_content {
    justify-self: start;
    max-width: var(--sz--s);
    padding: var(--s20);
    border-radius: var(--bdrs--30);
    --hl: var(--hl--s);

    /* 吹き出し内の flow 間隔は控えめに(l--flow が参照する --flow--base を上書き) */
    --flow--base: var(--flow--s);
  }

  .b--chat_deco {
    position: absolute;
    top: var(--deco-t);
    inset-inline: var(--deco-inset-x);
    width: var(--deco-size);
    height: var(--deco-size);
    scale: var(--deco-scale);
    mask: var(--deco-mask) center / contain no-repeat;
  }
  .b--chat--speak {
    --deco-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8"><path d="M8,8L8,8C7.4,4.8,5.4,2,2.6,0.4L2,0h6V8z"/></svg>');
  }
  .b--chat--think {
    --deco-t: min(calc(var(--avator-size) / 3), 1.5rem);
    --deco-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8"><circle cx="1.5" cy="1.7" r="1.5"/><circle cx="4.5" cy="5.2" r="2.5"/></svg>');
  }

  [data-chat-dir='start'] {
    --deco-inset-x: auto calc(100% - 1px);
  }
  [data-chat-dir='end'] {
    --deco-scale: -1 1;
    --deco-inset-x: calc(100% - 1px) auto;
    grid-template-areas: 'name avatar' 'body avatar';
    grid-template-columns: 1fr auto;
    justify-items: end;
  }
  [data-chat-dir='end'] .b--chat_content {
    justify-self: end;
  }
}

/* NOTE: 以下は @layer 外に配置(セレクタの詳細度を確保するため) */

/* speak バリアントの角丸調整: 左側 */
.b--chat--speak[data-chat-dir='start'] > div > .b--chat_content {
  border-start-start-radius: 0;
}

/* speak バリアントの角丸調整: 右側 */
.b--chat--speak[data-chat-dir='end'] > div > .b--chat_content {
  border-start-end-radius: 0;
}

Markup

The markup consists of the following classes and attributes.

Class / Attribute Description
b--chat Root element. Used together with l--grid, plus the b--chat--speak (speech) or b--chat--think (thought) modifier.
data-chat-dir Display position. Use start (avatar on the left) or end (avatar on the right).
b--chat_avatar Element displaying the avatar image (used with l--frame; optional).
b--chat_name Element displaying the name (optional).
b--chat_body Wrapper element for the speech bubble.
b--chat_deco Tail decoration of the bubble (used with a--decorator + u--cbox).
b--chat_content Element containing the content (used with l--flow + u--cbox).
--keycolor Key color of the bubble. Can be overridden via the style attribute (defaults to var(--gray)).

Examples

Conversation example
Taro

Lorem ipsum dolor sit amet. Consectetur adipiscing elit, sed do eiusmod tempor Incididunt ut. Labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut.

Hanako

Lorem ipsum dolor sit amet. consectetur adipisicing elit, sed do eiusmod tempor. Non facere Laudantium ex eos doloribus aut dolore nisi provident.

Lorem ipsum dolor sit amet. Consectetur adipiscing elit, sed do eiusmod tempor Incididunt ut. Labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut.

Resize
<Grid class="b--chat b--chat--speak" data-chat-dir="start">
<Frame class="b--chat_avatar" aria-hidden="true">
<img src="https://cdn.lism-css.com/img/avatar/EkABPzB34XR7.webp" alt="" width="60" height="60" decoding="async" />
</Frame>
<Lism class="b--chat_name">Taro</Lism>
<Lism class="b--chat_body">
<Decorator class="b--chat_deco" util="cbox" isSkipFlow />
<Flow class="b--chat_content" util="cbox">
<p>Lorem ipsum dolor sit amet, ...</p>
</Flow>
</Lism>
</Grid>
<Grid class="b--chat b--chat--speak" keycolor="green" data-chat-dir="end">
<Frame class="b--chat_avatar" aria-hidden="true">
<img src="https://cdn.lism-css.com/img/avatar/of5v8rPFMI8F.webp" alt="" width="60" height="60" decoding="async" />
</Frame>
<Lism class="b--chat_name">Hanako</Lism>
<Lism class="b--chat_body">
<Decorator class="b--chat_deco" util="cbox" isSkipFlow />
<Flow class="b--chat_content" util="cbox">
<p>Lorem ipsum dolor <i>sit amet</i>. ...</p>
<p>Lorem ipsum dolor sit amet, ...</p>
</Flow>
</Lism>
</Grid>

Thought style (b--chat--think)

Use b--chat--think instead of b--chat--speak to represent thoughts — speech the character thinks but doesn’t say aloud.

b--chat--think
Name B

Lorem ipsum dolor sit amet.

Name B

Lorem ipsum dolor sit amet. consectetur adipisicing elit, sed do eiusmod tempor. Non facere Laudantium ex eos doloribus aut dolore nisi provident.

Resize
<Grid class="b--chat b--chat--think" keycolor="blue" data-chat-dir="start">
<Frame class="b--chat_avatar" aria-hidden="true">
<img src="https://cdn.lism-css.com/img/avatar/EkABPzB34XR7.webp" alt="" width="60" height="60" decoding="async" />
</Frame>
<Lism class="b--chat_name">Name B</Lism>
<Lism class="b--chat_body">
<Decorator class="b--chat_deco" util="cbox" isSkipFlow />
<Flow class="b--chat_content" util="cbox">
<p>Lorem ipsum dolor sit amet.</p>
</Flow>
</Lism>
</Grid>
<Grid class="b--chat b--chat--think" keycolor="purple" data-chat-dir="end">
<Frame class="b--chat_avatar" aria-hidden="true">
<img src="https://cdn.lism-css.com/img/avatar/of5v8rPFMI8F.webp" alt="" width="60" height="60" decoding="async" />
</Frame>
<Lism class="b--chat_name">Name B</Lism>
<Lism class="b--chat_body">
<Decorator class="b--chat_deco" util="cbox" isSkipFlow />
<Flow class="b--chat_content" util="cbox">
<p>Lorem ipsum dolor <i>sit amet</i>. ...</p>
</Flow>
</Lism>
</Grid>

© 2026 Lism CSS.