Help with making a character text box

Twine Version: 2.6.2
SugarCube: 2.36.1

Hello! I’m trying to create text boxes for character speech, and with what I have so far in the CSS area, I get a plain box. I’m not too familiar with CSS, and I’d like to have a border that separates the image icon, the text, as well as a box above showing the character’s name.

Currently, it looks like this:


table.speech {
  border: 2px solid #ffffff;;


<table class="speech" width="700px">
  <tr align=left>
    <td><img src="" alt="icon-player" border="0" width="150" height="150"></td>
    <td style="text-align:left" width=600px><span style="color:aquamarine"> Text.</span></td>

I’d like for the end result to look like this:

Thanks in advance for any and all suggestions/advice.

Hi there,
Have you taken a look at Chapel’s Speech macro? I think this is what you might be looking for.

1 Like

I, like Manon, would also suggest looking at Chapel’s Speech Box System addon.

But to answer your question about how to create such a layout, it is all done by placing 4 sided HTML elements inside other elements. And then using CSS to size, position, and style the child elements within the structure. Which is the core technique behind Chapel’s addon. :slight_smile:

Such a element structure would look something like.

<div class="chat">
	<img src="url-to-the-portrait-image-file">
	<p>Hey there!</p>

note: The <<nobr>> macro is being used to supress the automatic conversion of line-breaks within the above structure in to <br> elements, as they can play havoc when using CSS to layout the elements in a structure.

Grid based layout CSS like the following can then be used to position the child elements of the structure relative to each other. Such CSS would be placed within the Story > Stylesheet area of your project.

.chat {
	display: grid;
	grid-template-columns: 20% 80%;
	grid-template-rows: auto;
		"name name"
		"image text";
	justify-items: stretch;
	border: 1px solid #eee;
.chat > p:first-of-type {
	grid-area: name;
	font-weight: bold;
	margin: 0;
	padding: 0.2em;
	border-bottom: 1px solid #eee;
.chat > img {
	grid-area: image;
	border-right: 1px solid #eee;
.chat > p:last-of-type {
	grid-area: text;
    margin: 0;
	padding: 0.5em;

note: The complete guild to using Grid layout can be found on the CSS Tricks site.

Once you have determined what HTML element structure you need, and the CSS required to style it the way you want, you would then create yourself either a custom Widget or a custom Macro to generate instances of said structure with the correct Name / Image / Text over & over again.

But, you can save yourself all the hard work by using an existing implementation like Chapel’s :slight_smile:

1 Like

Unfortunately, a lot of table layout attributes are deprecated (not recommended) in favour of CSS standards. Still, some people find HTML structure easier to understand. Here’s your text box done with <table> tags and standard (recommended) CSS.


table.speech {
	width: 700px;
	border-collapse: collapse;
table.speech td {
	text-align: left;
	padding: 10px;
	border: 2px solid #ffffff;
table.speech {
	color: #ffffff;
table.speech td.text {
	width: 100%;
	color: aquamarine;


<table class="speech">
		<td class="name" colspan="2">Name</td>
		<td><img src="" alt="icon-player" border="0" width="150" height="150"></td>
		<td class="text">Text.</td>

And the result looks like this:

Good luck on your project!

It was with that guide and a couple of others that I started with. I’ve never used a macro before so I had no idea how it worked, so I haven’t been able to make sense of how to use it.

You need to add the relevant javascript and CSS linked on the page:
(either the minified or the pretty, they are the same code, but different formatting)

Then use the <<character>> macro to set up the character in the StoryInit special passage:
<<character 'name' 'The Name Displayed on the page' 'the URL of the image'>>
(if you don’t include the The Name Displayed on the page, the macro will display name instead)

Then in the passage you want to use:
<<name>>Whatever text you want in the box<</name>>
(the name is the same as the first defined element in <<character>>)

Or you can just use <<say>> without having to setup the box in StoryInit:
<<say 'name' 'URL of the image>>Whatever text you want in the box<</say>>

Sorry for the late response, I was trying to figure out how to work it. Yep it works, thanks a bunch.

1 Like