jockles.com

All the Fannish things I do.

Megaskin by Jockles

← Previous Chapter · Chapter Index · Next Chapter →

Chapter 8: Twitter/X

Thanks to worlds_end_valentine, whose Twitter Work Skin Template this module is built on. Copied and adapted from it: the timestamp line, liked and reposted counts, labels, the sensitive content warning, polls, pictures and videos, scrollable threads, and DM reactions, group DMs, voice messages and the DM window.

8.1 Chapter Contents

8.2 Twitter/X posts, replies and quote tweets

Before we begin, here's the two kinds of post you can build: a tweet with its replies, in a scrolling thread, or tweets on their own, like a timeline. The full HTML is underneath each, which you can copy and modify yourself. The rest of this section takes the HTML apart so that you can modify all the individual parts to say exactly what you want.

8.2.1 A Tweet and Its Replies

Z Zim @ZimBits · 3h

Reminder to everyone that there could be (and likely are) queer players on many of the teams that didn't pledge. Thoughts go out to them. #HunterShortlist @SHunter

8:23 AM · 11 May 23

580 Reposts   2.6k Likes   10 Replies

Replying to @ZimBits

H Holster @HolsterInLaw · 2h

I played all through college with a guy whose boyfriend was also on the team. That man now plays professionally. This is not the whole story of queer hockey.

Replying to @HolsterInLaw

Profile picture of samthecat, a black and white cat screaming at the cameraSam @samthecat · 1h

this is lovely. anyway feed me

Replying to @ZimBits

S Stan @PuckStan · 45m

Settle something for me while we're all here. Who's got the cup this year?

Montreal

Boston

179 votes · 13 minutes left

Replying to @ZimBits

RL Rose Landry @RoseLandry · 30m

The Ottawa crowd last night 🏳️‍🌈

Black and white cat staring through a gap between a screen and a desk, with blurred cables hanging down around and blue sky behind Black and white cat screaming at the camera, on a red patterned rug

Replying to @RoseLandry

S Stan @PuckStan · 20m

Rose those are cats.

Reply - Tweet your reply

The full HTML for this thread
<div class="tw-thread theme-auto">
  <div class="tw-scroll">
    <div class="mob tw">
      <p class="tw-top"><span class="tw-pfp colour5">Z</span><span class="hide"> </span><span class="tw-name">Zim</span> <span class="tw-handle">@ZimBits · 3h</span></p>
      <p class="tw-text">Reminder to everyone that there could be (and likely are) queer players on many of the teams that didn't pledge. Thoughts go out to them. <span class="tw-link">#HunterShortlist</span> <span class="tw-link">@SHunter</span></p>
      <p class="tw-date">8:23 AM · 11 May 23</p>
      <p class="tw-stats"><span class="tw-rt"><b>580</b> Reposts</span> &nbsp; <span class="tw-liked"><b>2.6k</b> Likes</span> &nbsp; <b>10</b> Replies</p>
    </div>
    <div class="mob tw-reply">
      <p class="tw-replying">Replying to <span class="tw-link">@ZimBits</span></p>
      <p class="tw-top"><span class="tw-pfp colour2">H</span><span class="hide"> </span><span class="tw-name">Holster</span> <span class="tw-handle">@HolsterInLaw · 2h</span></p>
      <p>I played all through college with a guy whose boyfriend was also on the team. That man now plays professionally. This is not the whole story of queer hockey.</p>
    </div>
    <div class="mob tw-reply">
      <p class="tw-replying">Replying to <span class="tw-link">@HolsterInLaw</span></p>
      <p class="tw-top"><span class="tw-pfp"><span class="pfp"><img src="https://64.media.tumblr.com/6898dc3a42cc6c7ab9729360b71366e4/ba033a52c8982cb0-bf/s2048x3072/b548d2fe61b02e530c0edd2ee6a6bd56ab73ad2c.jpg" alt="Profile picture of samthecat, a black and white cat screaming at the camera"></span></span><span class="tw-name">Sam</span> <span class="tw-handle">@samthecat · 1h</span></p>
      <p>this is lovely. anyway feed me</p>
    </div>
    <div class="mob tw-reply">
      <p class="tw-replying">Replying to <span class="tw-link">@ZimBits</span></p>
      <p class="tw-top"><span class="tw-pfp colour1">S</span><span class="hide"> </span><span class="tw-name">Stan</span> <span class="tw-handle">@PuckStan · 45m</span></p>
      <p>Settle something for me while we're all here. Who's got the cup this year?</p>
      <p class="tw-opt">Montreal</p>
      <p class="tw-opt">Boston</p>
      <p class="tw-pollinfo">179 votes · 13 minutes left</p>
    </div>
    <div class="mob tw-reply">
      <p class="tw-replying">Replying to <span class="tw-link">@ZimBits</span></p>
      <p class="tw-top"><span class="tw-pfp colour3">RL</span><span class="hide"> </span><span class="tw-name">Rose Landry</span> <span class="tw-handle">@RoseLandry · 30m</span></p>
      <p>The Ottawa crowd last night 🏳️‍🌈</p>
      <p class="tw-media two">
        <span class="tw-photo"><img src="https://64.media.tumblr.com/694221426fb8229480fb3fb87b528ca7/ba033a52c8982cb0-01/s1280x1920/636653581e07a970475075f480c1717b23a72c0a.jpg" alt="Black and white cat staring through a gap between a screen and a desk, with blurred cables hanging down around and blue sky behind"></span>
        <span class="tw-photo"><img src="https://64.media.tumblr.com/6898dc3a42cc6c7ab9729360b71366e4/ba033a52c8982cb0-bf/s2048x3072/b548d2fe61b02e530c0edd2ee6a6bd56ab73ad2c.jpg" alt="Black and white cat screaming at the camera, on a red patterned rug"></span>
      </p>
    </div>
    <div class="mob tw-reply">
      <p class="tw-replying">Replying to <span class="tw-link">@RoseLandry</span></p>
      <p class="tw-top"><span class="tw-pfp colour1">S</span><span class="hide"> </span><span class="tw-name">Stan</span> <span class="tw-handle">@PuckStan · 20m</span></p>
      <p>Rose those are cats.</p>
    </div>
  </div>
  <p class="tw-foot"><span>Reply</span><span class="hide"> - </span>Tweet your reply</p>
</div>

8.2.2 A Timeline of Tweets

HF Hockey Fan @hockeyfan · 2h

Can't believe that overtime goal.

3 Reposts   13 Likes   1 Reply

SH Scott Hunter ✔ @SHunter · 5m

no comment. #NoComment

Reporter @sportsdesk
Sources say the trade is happening.

Readers added context: the trade has not been confirmed.

912 Reposts   8,204 Likes   77 Replies

Y Yuna @MetrosMomager · 2h

Only people in @MetrosMomager's Twitter Circle can see this Tweet.

Cat sitting again.

Black and white cat staring through a gap between a screen and a desk, with blurred cables hanging down around and blue sky behind Black and white cat screaming at the camera, on a red patterned rug Black and white cat holding out a paw daintily, on a beige and green cat tree. The cat looks to be stepping into the frame from the left Black and white cat sitting in an opened red suitcase, carry on size, on the floor behind a white door, and on a red patterned rug

SS Sharks or Swim @SharksSwim · 2h

My Captain.

Macklin Celebrini at the IHF Worlds, dressed in his red jersey and black helmet. He's surrounded by sparkles, a red vignette, and hearts containing the Canadian flag

PO Pace Off @Pace_Off_Puckers · 3h

Last Metros game of the regular season and @SHollanderHockeyPlayer looks miserable.

[Shane Hollander looking tired at a press conference]

J Jockles @jockles25 · 2h

Ilya Rozanov you will always be famous to me

[Video: a tribute edit of Ilya Rozanov, made from Heated Rivalry footage and set to "Would You Come Home" by Tyler Blackburn]

HF Hockey Fan @hockeyfan · 1d

Who's got the cup this year?

Montreal 75%

Boston 25%

97 votes · Final results

G Geri @Geronimum · 4h

Rink at night vs rink in the morning. Guess which one I prefer

[A photo of the empty rink at night][A photo of the same rink at 6am, full of children in helmets]

Content warning: Sensitive content
The Tweet author flagged this Tweet as showing sensitive content.

The full HTML for these tweets
<div class="mob tw theme-auto">
  <p class="tw-top"><span class="tw-pfp colour5">HF</span><span class="hide"> </span><span class="tw-name">Hockey Fan</span> <span class="tw-handle">@hockeyfan · 2h</span></p>
  <p class="tw-text">Can't believe that overtime goal.</p>
  <p class="tw-stats"><b>3</b> Reposts &nbsp; <b>13</b> Likes &nbsp; <b>1</b> Reply</p>
</div>

<div class="mob tw theme-auto">
  <p class="tw-top"><span class="tw-pfp colour6">SH</span><span class="hide"> </span><span class="tw-name">Scott Hunter <span class="tw-tick">✔</span></span> <span class="tw-handle">@SHunter · 5m</span></p>
  <p class="tw-text">no comment. <span class="tw-link">#NoComment</span></p>
  <p class="tw-quote"><b>Reporter</b> <span class="tw-handle">@sportsdesk</span><br>Sources say the trade is happening.</p>
  <p class="tw-note">Readers added context: the trade has not been confirmed.</p>
  <p class="tw-stats"><b>912</b> Reposts &nbsp; <b>8,204</b> Likes &nbsp; <b>77</b> Replies</p>
</div>

<div class="mob tw theme-auto">
  <p class="tw-top"><span class="tw-pfp colour3">Y</span><span class="hide"> </span><span class="tw-name">Yuna</span> <span class="tw-handle">@MetrosMomager · 2h</span></p>
  <p class="tw-label">Only people in @MetrosMomager's Twitter Circle can see this Tweet.</p>
  <p class="tw-text">Cat sitting again.</p>
  <p class="tw-media four">
    <span class="tw-photo"><img class="land" src="https://64.media.tumblr.com/694221426fb8229480fb3fb87b528ca7/ba033a52c8982cb0-01/s1280x1920/636653581e07a970475075f480c1717b23a72c0a.jpg" alt="Black and white cat staring through a gap between a screen and a desk, with blurred cables hanging down around and blue sky behind"></span>
    <span class="tw-photo"><img src="https://64.media.tumblr.com/6898dc3a42cc6c7ab9729360b71366e4/ba033a52c8982cb0-bf/s2048x3072/b548d2fe61b02e530c0edd2ee6a6bd56ab73ad2c.jpg" alt="Black and white cat screaming at the camera, on a red patterned rug"></span>
    <span class="tw-photo"><img class="land" src="https://64.media.tumblr.com/a99a60f0293cf7df3604b4a6dd4705f6/ba033a52c8982cb0-cc/s1280x1920/cb4c277845d0c3ef666d16b86b75509266b795b3.jpg" alt="Black and white cat holding out a paw daintily, on a beige and green cat tree. The cat looks to be stepping into the frame from the left"></span>
    <span class="tw-photo"><img src="https://64.media.tumblr.com/45b3b47d7c42b593f6242a40153a629c/ba033a52c8982cb0-d7/s2048x3072/4e71b117e87747d78dd3d95595cecc77eec48d38.jpg" alt="Black and white cat sitting in an opened red suitcase, carry on size, on the floor behind a white door, and on a red patterned rug"></span>
  </p>
</div>

<div class="mob tw theme-auto">
  <p class="tw-top"><span class="tw-pfp colour7">SS</span><span class="hide"> </span><span class="tw-name">Sharks or Swim</span> <span class="tw-handle">@SharksSwim · 2h</span></p>
  <p class="tw-text">My Captain.</p>
  <p class="tw-media"><img src="https://64.media.tumblr.com/c3c4ecb5bfed8fa9f0590c54206ddb30/cff2318529321620-44/s1280x1920/42befcc40a517e1f202dda40783be2ffb95c1d92.pnj" alt="Macklin Celebrini at the IHF Worlds, dressed in his red jersey and black helmet. He's surrounded by sparkles, a red vignette, and hearts containing the Canadian flag"></p>
</div>

<div class="mob tw theme-auto">
  <p class="tw-top"><span class="tw-pfp colour4">PO</span><span class="hide"> </span><span class="tw-name">Pace Off</span> <span class="tw-handle">@Pace_Off_Puckers · 3h</span></p>
  <p class="tw-text">Last Metros game of the regular season and <span class="tw-link">@SHollanderHockeyPlayer</span> looks miserable.</p>
  <p class="tw-media"><span>[Shane Hollander looking tired at a press conference]</span></p>
</div>

<div class="mob tw theme-auto">
  <p class="tw-top"><span class="tw-pfp colour8">J</span><span class="hide"> </span><span class="tw-name">Jockles</span> <span class="tw-handle">@jockles25 · 2h</span></p>
  <p class="tw-text">Ilya Rozanov you will always be famous to me</p>
  <div class="tw-media video"><iframe src="https://player.vimeo.com/video/1169167060?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" title="Ilya Rozanov | Come Home"></iframe><p class="vid-desc">[Video: a tribute edit of Ilya Rozanov, made from Heated Rivalry footage and set to "Would You Come Home" by Tyler Blackburn]</p></div>
</div>

<div class="mob tw theme-auto">
  <p class="tw-top"><span class="tw-pfp colour5">HF</span><span class="hide"> </span><span class="tw-name">Hockey Fan</span> <span class="tw-handle">@hockeyfan · 1d</span></p>
  <p class="tw-text">Who's got the cup this year?</p>
  <p class="tw-opt res win p75">Montreal<span class="hide"> </span><span class="tw-pct">75%</span></p>
  <p class="tw-opt res p25">Boston<span class="hide"> </span><span class="tw-pct">25%</span></p>
  <p class="tw-pollinfo">97 votes · Final results</p>
</div>

<div class="mob tw theme-auto">
  <p class="tw-top"><span class="tw-pfp colour2">G</span><span class="hide"> </span><span class="tw-name">Geri</span> <span class="tw-handle">@Geronimum · 4h</span></p>
  <p class="tw-text">Rink at night vs rink in the morning. Guess which one I prefer</p>
  <p class="tw-media two"><span class="tw-photo"><span class="tw-desc">[A photo of the empty rink at night]</span></span><span class="tw-photo"><span class="tw-desc">[A photo of the same rink at 6am, full of children in helmets]</span></span></p>
  <p class="tw-warn"><b>Content warning: Sensitive content</b><br>The Tweet author flagged this Tweet as showing sensitive content.</p>
</div>

8.2.3 Tweet Container

A tweet is a single container, <div class="mob tw theme-auto">, with a few lines inside it. There's no header or body here - the lines go straight in:

HF Hockey Fan @hockeyfan · 2h

Can't believe that overtime goal.

3 Reposts   13 Likes   1 Reply

<div class="mob tw theme-auto">
  <p class="tw-top"><span class="tw-pfp colour5">HF</span><span class="hide"> </span><span class="tw-name">Hockey Fan</span> <span class="tw-handle">@hockeyfan · 2h</span></p>
  <p class="tw-text">Can't believe that overtime goal.</p>
  <p class="tw-stats"><b>3</b> Reposts &nbsp; <b>13</b> Likes &nbsp; <b>1</b> Reply</p>
</div>

The next few sections go through each of those three lines.

8.2.4 Name and Handle

The first line, tw-top, has the account's picture, name, handle and the time:

SH Scott Hunter ✔ @SHunter · 5m

<p class="tw-top"><span class="tw-pfp colour6">SH</span><span class="hide"> </span><span class="tw-name">Scott Hunter <span class="tw-tick">✔</span></span> <span class="tw-handle">@SHunter · 5m</span></p>
  • tw-name is the bold display name.
  • tw-tick inside the name adds the blue verified tick. Leave it out if the account isn't verified.
  • tw-handle is the grey @handle, with the time after it. To take the handle from a character's profile, put a handle span in place of the @handle, with the handle typed inside it in a hide span for readers with the workskin off: <span class="tw-handle"><span class="handle pfp-shane"><span class="hide">@ShaneHollanderHockeyPlayer</span></span> · 2h</span> (see Character Profiles, in the Core, Themes, and Extras chapter).

8.2.5 Profile Picture

Every tweet has the account's round profile picture at the start of the name line. Put a tw-pfp span first in the tw-top line, with the initials inside it, and add colour1 to colour10 for a colour. When there's a picture, the handle moves under the name, like it does in the app:

HF Hockey Fan @hockeyfan · 2h

<p class="tw-top"><span class="tw-pfp colour5">HF</span><span class="hide"> </span><span class="tw-name">Hockey Fan</span> <span class="tw-handle">@hockeyfan · 2h</span></p>

For a real picture, put the picture tag inside a pfp span inside the tw-pfp:

Profile picture of samthecat, a black and white cat screaming at the cameraSam @samthecat · 1h

<p class="tw-top"><span class="tw-pfp"><span class="pfp"><img src="https://64.media.tumblr.com/6898dc3a42cc6c7ab9729360b71366e4/ba033a52c8982cb0-bf/s2048x3072/b548d2fe61b02e530c0edd2ee6a6bd56ab73ad2c.jpg" alt="Profile picture of samthecat, a black and white cat screaming at the camera"></span></span><span class="tw-name">Sam</span> <span class="tw-handle">@samthecat · 1h</span></p>

Or use a profile, so the same person has the same picture everywhere: <span class="tw-pfp"><span class="pfp pfp-shane"></span></span> (see Profile Pictures, in the Core, Themes, and Extras chapter). It works the same way in replies - just give the reply's name line the tw-top class, like the replies in the thread. The colours for colour1 to colour10 are set in the Twitter/X CSS, so you can change them there.

8.2.6 Tweet Text

The text of the tweet goes in tw-text. To make a hashtag, an @mention or a link blue, wrap it in a span with tw-link:

Reminder to everyone that there could be (and likely are) queer players on many of the teams that didn't pledge. Thoughts go out to them. #HunterShortlist @SHunter

<p class="tw-text">Reminder to everyone that there could be (and likely are) queer players on many of the teams that didn't pledge. Thoughts go out to them. <span class="tw-link">#HunterShortlist</span> <span class="tw-link">@SHunter</span></p>

8.2.7 Stats Line

The row of reposts, likes and replies is tw-stats. Put each number in <b> to make it bold, and use &nbsp; to space them out:

3 Reposts   13 Likes   1 Reply

<p class="tw-stats"><b>3</b> Reposts &nbsp; <b>13</b> Likes &nbsp; <b>1</b> Reply</p>

8.2.8 Replies

A reply is its own container, with the class tw-reply instead of tw. Put it straight underneath the tweet and the two join up into a thread:

Replying to @ZimBits

H Holster @HolsterInLaw · 2h

I played all through college with a guy whose boyfriend was also on the team. That man now plays professionally. This is not the whole story of queer hockey.

<div class="mob tw-reply">
  <p class="tw-replying">Replying to <span class="tw-link">@ZimBits</span></p>
  <p class="tw-top"><span class="tw-pfp colour2">H</span><span class="hide"> </span><span class="tw-name">Holster</span> <span class="tw-handle">@HolsterInLaw · 2h</span></p>
  <p>I played all through college with a guy whose boyfriend was also on the team. That man now plays professionally. This is not the whole story of queer hockey.</p>
</div>

tw-replying is the little grey "Replying to" line at the top. For a longer comment section, add as many tw-reply containers as you like, one after another.

8.2.9 Quote Tweets

To quote another tweet inside a tweet, add a paragraph with tw-quote after the text:

Reporter @sportsdesk
Sources say the trade is happening.

<p class="tw-quote"><b>Reporter</b> <span class="tw-handle">@sportsdesk</span><br>Sources say the trade is happening.</p>

Put the quoted account's name in <b> and their handle in tw-handle, then a line break and their words. The rounded box around it is drawn for you.

8.2.10 Community Notes

For the grey "Readers added context" box at the bottom of a tweet, use tw-note:

Readers added context: the trade has not been confirmed.

<p class="tw-note">Readers added context: the trade has not been confirmed.</p>

8.2.11 Timestamp Line

A tweet opened on its own page also shows the exact time and date above the counts. Add it with tw-date, just before the stats line:

8:23 AM · 11 May 23

<p class="tw-date">8:23 AM · 11 May 23</p>

8.2.12 Liked and Reposted Counts

When the account has liked or reposted the tweet, Twitter colours that count. To get that, wrap the number and its word in a span - tw-liked for a pink like, tw-rt for a green repost:

8:23 AM · 11 May 23

580 Reposts   2.6k Likes   10 Replies

<p class="tw-date">8:23 AM · 11 May 23</p>
<p class="tw-stats"><span class="tw-rt"><b>580</b> Reposts</span> &nbsp; <span class="tw-liked"><b>2.6k</b> Likes</span> &nbsp; <b>10</b> Replies</p>

8.2.13 Labels: Promoted and Circle Tweets

For a little grey line like "Promoted", or the notice on a Twitter Circle tweet, use tw-label:

Only people in @MetrosMomager's Twitter Circle can see this Tweet.

<p class="tw-label">Only people in @MetrosMomager's Twitter Circle can see this Tweet.</p>

8.2.14 Sensitive Content Warning

To cover a tweet's picture with the sensitive content warning, use tw-warn, with the heading in <b>:

Content warning: Sensitive content
The Tweet author flagged this Tweet as showing sensitive content.

<p class="tw-warn"><b>Content warning: Sensitive content</b><br>The Tweet author flagged this Tweet as showing sensitive content.</p>

8.2.15 Polls

A poll is a set of tw-opt options, with a tw-pollinfo line for the number of votes and the time left. While a poll is still open, each option is just an outlined box. Polls work in a tw-reply as well as a tweet, like Stan's:

Montreal

Boston

179 votes · 13 minutes left

<p class="tw-opt">Montreal</p>
<p class="tw-opt">Boston</p>
<p class="tw-pollinfo">179 votes · 13 minutes left</p>

For a finished poll, add res to every option, plus a bar size from p0 to p100 to match its percentage. The sizes are p0, p10, p20, p25, p30, p33, p40, p50, p60, p67, p70, p75, p80, p90 and p100. The winning option also gets win, which makes its bar blue. The percentage goes in a tw-pct span:

Montreal 75%

Boston 25%

97 votes · Final results

<p class="tw-opt res win p75">Montreal<span class="hide"> </span><span class="tw-pct">75%</span></p>
<p class="tw-opt res p25">Boston<span class="hide"> </span><span class="tw-pct">25%</span></p>
<p class="tw-pollinfo">97 votes · Final results</p>

8.2.16 Pictures and Videos

To add a picture or a video to a tweet, put it in a tw-media box, with a normal picture or video tag inside. Your own link goes in src, and a description of the picture goes in alt:

Macklin Celebrini at the IHF Worlds, dressed in his red jersey and black helmet. He's surrounded by sparkles, a red vignette, and hearts containing the Canadian flag

<p class="tw-media"><img src="https://64.media.tumblr.com/c3c4ecb5bfed8fa9f0590c54206ddb30/cff2318529321620-44/s1280x1920/42befcc40a517e1f202dda40783be2ffb95c1d92.pnj" alt="Macklin Celebrini at the IHF Worlds, dressed in his red jersey and black helmet. He's surrounded by sparkles, a red vignette, and hearts containing the Canadian flag"></p>

If you'd rather not host a picture, you can describe it in a span instead, in square brackets:

[Shane Hollander looking tired at a press conference]

<p class="tw-media"><span>[Shane Hollander looking tired at a press conference]</span></p>

For a video, use the embed code from a video site like Vimeo or YouTube. Add video to the box, which gives the player the right size, and put the embed code inside it. Keep the whole src link, including everything after the ? (Vimeo needs all of it to play the video), plus frameborder and a title that names the video for screen readers. You can leave out the width and height, because the box sets the size:

[Video: a tribute edit of Ilya Rozanov, made from Heated Rivalry footage and set to "Would You Come Home" by Tyler Blackburn]

<div class="tw-media video"><iframe src="https://player.vimeo.com/video/1169167060?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" title="Ilya Rozanov | Come Home"></iframe><p class="vid-desc">[Video: a tribute edit of Ilya Rozanov, made from Heated Rivalry footage and set to "Would You Come Home" by Tyler Blackburn]</p></div>

AO3 only allows embeds from certain sites, so check AO3's FAQ for the current list. A video file you host yourself can also go in a video tag with controls, inside a plain tw-media box. Videos don't get alt text on AO3, so add a video description straight after the video instead, like the one in the example above (see Video Descriptions, under Accessibility, in the Core, Themes, and Extras chapter).

For a tweet with several pictures, add two, three or four to the box to match the number of pictures, and put each picture tag in a tw-photo span. The span crops each picture to fit its space without squashing it. For the square spaces (all four in the four-photo layout, and the two small ones in the three-photo layout), add class="land" to the picture tag of any photo that's wider than it is tall (see Pictures in Boxes and Circles, in the Core, Themes, and Extras chapter). Two pictures sit side by side, both tall:

Black and white cat staring through a gap between a screen and a desk, with blurred cables hanging down around and blue sky behind Black and white cat screaming at the camera, on a red patterned rug

<p class="tw-media two">
  <span class="tw-photo"><img src="https://64.media.tumblr.com/694221426fb8229480fb3fb87b528ca7/ba033a52c8982cb0-01/s1280x1920/636653581e07a970475075f480c1717b23a72c0a.jpg" alt="Black and white cat staring through a gap between a screen and a desk, with blurred cables hanging down around and blue sky behind"></span>
  <span class="tw-photo"><img src="https://64.media.tumblr.com/6898dc3a42cc6c7ab9729360b71366e4/ba033a52c8982cb0-bf/s2048x3072/b548d2fe61b02e530c0edd2ee6a6bd56ab73ad2c.jpg" alt="Black and white cat screaming at the camera, on a red patterned rug"></span>
</p>

Three pictures have one tall picture on the left and two stacked on the right:

Yuna @MetrosMomager · 2h

Cat Sitting Again.

Black and white cat staring through a gap between a screen and a desk, with blurred cables hanging down around and blue sky behind Black and white cat screaming at the camera, on a red patterned rug Black and white cat holding out a paw daintily, on a beige and green cat tree. The cat looks to be stepping into the frame from the left

<p class="tw-media three">
  <span class="tw-photo"><img src="https://64.media.tumblr.com/694221426fb8229480fb3fb87b528ca7/ba033a52c8982cb0-01/s1280x1920/636653581e07a970475075f480c1717b23a72c0a.jpg" alt="Black and white cat staring through a gap between a screen and a desk, with blurred cables hanging down around and blue sky behind"></span>
  <span class="tw-photo"><img src="https://64.media.tumblr.com/6898dc3a42cc6c7ab9729360b71366e4/ba033a52c8982cb0-bf/s2048x3072/b548d2fe61b02e530c0edd2ee6a6bd56ab73ad2c.jpg" alt="Black and white cat screaming at the camera, on a red patterned rug"></span>
  <span class="tw-photo"><img class="land" src="https://64.media.tumblr.com/a99a60f0293cf7df3604b4a6dd4705f6/ba033a52c8982cb0-cc/s1280x1920/cb4c277845d0c3ef666d16b86b75509266b795b3.jpg" alt="Black and white cat holding out a paw daintily, on a beige and green cat tree. The cat looks to be stepping into the frame from the left"></span>
</p>

Four pictures make a grid of two rows:

Black and white cat staring through a gap between a screen and a desk, with blurred cables hanging down around and blue sky behind Black and white cat screaming at the camera, on a red patterned rug Black and white cat holding out a paw daintily, on a beige and green cat tree. The cat looks to be stepping into the frame from the left Black and white cat sitting in an opened red suitcase, carry on size, on the floor behind a white door, and on a red patterned rug

<p class="tw-media four">
  <span class="tw-photo"><img class="land" src="https://64.media.tumblr.com/694221426fb8229480fb3fb87b528ca7/ba033a52c8982cb0-01/s1280x1920/636653581e07a970475075f480c1717b23a72c0a.jpg" alt="Black and white cat staring through a gap between a screen and a desk, with blurred cables hanging down around and blue sky behind"></span>
  <span class="tw-photo"><img src="https://64.media.tumblr.com/6898dc3a42cc6c7ab9729360b71366e4/ba033a52c8982cb0-bf/s2048x3072/b548d2fe61b02e530c0edd2ee6a6bd56ab73ad2c.jpg" alt="Black and white cat screaming at the camera, on a red patterned rug"></span>
  <span class="tw-photo"><img class="land" src="https://64.media.tumblr.com/a99a60f0293cf7df3604b4a6dd4705f6/ba033a52c8982cb0-cc/s1280x1920/cb4c277845d0c3ef666d16b86b75509266b795b3.jpg" alt="Black and white cat holding out a paw daintily, on a beige and green cat tree. The cat looks to be stepping into the frame from the left"></span>
  <span class="tw-photo"><img src="https://64.media.tumblr.com/45b3b47d7c42b593f6242a40153a629c/ba033a52c8982cb0-d7/s2048x3072/4e71b117e87747d78dd3d95595cecc77eec48d38.jpg" alt="Black and white cat sitting in an opened red suitcase, carry on size, on the floor behind a white door, and on a red patterned rug"></span>
</p>

To describe a picture instead of showing it, put a span with tw-desc inside the tw-photo, with the description in square brackets:

[A photo of the empty rink at night][A photo of the same rink at 6am, full of children in helmets]

<p class="tw-media two"><span class="tw-photo"><span class="tw-desc">[A photo of the empty rink at night]</span></span><span class="tw-photo"><span class="tw-desc">[A photo of the same rink at 6am, full of children in helmets]</span></span></p>

All of this works in a tw-reply too.

8.2.17 A Scrollable Thread

A tweet with lots of replies can go in a scrolling window, with a "Tweet your reply" bar that stays at the bottom, like the thread at the top of this chapter. Wrap everything in tw-thread (with a theme class), put the tweet and the replies in a tw-scroll box, and finish with a tw-foot bar after it:

Reply - Tweet your reply

<p class="tw-foot"><span>Reply</span><span class="hide"> - </span>Tweet your reply</p>

The tweet and the replies keep their normal classes, but leave the theme class off them, because the tw-thread already has it. Only the box with the replies scrolls, once there's more than about a phone screen's worth. You don't need this for a short thread - ordinary tweets already scroll if they get too tall (see Scrolling Long Chats in the Core, Themes, and Extras chapter).

8.3 Twitter/X DMs

Here's the two kinds of DM you can build: a message between two people, or a group chat. As before, the full HTML is underneath each, and the rest of this section takes it apart.

8.3.1 A One-to-One DM

Shane Hollander - @ShaneHollanderHockeyPlayer

Shane: saw your tweet

Ilya: it was meant to be funny

Shane: it wasn't

10:14 PM

Ilya: it was a little bit funny

10:15 PM

Shane: ok it was a little bit funny

[Reactions: 😏 1]

Ilya: I am always funny

[Reactions: 🙄 1]

Shane: Macklin Celebrini at the IHF Worlds, dressed in his red jersey and black helmet. He's surrounded by sparkles, a red vignette, and hearts containing the Canadian flag

Ilya: [A photo of Ilya pulling a face at the camera]

Ilya: ▶0:02

10:21 PM

Start a message

The full HTML for this chat
<div class="mob twdm theme-auto">
  <p class="mob-head">Shane Hollander<span class="hide"> - </span><span>@ShaneHollanderHockeyPlayer</span></p>
  <div class="mob-body">
    <p class="msg in"><span class="hide"><em>Shane:</em> </span>saw your tweet</p>
    <p class="msg out"><span class="hide"><em>Ilya:</em> </span>it was meant to be funny</p>
    <p class="msg in"><span class="hide"><em>Shane:</em> </span>it wasn't</p>
    <p class="twdm-time">10:14 PM</p>
    <p class="msg out"><span class="hide"><em>Ilya:</em> </span>it was a little bit funny</p>
    <p class="twdm-time time-out">10:15 PM</p>
    <p class="msg in"><span class="hide"><em>Shane:</em> </span>ok it was a little bit funny</p>
    <p class="twdm-reacts"><span class="hide">[Reactions: </span>&#128527; 1<span class="hide">]</span></p>
    <p class="msg out"><span class="hide"><em>Ilya:</em> </span>I am always funny</p>
    <p class="twdm-reacts out"><span class="hide">[Reactions: </span>&#128580; 1<span class="hide">]</span></p>
    <p class="msg in pic"><span class="hide"><em>Shane:</em> </span><img src="https://64.media.tumblr.com/c3c4ecb5bfed8fa9f0590c54206ddb30/cff2318529321620-44/s1280x1920/42befcc40a517e1f202dda40783be2ffb95c1d92.pnj" alt="Macklin Celebrini at the IHF Worlds, dressed in his red jersey and black helmet. He's surrounded by sparkles, a red vignette, and hearts containing the Canadian flag"></p>
    <p class="msg out pic text"><span class="hide"><em>Ilya:</em> </span>[A photo of Ilya pulling a face at the camera]</p>
    <p class="msg out voice"><span class="hide"><em>Ilya:</em> </span><span class="twdm-play">&#9654;</span><span class="twdm-wave"></span><span class="twdm-dur">0:02</span></p>
    <p class="twdm-time time-out">10:21 PM</p>
  </div>
  <p class="twdm-foot"><span>Start a message</span></p>
</div>

8.3.2 A Group DM

Rookie Dinner - 4 people

Hayden:

are we still going out?

[Reactions: 👍 😂 3]

Shane:

yes. Ilya is paying

Ilya: I did not agree to this

Scott:

you did, actually. there are witnesses

7:02 PM

Start a message

The full HTML for this chat
<div class="mob twdm theme-auto">
  <p class="mob-head">Rookie Dinner<span class="hide"> - </span><span>4 people</span></p>
  <div class="mob-body">
    <p class="who">Hayden<span class="hide">:</span></p>
    <p class="msg in">are we still going out?</p>
    <p class="twdm-reacts"><span class="hide">[Reactions: </span>&#128077; &#128514; 3<span class="hide">]</span></p>
    <p class="who">Shane<span class="hide">:</span></p>
    <p class="msg in">yes. Ilya is paying</p>
    <p class="msg out"><span class="hide"><em>Ilya:</em> </span>I did not agree to this</p>
    <p class="who">Scott<span class="hide">:</span></p>
    <p class="msg in">you did, actually. there are witnesses</p>
    <p class="twdm-time">7:02 PM</p>
  </div>
  <p class="twdm-foot"><span>Start a message</span></p>
</div>

8.3.3 Twitter/X DM Window

DMs are built like iMessage - a container, a header and a body - with the module class twdm, so the container is <div class="mob twdm theme-auto">. First comes the header:

Shane Hollander - @ShaneHollanderHockeyPlayer

<p class="mob-head">Shane Hollander<span class="hide"> - </span><span>@ShaneHollanderHockeyPlayer</span></p>

The span in the header is the person's @handle. After the header comes <div class="mob-body">, which holds all of the messages.

8.3.4 Simple Messages

Messages are paragraphs with msg and either in or out. Sent messages are blue and received ones are grey:

Shane: saw your tweet

Ilya: it was meant to be funny

<p class="msg in"><span class="hide"><em>Shane:</em> </span>saw your tweet</p>
<p class="msg out"><span class="hide"><em>Ilya:</em> </span>it was meant to be funny</p>
Each part of a message, piece by piece
  • <p class="msg in"> - the bubble. in is grey on the left, out is blue on the right.
  • <span class="hide"><em>Shane:</em> </span> - only for readers with the workskin off. It's hidden in the chat, where the colours and sides show who's talking. With the workskin off, they don't, and a one-to-one DM has no names shown anywhere else, so this label is how those readers know who sent it.
  • saw your tweet - the message itself.

With the workskin off, this reads:

Shane: saw your tweet

Ilya: it was meant to be funny

Swap the name for whoever is talking. There's more on this in Accessibility, in the Core, Themes, and Extras chapter.

8.3.5 Timestamps

Twitter/X shows a small time under each message. Add it with twdm-time, straight after the message it belongs to:

Shane: it wasn't

10:14 PM

Ilya: it was a little bit funny

10:15 PM

<p class="msg in"><span class="hide"><em>Shane:</em> </span>it wasn't</p>
<p class="twdm-time">10:14 PM</p>
<p class="msg out"><span class="hide"><em>Ilya:</em> </span>it was a little bit funny</p>
<p class="twdm-time time-out">10:15 PM</p>

The second time has two classes - time-out lines it up on the right, under one of your messages. Leave it off for the other person's messages, and the time sits on the left.

8.3.6 Reactions

To show a reaction under a message, add a twdm-reacts paragraph straight after it. Add out to put it on the right, under one of your own messages. The two hide spans are only for readers with the workskin off, so the reaction reads "[Reactions: 😏 1]" instead of a stray emoji:

Shane: ok it was a little bit funny

[Reactions: 😏 1]

Ilya: I am always funny

[Reactions: 🙄 1]

<p class="msg in"><span class="hide"><em>Shane:</em> </span>ok it was a little bit funny</p>
<p class="twdm-reacts"><span class="hide">[Reactions: </span>&#128527; 1<span class="hide">]</span></p>
<p class="msg out"><span class="hide"><em>Ilya:</em> </span>I am always funny</p>
<p class="twdm-reacts out"><span class="hide">[Reactions: </span>&#128580; 1<span class="hide">]</span></p>

8.3.7 Pictures in DMs

A picture in a DM is a message with pic added. Put a picture tag inside it, or add text as well and describe the picture in words:

Shane: Macklin Celebrini at the IHF Worlds, dressed in his red jersey and black helmet. He's surrounded by sparkles, a red vignette, and hearts containing the Canadian flag

Ilya: [A photo of Ilya pulling a face at the camera]

<p class="msg in pic"><span class="hide"><em>Shane:</em> </span><img src="https://64.media.tumblr.com/c3c4ecb5bfed8fa9f0590c54206ddb30/cff2318529321620-44/s1280x1920/42befcc40a517e1f202dda40783be2ffb95c1d92.pnj" alt="Macklin Celebrini at the IHF Worlds, dressed in his red jersey and black helmet. He's surrounded by sparkles, a red vignette, and hearts containing the Canadian flag"></p>
<p class="msg out pic text"><span class="hide"><em>Ilya:</em> </span>[A photo of Ilya pulling a face at the camera]</p>

8.3.8 Voice Messages

A voice message is a message with voice, holding a play button in twdm-play, an empty twdm-wave span (the CSS draws the sound bars) and the length in twdm-dur:

Ilya: ▶0:02

<p class="msg out voice"><span class="hide"><em>Ilya:</em> </span><span class="twdm-play">&#9654;</span><span class="twdm-wave"></span><span class="twdm-dur">0:02</span></p>

8.3.9 Start a Message Bar

To finish off the window with the "Start a message" bar, add a twdm-foot after the body, inside the container:

Start a message

<p class="twdm-foot"><span>Start a message</span></p>

The header and this bar stay where they are, and once the chat gets long, the messages in between scroll.

8.3.10 Group Chats

For a group DM, put the group's name in the header (and the number of people in the span). Above each person's messages, add their name with who. The name shows either way, so it only needs a hidden colon after it, not the full label - your own messages, with no name above them, still need that. A reaction can have more than one emoji in it:

Hayden:

are we still going out?

[Reactions: 👍 😂 3]

<p class="who">Hayden<span class="hide">:</span></p>
<p class="msg in">are we still going out?</p>
<p class="twdm-reacts"><span class="hide">[Reactions: </span>&#128077; &#128514; 3<span class="hide">]</span></p>

← Previous Chapter · Chapter Index · Next Chapter →