Child-theme installation

WordPress & Picostrap Integration

Place the files, import the SCSS correctly, enqueue scripts in dependency order, and support LiveCanvas content.

Open playground
WP
SCSS path../animate/hf-motion
Set loadingBefore runtime
Cache bustingfilemtime()
picostrap5-child/
├── functions.php
├── animate/
│   ├── _hf-motion.scss
│   ├── hf-motion-sets.js
│   └── hf-motion.min.js
└── sass/
    └── main.scss

Import the SCSS partial

Your main.scss file is inside /sass, while the partial is inside /animate. Go up one level and then enter the animation folder:

// picostrap5-child/sass/main.scss
@import "../animate/hf-motion";

Browsers never load SCSS directly. Compile it through the same Picostrap build process that produces your theme CSS.

Enqueue deferred scripts with the first-paint bootstrap

function sa_enqueue_hf_motion() {
    $directory = get_stylesheet_directory();
    $uri       = get_stylesheet_directory_uri();

    $sets_path  = $directory . '/animate/hf-motion-sets.js';
    $motion_path = $directory . '/animate/hf-motion.min.js';

    wp_enqueue_script(
        'hf-motion-sets',
        $uri . '/animate/hf-motion-sets.js',
        array(),
        file_exists($sets_path) ? filemtime($sets_path) : null,
        array(
            'strategy'  => 'defer',
            'in_footer' => false,
        )
    );

    wp_enqueue_script(
        'hf-motion',
        $uri . '/animate/hf-motion.min.js',
        array('hf-motion-sets'),
        file_exists($motion_path) ? filemtime($motion_path) : null,
        array(
            'strategy'  => 'defer',
            'in_footer' => false,
        )
    );

    $bootstrap = "(function(d,w){"
        . "d.documentElement.classList.add('hf-motion-pending');"
        . "w.HFMotionFirstPaintTimer=w.setTimeout(function(){"
        . "d.documentElement.classList.remove('hf-motion-pending');"
        . "},3000);"
        . "}(document,window));";

    wp_add_inline_script('hf-motion', $bootstrap, 'before');
}
add_action('wp_enqueue_scripts', 'sa_enqueue_hf_motion', 20);

The script strategy array requires WordPress 6.3 or newer. On older WordPress versions, keep the scripts blocking in the head by using false as the final enqueue argument; do not improvise a footer load for above-the-fold motion.

Mark above-the-fold content explicitly

Add the load trigger to opening-viewport reveals. A stagger group passes the trigger to its eligible children:

<div class="hf-stagger-children" data-hf-trigger="load">
  <h1>Opening headline</h1>
  <p>Opening copy</p>
  <a href="#services">Review services</a>
</div>

Leave data-hf-trigger off below-the-fold content so it keeps the default viewport-observed behavior.

LiveCanvas and dynamically inserted content

With observeMutations: true, newly inserted data-hf elements are prepared automatically. For explicit control:

HFMotion.refresh(document.querySelector('#new-content'));

Stacked image example

<div data-hf="parallax" data-hf-set="dramatic">
  <img
    src="<?php echo esc_url($image_url); ?>"
    alt=""
    data-hf="fade"
    data-hf-set="default"
  >
</div>