Components
Link
Example markup
<a href="https://thefifthworld.com">Link</a>
- Use links to go somewhere. Use buttons to do something.
- Avoid unclear link text like “click here” or just “here.” Look for ways to use the link text to describe what the user will find if she clicks on it.
Lists
- Here we have an unordered list.
- Unordered lists present related items, but not in any particular order.
-
List items can include paragraph tags.
They can even include multiple paragraph tags.
-
List items can also include other lists.
- An unordered list item
- Another unordered list item
- One more unordered list item
- With this list item, we’ll ramble on for a little bit so that we have lots of text and so can see how the list item handles longer text when it will need to wrap that text, thusly.
- Here we have an ordered list.
- Unordered lists present items in a specified order.
-
List items can use paragraph tags and other lists.
- First ordered list item
- Second ordered list item
-
Third ordered list item
-
We can go three layers deep with distinct ordering systems.
- Four, actually.
-
- With this list item, we’ll ramble on for a little bit so that we have lots of text and so can see how the list item handles longer text when it will need to wrap that text, thusly.
Example markup
<!-- Unordered list -->
<ul>
<li>List item</li>
<li>List item</li>
<li>List item</li>
</ul>
<!-- Ordered list -->
<ol>
<li>List item</li>
<li>List item</li>
<li>List item</li>
</ol>
- Use lists when you need to present a list of items.
- Use an ordered list when the order of the items has meaning.
- Use an unordered list when the order of the items does not have any meaning.
Horizontal rule
Example markup
<hr />
- Use to create a thematic break between paragraphs (e.g., shifting to a new scene in a story or to a new topic within a section).
Table
# | Line | Syllables |
---|---|---|
1 | There was an Old Man with a beard, | Eight |
2 | Who said, ‘It is just as I feared! | Eight |
3 | Two Owls and a Hen, | Five |
4 | Four Larks and a Wren, | Five |
5 | Have all built their nests in my beard!’ | Eight |
5 | Thirty-four |
Example markup
<table>
<tcaption>Table 1. A limerick</tcaption>
<thead>
<tr>
<th class="num">#</th>
<th>Line</th>
<th class="short">Syllables</th>
</tr>
</thead>
<tbody>
<tr>
<td class="num">1</td>
<td>There was an Old Man with a beard,</td>
<td class="short">Eight</td>
</tr>
<tr>
<td class="num">2</td>
<td>Who said, ‘It is just as I feared!</td>
<td class="short">Eight</td>
</tr>
<tr>
<td class="num">3</td>
<td>Two Owls and a Hen,</td>
<td class="short">Five</td>
</tr>
<tr>
<td class="num">4</td>
<td>Four Larks and a Wren,</td>
<td class="short">Five</td>
</tr>
<tr>
<td class="num">5</td>
<td>Have all built their nests in my beard!’</td>
<td class="short">Eight</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="num">5</td>
<td />
<td class="short">Thirty-four</td>
</tr>
</tfoot>
</table>
- Use to present tabular data. That means a collection of items, where each item generally has some value for a given set of keys (columns).
Blockquote
The singular magic of a place is evident from what happens there, from what befalls oneself or others when in its vicinity. The songs proper to a specific site will share a common style, a rhythm that matches the pulse of the place, attuned to the way things happen there – to the sharpness of the shadows or the rippling speech of water bubbling up from the ground. In traditional Ireland, a country person might journey to one distant spring in order to cure her insomnia, to another for strengthening her ailing eyesight, and to yet another to receive insight and protection from thieves. For each spring has its own powers, its own blessings, and its own curses. Different gods dwell in different places, and different demons. Each place has its own dynamism, its own patterns of movement, and these patterns engage the senses and relate them in particular ways, instilling particular moods and modes of awareness, so that unlettered, oral people will rightly say that each place has its own mind, its own personality, its own intelligence.
David Abram, The Spell of the Sensuous: Perception and Language in a More-Than-Human World (p. 182)
Example markup
<blockquote>
<p>The singular magic of a place…</p>
<cite>David Abram…</cite>
</blockquote>
- Use the
<blockquote>
tag to wrap a long quotation (one or several paragraphs). - If you don’t mention the source of the quote in the text, use the
<cite>
tag, as in the example provided here.
Aside
Example markup
<aside>
<h3>Missing Games</h3>
<p>Roleplaying games require significant blocks…</p>
<p>To play a Fifth World saga you don’t…</p>
</aside>
- Use an aside for content that relates only indirectly or tangentially to the main content of the page. Sidebars represent perfect examples of asides.
Label
Example markup
<label for="label1">Label</label>
<input type="text" id="label1" />
<label for="label2">
Label
<p class="note">This label has a note.</p>
</label>
<input type="text" id="label2" />
Input
Example markup
<input type="text" placeholder="Text input" />
<input type="email" placeholder="Email input" />
<input type="password" placeholder="Password input" />
<input type="search" placeholder="Search input" />
<input type="tel" placeholder="Telephone input" />
<input type="url" placeholder="URL input" />
- Use the most specific input type for the type of data the field collects. Sometimes this will make no difference (for example, on most desktop browsers, all of these fields may appear the same), but some devices take advantage of this information (for example, phones will often change to a more useful keyboard layout for each of the types used here). If no other type applies, use
text
.
Input (error state)
Sorry, Bad input won’t work.
Example markup
<label for="input-err" class="error">Label</label>
<input type="text" id="input-err" class="error" value="Bad input" />
<p class="error">Sorry, <strong>Bad input</strong> won’t work.</p>
- Use the
error
class to highlight fields that a user will need to correct in order to proceed. - Our guidance on using E-Prime applies to error messages, too!
- Use JavaScript wherever possible to provide immediate feedback, but that doesn’t mean duplicating code. For example, you can write an API endpoint to check inputs, and then use it both on the backend and from the client as an optional enhancement.
- See the Title, Path & Parent component for an example of this component in action. It uses JavaScript to provide a client-side enhancement, which checks a path’s validity against an API. While the path field remains hidden, we use only a paragraph with the
error
class, but when the user has revealed the field the field and its label also use the error state.
Textarea
Example markup
<textarea></textarea>
- Use a textarea anywhere that the user must enter a large amount of text.
Select
Example markup
<select>
<option>Option A</option>
<option>Option B</option>
<option>Option C</option>
<optgroup label="Group 1">
<option>Option D</option>
<option>Option E</option>
<option>Option F</option>
</optgroup>
<optgroup label="Group 2">
<option>Option G</option>
<option>Option H</option>
<option>Option I</option>
</optgroup>
</select>
- Use select when you want a user to choose one option from a list. If she can select multiple options, use a checkbox list.
Checkbox
Example markup
<input type="checkbox" id="checkbox-example" />
<label for="checkbox-example">This is a checkbox.</label>
- Use a single checkbox for binary values, like allowing a user to give consent (for signing up for an email list, for example). Consent only counts when someone gives it freely, so make sure that users always opt in, rather than having to opt out. Having a consent box checked by default does not count as granting consent. If a user could grant “consent” without knowing it, then you can’t actually call what they’ve granted “consent.”
- To allow a user to select zero or more options from a list, use a checkbox list.
Checkbox list
Example markup
<ul class="checkboxes">
<li>
<input type="checkbox" id="checkbox-list1" name="checkbox-list" />
<label for="checkbox-list1">Option #1</label>
</li>
<li>
<input type="checkbox" id="checkbox-list2" name="checkbox-list" />
<label for="checkbox-list2">Option #2</label>
</li>
<li>
<input type="checkbox" id="checkbox-list3" name="checkbox-list" />
<label for="checkbox-list3">Option #3</label>
</li>
</ul>
- Use a checkbox list when a user should select zero or more options from a list. If she should just select one option, use a select instead.
File upload
Example markup
<form action="/your/form/endpoint" method="POST" enctype="multipart/form-data">
<label for="file">File</label>
<input type="file" name="file" id="file" />
</form>
- Use this component to upload a file.
- As a JavaScript enhancement, this component adds drag-and-drop functionality, as well as the option to create a thumbnail for your image. You must include this component inside of a form with an
action
attribute as well asenctype="multipart/form-data
.
Login form
Example markup
<section class="login">
<form action="#login-form" method="post">
<label for="email">Email</label>
<input type="email" name="email" id="email" placeholder="you@example.com" />
<label for="passphrase">Passphrase</label>
<input type="text" name="passphrase" id="passphrase" placeholder="Whisper your secret passphrase" />
<p class="buttons">
<button>Log in</button>
</p>
<p class="note">
<a href="/forgot-passphrase">Forgot your passphrase?</a>
</p>
</form>
<div class="oauth2-login">
<p>Or login with…</p>
<ul>
<li><a href="/login/patreon" class="button patreon">Patreon</a></li>
<li><a href="/login/discord" class="button discord">Discord</a></li>
<li><a href="/login/google" class="button google">Google</a></li>
<li><a href="/login/facebook" class="button facebook">Facebook</a></li>
<li><a href="/login/twitter" class="button twitter">Twitter</a></li>
</ul>
</div>
</section>
- Use this component to offer a user the opportunity to authenticate herself, using either her Fifth World account or any of the OAuth2 providers recognized by the Fifth World website.
Title, Path & Parent
Example markup
<form class="page">
<label for="title">Title</label>
<input id="title" name="title" type="text" placeholder="What do you want to write about?" />
<label for="path">
Path
<p class="note">This sets the page’s URL. If left blank, it will default to a “slugified” version of the title (e.g., “New Page” will become <code>/new-page</code>).</p>
</label>
<input id="path" name="path" type="text" placeholder="/example" />
<label for="parent">
Parent
<p class="note">Should this page belong to another one? <span class="instructions">If so, provide the path to that other page here.</span></p>
</label>
<input id="parent" name="parent" type="text" />
<button>Create Page</button>
</form>
- We designed this component specifically for the title, path, and parent fields used when we create and edit pages. These fields relate to each other and to the rest of the wiki in specific ways, so we built some specific JavaScript enhancements around them. We enhance the parent field with an autocomplete to make it easier to find the page you’d like to connect this page to. We move the path field out of the way unless you want to override the default, based on the title and parent. And if you create an invalid path, we provide a JavaScript enhancement to warn you and disable the form’s submit button.
Panel links
Example markup
<a href="components.html" class="panel">
<h2>Components</h2>
<p>Our component library lists and documents all of the components in the design system.</p>
</a>
- Use this pattern when a page or section focuses primarily on driving a user to a specific link, and that link has both a title and some sort of description to go along with it. This pattern makes the entire block of text interactive.
Like & Unlike
Example markup
<!-- Use this version when the user has not liked the content yet. -->
<p class="likes">
<a href="/path/to/like/content" class="like" data-unlike="/path/to/unlike/content">Like</a>
<span class="count">100</span> likes
</p>
<!-- Use this version when the user has liked the content already. -->
<p class="likes">
<a href="/path/to/unlike/content" class="unlike" data-like="/path/to/like/content">Unlike</a>
<span class="count">101</span> likes
</p>
- Use this component when you know the user’s identity and can tell if she has liked this content before or not. If she has, present the option to unlike it. If she hasn’t, give her the opportunity to like it.
- As a client-side enhancement, this component can send the request without reloading the page. This enhancement uses optimistic feedback, assuming that everything will go well (since it normally does), but then providing an error message if something goes wrong.
- Only use this component when you can also determine how many other people have already liked this content. Use it to present that information to the user.
File download
Example markup
<a href="/path/to/v1.0.pdf" class="download" download>
<span class="label">v1.0.pdf</span>
<span class="details">application/pdf; 30.2 MB</span>
</a>
- Use this component to present a link to download a file (e.g., a PDF).
- Clicking on this component should always open an OS-specific dialogue box to save the file. Make sure to include the
download
attribute to ensure this in modern browsers. This will allow you to use this component even for images that would otherwise load in the browser. - This component should generally follow some text that clearly describes the file so that the user knows exactly what she will get if she downloads it.
Collapsible
Example markup
<aside class="collapsible">
<h3>Missing Games</h3>
<!-- Content -->
</aside>
- You can make the content of any aside collapsible by adding the
collapsible
class. The first element in the<aside>
must be a heading tag, which will be used to toggle the collapsible area open and closed. Any other content can follow. - If JavaScript fails for any reason, collapsible areas render like any other aside.
- Do not place important content inside a collapsible element! Collapsible elements hide items from users, so anything you put into one is something that many users will never see, so you want to make sure that’s OK. For example, we use collapsible areas for metadata forms. If a user never realizes these options exist, that’s OK, because these should be automatically populated with appropriate values, and other users can always correct any problems that may pop up later.
Recent updates
Example markup
<table class="updates">
<tbody>
<tr>
<td>
<a href="/africa">
Africa
<span class="path">/africa</span>
</a>
</td>
<td><time datetime="2020-06-24 19:33">24 Jun 2020 7:33 PM</time></td>
</tr>
<tr>
<td>
<a href="/antarctica">
Antarctica
<span class="path">/antarctica</span>
</a>
</td>
<td><time datetime="2020-06-24 19:33">24 Jun 2020 7:33 PM</time></td>
</tr>
<tr>
<td>
<a href="/eurasia">
Eurasia
<span class="path">/eurasia</span>
</a>
</td>
<td><time datetime="2020-06-24 19:33">24 Jun 2020 7:33 PM</time></td>
</tr>
<tr>
<td>
<a href="/north-america">
North America
<span class="path">/north-america</span>
</a>
</td>
<td><time datetime="2020-06-24 19:33">24 Jun 2020 7:33 PM</time></td>
</tr>
<tr>
<td>
<a href="/south-america">
South America
<span class="path">/south-america</span>
</a>
</td>
<td><time datetime="2020-06-24 19:33">24 Jun 2020 7:33 PM</time></td>
</tr>
<tr>
<td>
<a href="/sahel">
Sahel
<span class="path">/sahel</span>
</a>
</td>
<td><time datetime="2020-06-24 19:33">24 Jun 2020 7:33 PM</time></td>
</tr>
<tr>
<td>
<a href="/pacific">
Pacific Ocean
<span class="path">/pacific</span>
</a>
</td>
<td><time datetime="2020-06-24 19:33">24 Jun 2020 7:33 PM</time></td>
</tr>
<tr>
<td>
<a href="/atlantic">
Atlantic Ocean
<span class="path">/atlantic</span>
</a>
</td>
<td><time datetime="2020-06-24 19:33">24 Jun 2020 7:33 PM</time></td>
</tr>
<tr>
<td>
<a href="/indian">
Indian Ocean
<span class="path">/indian</span>
</a>
</td>
<td><time datetime="2020-06-24 19:33">24 Jun 2020 7:33 PM</time></td>
</tr>
<tr>
<td>
<a href="/arctic">
Arctic Ocean
<span class="path">/arctic</span>
</a>
</td>
<td><time datetime="2020-06-24 19:33">24 Jun 2020 7:33 PM</time></td>
</tr>
</tbody>
</table>
- We use this component on the dashboard to show the ten most recently updated pages on the wiki.
Page history
Summary | ||
---|---|---|
An update
Change made by Jason Godesky, 24 June 2020 7:33 PM |
||
Initial text
Change made by Jason Godesky, 24 June 2020 7:27 PM |
Example markup
<table class="historry">
<thead>
<tr>
<th />
<th />
<th>Summary</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="radio" name="a" value="12346" />
</td>
<td>
<input type="radio" name="b" value="12346">
</td>
<td>
An update
<p class="details">Change made by <a href="/member/123">Jason Godesky</a>, <a href="/page/12346">24 June 2020 7:33 PM</a></p>
</td>
</tr>
<tr>
<td>
<input type="radio" name="a" value="12345" />
</td>
<td>
<input type="radio" name="b" value="12345">
</td>
<td>
Initial text
<p class="details">Change made by <a href="/member/123">Jason Godesky</a>, <a href="/page/12345">24 June 2020 7:27 PM</a></p>
</td>
</tr>
</tbody>
</table>
- We use this component to show the history of changes made to a page.
Page diff
Version created by Jason Godesky on 20 June 2020 8:00 PM | Version created by Giulianna Lamanna on 20 June 2020 8:15 PM |
---|---|
Initial text | Updated some stuff |
Roll back to this version | Current version |
Title | |
Test Page | Test Page |
Path | |
/test | /test |
Parent | |
Body | |
This is the original text. | This is the |
Example markup
<table class="diff">
<thead>
<tr class="version">
<th>Version created by <a href="/member/123">Jason Godesky</a> on 20 June 2020 8:00 PM</th>
<th>Version created by <a href="/member/321">Giulianna Lamanna</a> on 20 June 2020 8:15 PM</th>
</tr>
<tr class="msg">
<th>Initial text</th>
<th>Updated some stuff</th>
</tr>
<tr class="rollback">
<th><a href="/path/to/roll/back/to/this/version">Roll back to this version</a></th>
<th class="current">Current version</th>
</tr>
</thead>
<tbody>
<tr>
<th colspan="2">Title</th>
</tr>
<tr>
<td>Test Page</td>
<td>Test Page</td>
</tr>
<tr>
<th colspan="2">Path</th>
</tr>
<tr>
<td>/test</td>
<td>/test</td>
</tr>
<tr>
<th colspan="2">Parent</th>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<th colspan="2">Body</th>
</tr>
<tr>
<td>This is the original text.</td>
<td>This is the <del>original</del><ins>new</ins> text.</td>
</tr>
</tbody>
</table>
- We use this component to compare two versions of the same page. Show the older version on the left (in the first column) and the more recent version on the right (in the second column).
- The older version never shows any changes, because it serves as the baseline that we compare the more recent version against. The more recent version highlights what changed between them.
- If the more recent version represents the latest version of the page, use the “Current version” version demonstrated here. If it does not represent the most recent version, then both versions should provide links in the header that will provide the user to roll the page back to that version.
Place map
Example markup
<div class="leaflet-wrapper place" data-coords="40.441822,-80.012788"></div>
- We use this map on locations — pages about a particular place. If JavaScript loads, then you see a map of the locale around the place. If JavaScipt fails for any reason, you don’t even know you missed anything.
Action columns
Your Membership
-
Your Profile
Update your name, email, and password, and decide what you want to share about your activity on the Fifth World.
-
Connect
Connect other services like Facebook, Twitter, Patreon, Google, or Github, so you can use them to log in.
-
Invitations
Invite your friends to join the Fifth World, and see a list of all the members that you invited.
-
Chat
Join the Fifth World Discord server to chat with other members.
Example markup
<section class="action-cols">
<h3>Your Membership</h3>
<ul>
<li>
<a href="https://thefifthworld.com/member/1234/edit" class="button">Your Profile</a>
<p>Update your name, email, and password, and decide what you want to share about your activity on the Fifth World.</p>
</li>
<li>
<a href="https://thefifthworld.com/connect" class="button">Connect</a>
<p>Connect other services like Facebook, Twitter, Patreon, Google, or Github, so you can use them to log in.</p
</li>
<li>
<a href="https://thefifthworld.com/invite" class="button">Invitations</a>
<p>Invite your friends to join the Fifth World, and see a list of all the members that you invited.</p>
</li>
<li>
<a href="https://discord.gg/CODE" class="button">Chat</a>
<p>Join the Fifth World Discord server to chat with other members.</p>
</li>
</ul>
</section>
- We use this component to present the options that members have to administer their accounts on the dashboard page.
- You can reuse this component when you have several actions to present and each one requires a bit more explanation than what you can fit on a button.
Create Something
Create Something
Add something new to the Fifth World.
Example markup
<section class="create">
<h3>Create Something</h3>
<p>Add something new to the Fifth World.</p>
<ul>
<li><a href="https://thefifthworld.com/new" class="button">Add a Page</a></li>
<li><a disabled="" title="Coming soon" class="button">Add a Family</a></li>
<li><a disabled="" title="Coming soon" class="button">Add a Character</a></li>
<li><a disabled="" title="Coming soon" class="button">Add a Place</a></li>
<li><a disabled="" title="Coming soon" class="button">Write a Story</a></li>
<li><a href="https://thefifthworld.com/upload" class="button">Upload a File</a></li>
<li><a disabled="" title="Coming soon" class="button">Upload Art</a></li>
</ul>
</section>
- We use this component to present members with their options for creating new pages on the Fifth World website.
- Currently, we have the basic new page and file upload versions available. We’ll add specialized forms for other types of content over time, and update this component’s markup to link to those as they become available.
Image
Example markup
<img src="/img/forest.png" alt="The Suburban Forest, by Nick Pedersen" />
- Every image must have an
alt
tag! Thealt
attribute should meaningfully describe the image shown. - If you have a hard time coming up with appropriate content for this, that might offer you a hint that you shouldn’t use the image. Images that we have a hard time describing usually offer decoration and little else. That means they’ll require extra overheard for users without offering anything substantive in return. As we once heard from Edward Tufte, “however nice your interface is, it would be better if there were less of it.” We find a beauty in simplicity and usability. Have confidence in your design’s ability to stand up without such decoration.
Figure
Example markup
<figure>
<img src="/img/forest.jpg" alt="The Suburban Forest, by Nick Pedersen" />
<figcaption class="numbered">“The Suburban Forest” by <a href="https://nick-pedersen.com/">Nick Pedersen</a></figcaption>
</figure>
- Use a figure to present an image or other such embedded media along with a caption.
- If you add the
numbered
class to the<figcaption>
tag (as in the example above) then a JavaScript enhancement will add Figure X to each such caption, numbering all such figures in the order they appear on the page.
Thumbnail gallery
Example markup
<ul class="thumbnails">
<!-- Repeat the <li> element for each thumbnail in your gallery -->
<li>
<a href="/path/to/image/page">
<img src="/path/to/thumbnail" alt="Title of Work, Artist Name" />
</a>
</li>
</ul>
- Use this component to provide a user with the opportunity to browse through a variety of illustrations or other images.
- This gallery only works with square thumbnails. Do not use this component to display the full pieces themselves.
- The markup provided here assumes that each image has a page that you can link to, as art on the Fifth World website does. If you do not have pages for each work, you can skip the links, but this greatly reduces the utility of the component, since it then only displays thumbnails.
Artist listing
Example markup
<section class="artist">
<h2>
<a href="/path/to/artist/page">Artist Name</a>
</h2>
<ul class="thumbnails">
<!-- Repeat the <li> element for each thumbnail in your gallery -->
<li>
<a href="/path/to/image/page">
<img src="/path/to/thumbnail" alt="Title of Work, Artist Name" />
</a>
</li>
</ul>
</section>
- This component works especially well when you repeat it to show several artists, along with glimpses of their work.
- This component uses the thumbnail gallery component and expands it a bit, adding a unique heading that helps to separate the work of different artists.
- The markup presented here assumes that each artist has a gallery page, and that you will link to them from their headings, but it can also work without those links. Wherever possible, though, do provide links so that users can see more of the artist’s work.
Video
Example markup
<div class="video-wrapper">
<!-- Insert the embed code for your <iframe> from a service like YouTube or Vimeo here. -->
</div>
- Use this component to embed videos from YouTube, Vimeo, or other such video hosting services on a page.