Inline Answers

Inline answers are blocks of HTML 5 content that are displayed on answer pages. Solve for All and the platforms Solve for All clients run on put restrictions on the content to ensure user security is not compromised. This page describes those limitations as well as some ways to get styling and dynamic behavior despite them.

To get started quickly, check out the guides to creating an Answer Generator that produces server-side sanitized content and an Answer Generator that produces trusted content.

Server-Side Sanitized Content

By allowing Solve for All to sanitize the HTML content you pass to it, you can have your content injected into the answers page without sandboxing, resulting in a more native look and faster loading. However, the set of tags and attributes is restricted; in particular, no scripts are allowed, and no id attributes are allowed.

Allowed Tags and Attributes

Server-side sanitization allows only a subset of HTML tags and attributes. All allowed tags can have these attributes:

The following is a list of allowed tags, along with the corresponding attributes allowed, in addition to the list above:

Tag Allowed Attributes
a href (must be an absolute URL), data-show-count (useful for Twitter follow buttons), rel
b None
big None
blockquote None
body None
br None
caption None
cite None
code None
col None
colgroup None
dd None
del class, title, cite, datetime
div None
dl None
dt None
em None
h1, h2, h3, h4, h5, h6 None
hr None
html None
i None
img alt, src, data-img-fallback-method, data-img-remove-on-error, data-img-restore-src, data-img-src-0 ~ data-img-src-3 (See image fallbacks) All sources must be absolute URLs.
ins class, title, cite, datetime
kbd None
li None
ol None
p None
pre None
q None
s None
samp None
section None
small None
span None
strike None
strong None
style None
sub None
sup None
table None
tbody None
th None
thead None
td None
tfoot None
tr None
u None
ul None
var None

Styling

Without additional styling, you can still make sanitized inline content look decent since Bootstrap 3.3.6 (with the Spacelab theme from Bootswatch) and Font Awesome 4.5.0 CSS classes and fonts are available.

Inline styles

You can include inline styles, subject to the following restrictions:

  • Styles must be defined within <style> blocks or in the style attribute of any HTML element. No external styles via link elements or @import rules are allowed.
  • The following CSS properties are not supported:
    • position
    • left
    • right
    • top
    • bottom
  • Most vendor-specific CSS properties, such as -moz-border-radius are not supported (you probably don't need them in modern browsers anyway). The exceptions are:
    • -webkit-align-content
    • -webkit-align-items
    • -webkit-align-self
    • -webkit-box-align
    • -webkit-box-flex
    • -webkit-box-orient
    • -webkit-box-pack
    • -webkit-flex
    • -webkit-flex-direction
    • -webkit-flex-grow
    • -webkit-flex-justify-content
    • -webkit-flex-shrink
    • -webkit-flex-wrap
    • -webkit-line-clamp
    • -webkit-order
  • All URL values must conform to the following rules:
    • The protocol must either be http or https
    • The path extension must be .gif, .ico, .jpeg, .jpg, .png, .svg, .tif, or .tiff
  • Only top-level style rules are supported. So import rules, font faces, viewport rules, and media queries don't work. We'll probably add support for font faces and media queries in the future.

Your CSS is isolated to only affect your content, so no need to worry about affecting other content on the answers page.

Special CSS classes

Additionally, CSS classes in this format can be used to adjust the spacing between elements:

[spacing type]-[direction]_[spacing amount]

where

  • [spacing-type] is one of margin, border, and padding
  • [direction] is one of top, bottom, left, and right
  • [spacing amount] is the amount of space, in pixels. The amount must be between -100 and 100 pixels.

So for example,

<div class="margin-left_-10 padding-top_20">
  This is moved by special classes!
</div>

gives the <div> the style margin-left: -10px; padding-top: 20px;.

Some more special classes are available for sanitized content:

Class CSS
initially_hidden .initially_hidden { display: none; }
block .block { display: block; }
inline-block .inline-block { display: inline-block; }
inline .inline { display: inline; }
plain .plain { color: black; } /* Useful for plain links */
plain_on_hover .plain_on_hover:hover { color: black; }

Dynamic Behavior

Even without Javascript, sanitized inline content can have some dynamic behavior which is provided by the Javascript of the containing answers page.

Content Expansion

If your inline answer contains a lot of content that the user may not want to see immediately, you can hide it in a content expansion block like this:

<div>
  <span class="content_expander">
    <span class="content_expander_label">See more ... </span>
    <i class="fa fa-chevron-down"></i>
  </span>
</div>
<div class="content_expandable initially_hidden">
   Some initially hidden, gory details here.
</div>

The <div> containing the text "Some initially hidden, gory details here." will be hidden initially, due to the initially_hidden class. When the user clicks the icon, the <div> slides down and the icon changes to . This can be reversed, or the content can start visible, and slide up when the user clicks the icon, like this:

<div>
  <span class="content_expander">
    <span class="content_expander_label">Hide details </span>
    <i class="fa fa-chevron-up"></i>
  </span>
</div>
<div class="content_expandable">
  Some initially visible content here.
</div>

Generally, this is how it works: when an element with the class content_expander is clicked, the code on the answers page looks at its next immediate sibling. If the sibling has the content_expandable class, the code slides it down or up, toggling the visibility, and stops. Otherwise, the parent of the element with the class content_expander is traversed, and its sibling is examined, and so on, until a content_expandable sibling element is found or the parents are exhausted.

The text inside the <span> with class content_expander_label will be changed according to the following rules:

  • On expansion:
    1. If the data-less-label attribute is present on the <span>, its value will replace the text
    2. Otherwise, the first of occurrance of the string more will be changed to less, respecting capitalization
  • On contraction:
    1. If the data-more-label attribute is present on the <span>, its value will replace the text
    2. Otherwise, the first of occurrance of the string less will be changed to more, respecting capitalization

Image Fallbacks

<img> tags can also declare fallback source URLs by setting these attributes:

Attribute Description
data-img-fallback-method Which method to use to implement fallbacks. One of:
  • onerror: Use the onerror handler of the img element. The src of the <img> tag is set with the fallback sources one by one until no error is detected. This is the default method, since it does not require the source URLs to be reachable via cross-site AJAX requests. However, this method is probably less reliable.
  • ajax: Load the fallback sources via an AJAX HEAD request. The first one that loads successfully is set as the src attribute of the image. Requires the fallback URLs be reachable via cross-site AJAX requests.
data-img-src-0 ~ data-img-src-3 Up to 4 possible URLs to use for the source URL. Will be tried sequentially starting from data-img-src-0.
data-img-remove-on-error If all fallbacks fail, the <img> tag is removed from the DOM unless this attribute is set to false.
data-img-restore-src If all fallbacks fail, the src attribute of the <img> set to the value of the data-img-src-0 attribute unless this attribute is set to false.

To use image fallbacks, set the above attributes and also give the image the class with_fallback, but do not set the src attribute. For example:

<img data-img-src-0="http://upload.wikimedia.org/wikipedia/commons/9/9e/JQuery_logo.svg"
 data-img-src-1="http://upload.wikimedia.org/wikipedia/en/9/9e/JQuery_logo.svg"
 class="with_fallback">

We'll probably open-source the image fallback code in the future.

Trusted Content

If your Answer Generator produces answers with the serverSideSanitized property set to false, and the user grants the trusted_content permission, the inline content will be inserted without modification into a sandboxed iframe. This means you can use any HTML element including <script>. iframes that hold sandboxed content are sandboxed with sandbox="allow-forms allow-scripts allow-top-navigation". There are some additional limitations to be aware of:

Sizing

For now, a limitation of trusted content is that the preferred size of the iframe can't be detected, so Solve for All uses the preferredHeight property of the inline answer, which may not match the actual height of the content. In the future, we'll be able to fix this provided you include a special script in the inline content.

Links

<a> elements should have the attribute target="_top" so that they open when clicked. Otherwise, the browser will try to load the content into the iframe which won't work if the linked site doesn't allow its content to be displayed in an iframe.

Scripts in the Google Chrome Extension

Google Chrome restricts the set of hosts that can be used to load scripts in extensions, to hosts that are whitelisted by the extension. Additionally, it does not allow execution of inline scripts. (For more details, see the Chrome documentation on the Content Security Policy.) Therefore, content that displays fine on solveforall.com may have to modified so that it can display inside the Solve for All Chrome extension. The Chrome extension allows scripts from these sources:

  • https://*.google.com
  • https://*.gstatic.com
  • https://cdn.rawgit.com
  • https://dl.dropbox.com
  • https://dl.dropboxusercontent.com
  • https://ssl.google-analytics.com
  • https://*.googleapis.com
  • https://netdna.bootstrapcdn.com
  • https://code.jquery.com
  • https://cdnjs.cloudflare.com
  • https://cdn.jsdelivr.net
  • https://api.opencnam.com
  • https://public-api.wordpress.com
  • https://backend.deviantart.com
  • https://api.meetup.com
  • https://soundcloud.com
  • https://*.slideshare.net
  • https://*.barchart.com
  • https://*.twitter.com
  • https://ssl.microsofttranslator.com

You can get popular Javascript libraries from the CDNs above, in particular, jsDelivr allows you to download multiple scripts in a single request. For your own scripts, you have the following options:

  • Upload them to Dropbox and follow these instructions on how to get public links suitable for inclusion in a web page
  • Store the script in a public GitHub repository, then use RawGit to serve them. No uptime guarantees though.

You will need to externalize your scripts if they are inline within the HTML content.

If you have any hosts you'd like to see added, please contact us at feedback@solveforall.com.

Theming

To make your inline content match the style of the answers page, we recommend you include the stylesheet of the Spacelab theme from Bootswatch, using the following HTML in the <head> section:

<link href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/spacelab/bootstrap.min.css" rel="stylesheet">