0 votes
by (1.2k points)

I'm building a shop system and whilst there's a default CSS setup for shops I'm customising some of them to add a bit of character. I'm doing this by having something like this in the passage:

<style>
div[id$='Male']:not([class*="Female"]).shopInventoryList {
    display: inline-table;
    background-color: #151515;
    border-style: none;
    margin: 5px;
    padding: 5px;
    float: left;
    border-radius: 0px;
    vertical-align: top;
    height: 200px;
    font-family: 'Patrick Hand SC', cursive;
    -webkit-box-shadow: 0 0 11px 2px rgba(255, 255, 255, 0.35);
    -moz-box-shadow: 0 0 11px 2px rgba(255, 255, 255, 0.35);
    box-shadow: 0 0 11px 2px rgba(255, 255, 255, 0.35);
	text-transform: uppercase;
    font-family: 'Source Sans Pro';
    font-weight: lighter;
}
</style>

If that's not present then the shop passage falls back on the style defined in the game's main CSS file.

That's been working fine but for the latest shop I'm working on I want to use an embedded image. I've done this elsewhere by encoding it in base64 but those have been stand-alone images using <img> tags. In theory this should work just fine in CSS and the image is under 10 KB.

It seems that I cannot embed the image properly though, at least not using <style> tags. The CSS currently looks like this: https://pastebin.com/gcC1fCE5 (I hit the character limit on here!)

I've included the full image there as from what I can tell pasting it into the style of any given element on any web page successfully adds the woodgrain texture to that element.

Also, oddly, normally I can modify the CSS using browser developer tools but as soon as I add the background imagine the rest of the CSS is shown and applied but is marked in grey and cannot be edited. Very odd.

Is this a limitation of Sugarcube?

Any suggestions on how to add such an image without external files (the main reason I'm using base64)?

1 Answer

+1 vote
by (64.2k points)
selected by
 
Best answer

I'm doing this by having something like this in the passage:

<style>
div[id$='Male']:not([class*="Female"]).shopInventoryList {
    /* […] */
    font-family: 'Patrick Hand SC', cursive;
    /* […] */
    font-family: 'Source Sans Pro';
    /* […] */
}
</style>

You're specifying the font-family property twice there.

 

Is this a limitation of Sugarcube?

You're probably running into the fact that using HTML <style> and <script> tags isn't really supported by the regular HTML tag parser at the moment.

Try wrapping your <style> tags within the verbatim HTML parser markup—i.e. <html></html>.  For example:

<html><style>
	/* your styles here */
</style></html>

 

Any suggestions on how to add such an image without external files (the main reason I'm using base64)?

The above suggestion will probably work.  That said, what compiler are you using?

 

by (1.2k points)

Try wrapping your <style> tags within the verbatim HTML parser markup—i.e. <html></html>

That fixed the problem instantly. Thanks!

You're specifying the font-family property twice there.

Yep. Not sure why because it's not in the code for the passage! Either that or I fixed it in Twine but was copying code from a previous version that I was testing in a browser. Can't sneak anything past you wink

by (64.2k points)

Update.  The next release of SugarCube will better handle <style> tags within passages, so use of the verbatim HTML parser markup will no longer be necessary.  In other words, the following will work as you'd expect:

<style>
	/* your styles here */
</style>

Additionally.  The tags will be processed for image passage transclusion exactly the same as the Story Stylesheet or stylesheet-tagged passages.

by (1.2k points)

Excellent!

I'm not really sure what this bit means though:

Additionally.  The tags will be processed for image passage transclusion exactly the same as the Story Stylesheet or stylesheet-tagged passages.

by (64.2k points)

Exactly what it says on the tin.

Beyond the methods of embedding images that work in every story format—such as you're currently using.  SugarCube natively supports image embedding via a mechanism known as image passages.  An image passage is simply a passage with a special tag whose content is the Base64 encoded data URI form of an image.

Various Twine/Twee compilers are able to construct image passages for you—Twine 1 and Tweego for sure, maybe others—but it can easily be done manually.

To use image passages within SugarCube, regardless of how they were created, you'd use one of the available image markups, but instead of supplying a URL, you specify the name of the image passage.

For direct use, you may use either the [img[]] markup or an <img> tag with the data-passage attribute.  For example—assume an image passage named woodgrain:

[img[woodgrain]]
	/* OR */
<img data-passage="woodgrain">


For use within CSS, you must use the [img[]] markup.  For example—again assuming an image passage named woodgrain:

background: [img[woodgrain]] no-repeat center center;
	/* OR */
background-image: [img[woodgrain]];

Obviously, for that to work, the CSS must receive special pre-processing to transclude the markup with standard CSS syntax.  Stylesheets already receive that processing step.  What the comment meant is that with the release of SugarCube v2.22.0, <style> tags will also receive the processing—those not within a verbatim HTML parser markup anyway.

by (1.2k points)

Exactly what it says on the tin.

Yeeeeah, you say that but it's not exactly layman's terms wink

The explanation cleared it up though!

I've only ever worked in Twine2 so it looks like image passages aren't on the table for me, or at least I can't find an example of what the exact syntax for base64 passages is. I'm not entirely clear on whether Twine2 doesn't support them in the sense of their very existence or merely creating them. I know I can't import images directly but can I create a passage manually that's an equivalent - and if so, how?

On the plus side this has been doing wonders for my CSS skills as I've been trying my hardest not to use any images if at all possible!

 

by (64.2k points)

As I noted in my last reply, an image passage is simply a passage with a special tag whose content is the Base64 encoded data URI form of an image.

You should already know what a Base64 encoded data URI is since you used one in your pastebin example.  In short, however, it's the bit within the url() functional notation you supplied to the background-image property, which looks like the following:

data:image/jpeg;base64,/9j/4QAYRXhpZgAAS …(cont.)…

Assuming you created that with a tool (online or not), it probably has an option to simply give you the Base64 encoded data URI.

Regardless.  You place the data URI of the image within an otherwise empty passage and tag the passage with the following (exactly):

Twine.image

And your image passage is complete.  Whatever name you gave the image passage is how you reference it via the markup, as noted previously.

by (1.2k points)
Excellent! That works nicely!

Is that hidden away in the documentation somewhere as I feel like I would have encountered it by now if it was. Usually the issue I have with things like this is the precise nature of the syntax. So in this case I didn't know that it shouldn't have, for example, HTML image tags in the passage.

Then again even if I'd got that right I wouldn't have known about the Twine.image tag so thanks!
by (64.2k points)
Information on the construction of image passages?  Not as far as I know.  There's nothing in SugarCube's docs certainly.

Due to having to construct a Base64 encoded data URI for each image, it's the kind of thing that, frankly, should be handled by the tooling, so needing a HOWTO for it has never really come up.

I brought it up here simply because you were already doing the hardest part.
by (1.2k points)
edited by

That at least makes me feel a bit less of a prat laugh

I do my best to read the documentation but my understanding is far from perfect. It does seem rather odd that Twine 2.x doesn't support converting images to Base64 passages though!

Is it possible to assign HTML IDs/classes to images using the image markup? I can work around the limitation if not but it'd be handy if it did support them.

edit: oops, I meant markup!

by (64.2k points)

I assume you meant image markup, not macro.

Yes, though how varies depending on which markup you wish to use.  If you meant using the [img[]] markup, then not directly, but you can wrap an element around them easily enough.  If you mean using the <img> markup, then yes, absolutely—it's a normal HTML <img> tag in most respects, it just receives some special processing.


Using a custom styles markup wrapper with the [img[]] markup

→ ID
@@#foo;[img[woodgrain]]@@

→ Class(es)
@@.bar;[img[woodgrain]]@@
@@.bar.baz.qaz;[img[woodgrain]]@@

→ ID & class(es)
@@#foo;.bar;[img[woodgrain]]@@
@@#foo;.bar.baz.qaz;[img[woodgrain]]@@

A few example style rules (mostly just the selectors):

#foo>img { … }
.bar>img { … }
#foo.bar>img { … }

Using the <img> markup

→ ID
<img data-passage="woodgrain" id="foo">

→ Class(es)
<img data-passage="woodgrain" class="bar">
<img data-passage="woodgrain" class="bar baz qaz">

→ ID & class(es)
<img data-passage="woodgrain" id="foo" class="bar">
<img data-passage="woodgrain" id="foo" class="bar baz qaz">

A few example style rules (mostly just the selectors):

#foo { … }
.bar { … }
#foo.bar { … }

 

by (1.2k points)
Oops, yep, I meant markup.

Before today I was writing custom widgets for the few images I'd decided to include in various places (not CSS related) so I've since gone back and changed them to the image passage method. My widget setup allowed me to assign IDs so I was applying CSS to them that way but now I'm using the title method instead. I don't know what I'll want to do with images in future though so I figured it might be prudent to ask whether IDs/classes were supported in the simplified markup.

The data passage method should be fine if I need it though - thanks!
Welcome to Twine Q&A, where you can ask questions and receive answers from other members of the community.

You can also find hints and information on Twine on the official wiki and the old forums archive.

See a spam question? Flag it instead of downvoting. A question flagged enough times will automatically be hidden while moderators review it.
...