-
Allows you to render slides with silky smooth CSS View Transitions.
-
Provides customizable slide transitions.
-
Provides full screen toggling of your presentation.
-
Provides keyboard shortcuts.
-
Works with dynamically or statically generated web sites.
The following assumes you are already using htmx and have it configured in the same manner as documented in this setup section.
To load CSS and JavaScript, add the following to your page:
<link href="https://unpkg.com/htmx-slide@latest/build/style.css" rel="stylesheet">
<script src="https://unpkg.com/htmx-slide@latest"
integrity="sha384-fScIyPEy6OzOa5PnWzBtl662obABP840cxSPq0o1LD66Iz6CmreHu/K3kpcKNBut"
crossorigin="anonymous"
defer>
</script>To use via Import Maps, add the following to your layout:
<link href="https://unpkg.com/htmx-slide@latest/build/style.css" rel="stylesheet">
<script type="importmap">
{
"imports": {
"htmx-slide": "https://unpkg.com/htmx-slide@latest"
}
}
</script>
<script type="module">
import "htmx-slide";
</script>To install via NPM, run:
npm install htmx-slideOnce the library is installed, you only need to import it:
import "htmx-slide/build/style.css";
import "htmx-slide";To use, add a top-level element (section in this case) where you enable the slide extension. Once the extension has been enabled, you can then add your view port, progress bar, and actions. Example:
<section class="htmx-slide"
hx-ext="slide"
hx-select-oob="#slide, #progress, #actions"
hx-swap="transition:true">
<div class="container">
<div class="viewport">
<img id="slide"
src="one.svg"
alt="One"
class="slide"
width="960"
height="540"
data-transitions-forward="push"
data-transitions-backward="wipe">
</div>
<progress id="progress" class="progress" value="0" max="4"></progress>
<div id="actions" class="actions">
<a href="_five.html"
class="action"
data-direction="backward"
hx-get="_five.html"
hx-trigger="click, keyup[key=='ArrowLeft'] from:body"
hx-push_url="true">
Previous
</a>
<span class="status">1 of 5</span>
<a href="_two.html"
class="action"
data-direction="forward"
hx-get="_two.html"
hx-trigger="click, keyup[key=='ArrowRight'] from:body"
hx-push_url="true">
Next
</a>
<button data-fullscreen-trigger>[ ]</button>
</div>
</div>
</section>The above is the minimum to load the extension, the initial slide, and navigate between slides. Here’s the breakdown:
-
section(required): Thesectionelement provides a semantic element to enable the extension and supply the minimum attributes. You’re not limited to thesectionelement as any valid HTML element would work for your top level element.-
class(optional): Necessary to style the extension. If you don’t want to use the default styles then you can remove along with the associatedstyle.css. Thestyle.cssis compiled from the style sheets located in thelib/stylesheetsof this project. If you need a detailed breakdown on how CSS View Transitions and key frames work, check out the htmx View Transitions article to learn more. -
hx-ext(required): Ensures this extension is enabled. -
hx-select-oob(required): Defines which elements should be selected as out of bounds updates when moving forward and backward through your slides since only the slide, progress, and action elements are the only elements that will change per each slide. The values must be IDs, not classes. -
hx-swap(required): Ensures htmx enables CSS View Transitions properly. If missing, no transitions will fire.
-
-
.container(required): Ensures the view port, progress bar, and associated actions don’t expand the width of your slides. -
.viewport(required): Ensures contents of this element can be toggled via the Fullscreen API. -
#slide(required): Ensures this can be updated (swapped) out of bounds. -
#progress(optional): Provides real-time progress. Delete and remove fromhx-select-oobif not desired. -
#actions(required): Ensure you can navigate to the previous, next, first, and last slide. You can add or remove actions as desired. The above shows what’s possible. When using action links, use the following attributes:-
.action(optional): Allows you to style the action if desired. -
data-direction(required): Ensures this extension knows which direction to transition the slide. Valid values are:forwardorbackward. -
hx-get(required): Gets the next slide. -
hx-trigger(required): Triggers the action. Feel free to customize keyboard short behavior as desired. -
hx-push_url(optional): Ensures your browser history is updated so browser back and forward navigation works.
-
-
data-fullscreen-trigger(optional): Triggers full screen mode. The value is meant to be empty. If a value is supplied, it’ll be ignored. You can, optionally, add adata-fullscreen-targetwith any valid CSS selector in case you want to target a different element for full screen. The default is:.viewport.
When building your implementation, the above shows the initial page to render. All subsequent pages only need to be HTML fragments/partials which have the elements shown in the .container as those are the only elements that need to change upon each HTTP GET request.
In addition to the above, you can configure the extension via the following data attributes:
<section hx-ext="slide"
data-slide="#slide"
data-transitions-forward="push"
data-transitions-backward="push"
data-fullscreen-key="f"
data-fullscreen-trigger="[data-fullscreen-trigger]">The above shows the default settings which is why you don’t need to supply these when enabling this extension. Should the above defaults not be desired, then you can customize as follows:
-
data-slide: Use any valid CSS selector to target a different slide element. -
data-transitions-forward: The view transition name for forward movement. -
data-transitions-backward: The view transition name for backward movement. -
data-fullscreen-key: The full screen keyboard shortcut. -
data-fullscreen-trigger: The element which triggers the full screen toggle (usually a button).
You can also override global extension behavior by using the transitions data attribute on your slide element. Example (truncated for brevity):
<img id="slide"
data-transitions-forward="iris"
data-transitions-backward="wipe">The above gives you fine level control over the behavior of each slide instead of inheriting the extension’s behavior or the global defaults and is a powerful way to keep your presentation interesting with different transitions.
The data-transitions-* attributes adhere to the following order of precedence (where the first takes highest priority):
-
Slide
-
Extension
-
Defaults
Keyframes provide the low level animation sequences for use in your view transitions (see below). The source for these can be found in the lib/stylesheets/keyframes.css file which is included when you import the htmx-slide/build/style.css as described Setup section above.
Each keyframe uses the htmx-slide-* prefix but feel free to add your own and link them to your own view transitions.
View transitions (i.e. ::view-transition-old, ::view-transition-new) are built atop the keyframes and are what make the slide transitions possible. The source for these can be found in the lib/stylesheets/view_transitions.css file which is included when you import the htmx-slide/build/style.css as described Setup section above.
Several view transitions are provided for you:
-
Curtain
-
Iris
-
Push (default)
-
Scale
-
Wipe
You can customize each slide’s transition, as mentioned in the Configuration section, by using the following data attributes on the extension element or the slide element. Example:
-
data-transitions-forward="iris": Uses the iris transition when moving forward to the next slide. -
data-transitions-backward="scale": Uses the scale transition when moving backward to the next slide.
Each view transition name uses the htmx-slide-<name>-forward prefix. You can create and use your own transitions by use the same format as long as your name is unique and doesn’t conflict with the provided transitions. Once your custom view transition is ready, simply use the name of your transition for the data-transitions-* attributes to enable.
You are not limited to previous and next actions as shown above as you can add as many as you deem necessary. For example, the following shows how to use previous, next, first, and last actions for navigation.
With First and Last Actions
<div id="actions" class="actions">
<a href="_five.html"
class="action"
data-direction="backward"
hx-get="_five.html"
hx-trigger="click, keyup[key=='ArrowLeft'] from:body"
hx-push_url="true">
Previous
</a>
<span class="status">1 of 5</span>
<a href="_two.html"
class="action"
data-direction="forward"
hx-get="_two.html"
hx-trigger="click, keyup[key=='ArrowRight'] from:body"
hx-push_url="true">
Next
</a>
<a href="_one.html"
class="action"
data-direction="backward"
hx-get="_one.html"
hx-trigger="click, keyup[key=='['] from:body"
hx-push_url="true">
First
</a>
<button data-fullscreen-trigger>[ ]</button>
<a href="_five.html"
class="action"
data-direction="forward"
hx-get="_five.html"
hx-trigger="click, keyup[key==']'] from:body"
hx-push_url="true">
Last
</a>
</div>As long as your actions are defined within the #actions element, this extension will swap them in properly.
Due to the power of htmx’s out-of-bound selects used by this extension, this means your HTML fragments only need to supply the element IDs as defined by your out-of-bound selects. This gives you the freedom to supply a full page, partial page, or exact elements for maximum flexibility when using this extension.
To contribute, run:
git clone https://github.com/bkuhlmann/htmx-slide
cd htmx-slide
bin/setupTo build, run:
bin/buildTo view the interactive demonstration, run:
bin/demo
open http://localhost:3030Any changes to source code will automatically rebuild and reload the demonstration.
To deploy, follow these steps:
-
Ensure you are on the
mainbranch. -
Ensure you’ve updated the
CITATION.cffandpackage.jsonwith new version and committed the changes. -
Run the following:
bin/build
bin/publish-
Built with Rubysmith.
-
Engineered by Brooke Kuhlmann.