IntersectionRender

View Source

NOTE: Introduced feature in v0.4.1.

IntersectionRender disables rendering of child content before it has come into the root element's viewport at least once. Useful for lazy loading content besides media.

<script>
    import {
        Box,
        Code,
        IntersectionRender,
        Spacer,
        Transition,
    } from "@kahi-ui/framework";

    let is_intersecting = false;
</script>

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Box
    palette={is_intersecting
        ? "affirmative"
        : "negative"}
    padding="small"
>
    Scroll down to watch this <Code>Box</Code> change when
    the <Code>Box</Code> comes into view.
</Box>

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<IntersectionRender
    threshold={0.5}
    bind:is_intersecting
>
    <Transition animation="scale" variation="enter">
        <Box palette="inverse" padding="small">
            I am in view!
        </Box>
    </Transition>
</IntersectionRender>

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Box
    palette={is_intersecting
        ? "affirmative"
        : "negative"}
    padding="small"
>
    Scroll up to watch this <Code>Box</Code> change when
    the <Code>Box</Code> comes into view.
</Box>

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

Imports

<script>
    import {IntersectionRender} from "@kahi-ui/framework";
</script>

Compatibility

The Component only runs on clientside Browsers with Javascript enabled. So you need to plan a SSR-compatible fallback if using in a SSR scenario. It is also dependent on IntersectionObserver.

Eager

NOTE: It is good practice to give the IntersectionRender a fixed size that generally matches the child content when using this mode. Otherwise you can end up with janky scrolling.

You can change the behavior of IntersectionObserver by passing in the loading attribute. Which will make the Component ALWAYS disable rendering when outside of the root viewport, not just on initial load.

<script>
    import {
        Box,
        Code,
        IntersectionRender,
        Spacer,
        Transition,
    } from "@kahi-ui/framework";

    let is_intersecting = false;
</script>

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Box
    palette={is_intersecting
        ? "affirmative"
        : "negative"}
    padding="small"
>
    Scroll down to watch this <Code>Box</Code> change when
    the <Code>Box</Code> comes into view.
</Box>

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<IntersectionRender
    class="intersectionrender-eager"
    loading="eager"
    threshold={0.5}
    bind:is_intersecting
>
    <Transition animation="scale" variation="enter">
        <Box
            class="intersectionrender-eager"
            palette="inverse"
            padding="small"
        >
            I am in view!
        </Box>
    </Transition>
</IntersectionRender>

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Box
    palette={is_intersecting
        ? "affirmative"
        : "negative"}
    padding="small"
>
    Scroll up to watch this <Code>Box</Code> change when
    the <Code>Box</Code> comes into view.
</Box>

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<style>
    :global(.intersectionrender-eager) {
        height: 40px;
    }
</style>

Fallthrough

USAGE: REPL renders in your Browser, so this feature will always conditionally render anyway.

By default, IntersectionRender will never render when running in SSR environments. You can change it to always render in those environments via the fallthrough property.

<script>
    import {
        Box,
        Code,
        IntersectionRender,
        Spacer,
        Transition,
    } from "@kahi-ui/framework";

    let is_intersecting = false;
</script>

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Box
    palette={is_intersecting
        ? "affirmative"
        : "negative"}
    padding="small"
>
    Scroll down to watch this <Code>Box</Code> change when
    the <Code>Box</Code> comes into view.
</Box>

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<IntersectionRender
    threshold={0.5}
    fallthrough
    bind:is_intersecting
>
    <Transition animation="scale" variation="enter">
        <Box palette="inverse" padding="small">
            I am in view!
        </Box>
    </Transition>
</IntersectionRender>

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Box
    palette={is_intersecting
        ? "affirmative"
        : "negative"}
    padding="small"
>
    Scroll up to watch this <Code>Box</Code> change when
    the <Code>Box</Code> comes into view.
</Box>

<Spacer spacing="huge" />
<Spacer spacing="huge" />

<Spacer spacing="huge" />
<Spacer spacing="huge" />

Properties

IntersectionRender

Name Description Types
fallthrough When the property is set, IntersectionRender will always render the child content in SSR environments, e.g. SvelteKit
boolean
loading When the property is set, IntersectionRender will always disable rendering of child content when not intersecting the root viewport.
eager
root Sets an Element which is an ancestor of the intended target, whose bounding rectangle will be considered the viewport. Any part of the target not visible in the visible area of the root is not considered visible.
document.body (DEFAULT) Document Element
root_margin Sets a set of offsets to add to the root's bounding_box when calculating intersections, effectively shrinking or growing the root for calculation purposes.
string
threshold Sets a number(s) between 0.0 and 1.0, specifying a ratio of intersection area to total bounding box area for the observed target. A value of 0.0 means that even a single visible pixel counts as the target being visible. 1.0 means that the entire target element is visible.
number number[]
has_intersected Exports a readonly property which is true whenever IntersectionRender has intersected the root viewport at least once.
readonly boolean
is_intersecting Exports a readonly property which is true whenever IntersectionRender is intersecting the root viewport.
readonly boolean

Events

IntersectionRender

Name Description Types
intersectionend Fires whenever an intersection with the root viewport ends.
CustomEvent<IntersectionObserverEntry[]>
intersectionstart Fires whenever an intersection with the root viewport starts.
CustomEvent<IntersectionObserverEntry[]>

Slots

IntersectionRender

Name Description Types
default Default unnamed slot.
{}