Supported CSS Properties
Fold.page uses your CSS as an API for building a 3D scene. It reads the browser's final computed values — meaning standard CSS properties, cascade rules, media queries, pseudo-selectors, and responsive breakpoints all apply exactly as they do in the 2D page. Your existing styles just work in 3D.
Text Properties
Extracted for all text-type elements — paragraphs, headings, links, list items, buttons, and .foldpage-text elements.
| CSS Property | 3D Effect | Notes |
|---|---|---|
color | Text fill color | RGBA values are split: RGB sets the color, alpha sets opacity. |
font-size | Text size | |
font-family | Font file selection | Mapped to bundled fonts. See Font Families below. |
font-weight | Bold variant | Values ≥ 700 (or keyword bold) select the bold font variant. |
font-style | Italic variant | italic selects the italic variant. Combines with bold for bold-italic. |
line-height | Vertical line spacing | Falls back to font-size if the computed value is not a number. |
letter-spacing | Character spacing | Combined with a per-font letter-spacing factor. See Font Families. |
text-align | Horizontal alignment | left, center, right, justify. Also affects 3D anchor position. |
text-transform | Case transformation | uppercase is applied to the text string before rendering. |
text-decoration | Underline line | Presence of underline enables underline rendering. See Text Decoration. |
text-decoration-color | Underline color | Stored only when it explicitly differs from the element's text color. |
text-decoration-style | Underline style | solid (default, omitted), double, dotted, dashed, wavy. |
text-decoration-thickness | Underline weight | Accepts px and em values. auto and from-font use the renderer default. |
text-underline-offset | Underline distance from baseline | px and em values. Positive = further from text. auto uses renderer default. |
text-indent | First-line indent | px, em, and % (relative to element width) are all resolved to a pixel value. |
text-shadow | Shadow text meshes | Each shadow layer becomes a separate 3D text mesh. See Text Shadows. |
vertical-align | Vertical text offset | Keywords (sub, super, middle, top, bottom, text-top, text-bottom) and numeric values are mapped to em-based Y offsets. |
white-space | Whitespace handling | nowrap suppresses wrapping. pre, pre-wrap, pre-line, break-spaces preserve spaces and newlines. Drives text extraction. |
tab-size | Tab width | Integer number of spaces per tab (default 8 per spec). Only meaningful when white-space preserves tabs. |
direction | Text direction | rtl reverses character order for right-to-left language support. |
opacity | Text transparency | Original opacity preserved before DOM hiding. Reproduced on the 3D mesh. |
Font Families
Fold.page ships with bundled TTF fonts for all five generic CSS families, each with available variants:
CSS font-family contains | Mapped Font | Variants |
|---|---|---|
serif | Caladea | Regular, Bold, Italic, Bold Italic |
sans-serif | Lato | Regular, Bold, Italic, Bold Italic |
monospace | Inconsolata | Regular, Bold, Black |
cursive | Edu NSW ACT Cursive | Regular, Bold |
fantasy | Caveat | Regular, Bold |
How matching works: Fold.page checks the computed font-family string for each generic keyword (serif, sans-serif, etc.). The matched family determines the base font. font-weight and font-style then select the specific variant. Unrecognised custom font names fall back to sans-serif (Lato) with full weight/style resolution preserved.
Text Shadows
Each text-shadow layer becomes a separate 3D text mesh, stacked behind the primary text at increasing Z depths.
h1 {
text-shadow:
2px 2px rgba(255, 100, 200, 0.4),
4px 4px rgba(200, 50, 150, 0.3),
6px 6px rgba(150, 0, 100, 0.2);
}text-shadow component | 3D effect |
|---|---|
| X offset | Horizontal position offset (scaled to world units) |
| Y offset | Vertical position offset (scaled, Y-inverted for 3D) |
| Blur radius | Soft glow on the shadow |
| Color | Fill and outline color for the shadow mesh |
Performance cap: Fold.page limits text shadows to 20 layers per element.
Depth-Driven Text Shadows (no CSS text-shadow required)
A text element with no CSS text-shadow and no visible background (no background fill/gradient, no box-shadow) can use data-foldpage-depth / data-foldpage-depth-interval instead — the same attributes that drive image depth-repetition (see Image Capabilities → Depth Repetition):
<!-- No text-shadow, no background: depth 9 / interval 2 = round(4.5) = 5 synthetic
shadow layers, 50% opacity, inheriting the text color. Text + layers together
shift forward 10px (5 × 2) toward the camera. -->
<p data-foldpage-depth="9" data-foldpage-depth-interval="2">Bulging text</p>- Layer count:
round(depth / interval), capped at 20 layers — same formula and cap as images. - Each synthetic layer is 50% opacity and inherits the element's text color — there's no per-layer styling attribute for text the way
box-shadowstyles image depth copies. - The entire stack — including the primary text mesh — is pushed forward toward the camera by the clamped layer count × interval, mirroring the no-
box-shadowimage case. Text bulges out of the page rather than sinking into it. - Mutually exclusive with CSS
text-shadow. If the element has an authoredtext-shadow,data-foldpage-depthis ignored for text entirely — the real shadow layers keep their own CSS-defined position, color, and blur, and are not pushed forward.data-foldpage-depth-intervalstill controls the Z-spacing between those real layers (replacing the fixed default spacing), just without the synthesis or the forward push. - Mutually exclusive with a visible background. If the element has a background fill/gradient or
box-shadow,data-foldpage-depthdrives that background's extrusion instead (see Data Attribute API →data-foldpage-depth) and text is left alone.
Text Decoration
The text decoration system reads the longhand sub-properties that the browser always decomposes from the text-decoration shorthand:
a {
text-decoration: underline wavy 2px #ff6600;
text-underline-offset: 4px;
}| Property | Values read | Notes |
|---|---|---|
text-decoration / text-decoration-line | underline, none | Presence of underline enables the underline mesh. |
text-decoration-color | Any color | Stored only when different from the element's color. Defaults to color otherwise. |
text-decoration-style | solid, double, dotted, dashed, wavy | solid is the default and is omitted (renderer uses its fast path). |
text-decoration-thickness | px, em | auto and from-font fall back to renderer default. |
text-underline-offset | px, em | auto (the default) falls back to renderer default. |
These properties also participate in hover state extraction — you can change underline appearance on :hover and Fold.page will pick it up.
Box and Layout Properties
| CSS Property | 3D Effect | Notes |
|---|---|---|
padding-left | X position offset, text width | Shifts text anchor and narrows text block. |
padding-right | X position offset, text width | Shifts text anchor and narrows text block. |
padding-top | Y position offset | Shifts text origin downward. |
padding-bottom | Y position | Used in height calculations. |
z-index | Draw order | Numeric z-index is read and used to sort 3D elements within the same scene group. auto is treated as 0. |
display | Visibility | Elements with display: none are skipped. |
visibility | Visibility | visibility: hidden elements and their ancestors cause element skipping. |
top | Sticky threshold | For position: sticky elements, top determines the scroll offset at which the element transitions from scroll mode to fixed mode. |
Background Properties
Extracted for .foldpage-bg elements.
| CSS Property | 3D Effect | Notes |
|---|---|---|
background-color | Plane surface color | Full RGBA support. Alpha controls plane opacity. |
background-image | Plane texture or gradient | url() loads as a texture. linear-gradient and radial-gradient are rendered via canvas to a texture. |
border-radius | Rounded corners | Computed shorthand radius applied to the rounded plane geometry. |
border-top-left-radius etc. | Per-corner radius | Individual corner radii are read when the four corners differ. |
border-width | Border thickness | Uniform border thickness, scaled to world units. |
border-top-width / border-right-width / border-bottom-width / border-left-width | Per-side border thickness | Applied when sides differ. |
border-color | Border color | Uniform border color. RGBA supported. |
border-top-color / border-right-color / border-bottom-color / border-left-color | Per-side border color | Applied when sides have different colors. |
box-shadow | Depth repetition layers | Multiple box-shadow layers drive per-instance depth copies. See Box Shadow Depth. |
background-size, background-position, and background-repeat are not read. Background images render at the element's layout dimensions without size or position transforms.
Box Shadow Depth
box-shadow drives per-instance depth repetition on images and .foldpage-bg elements when combined with data-foldpage-depth:
.card {
box-shadow:
0 4px 8px rgba(0,0,0,0.5),
0 8px 16px rgba(100,0,200,0.3);
}Each shadow becomes a separate 3D mesh offset on the Z axis. Shadow properties map to 3D layer properties: offset-x/y → mesh XY offset, color → tint, spread-radius → mesh scale, blur-radius → layer opacity, inset → direction.
See Image Capabilities — Depth Repetition for the full data-foldpage-depth / data-foldpage-depth-interval control model.
Hover Styles
Your :hover rules apply to the 3D elements with no changes.
/* These hover styles are automatically picked up by Fold.page */
a:hover {
color: #ff6600;
text-decoration: underline;
}
.card:hover {
background-color: rgba(100, 100, 255, 0.4);
}
h2:hover {
font-size: 22px;
opacity: 0.9;
}Hover properties read for text elements:
| CSS Property | Effect on Hover |
|---|---|
color | Text color change |
font-size | Text size change |
font-weight | Bold toggle |
font-style | Italic toggle |
opacity | Transparency change |
text-decoration / text-decoration-line | Underline on/off |
text-decoration-color | Underline color change |
text-decoration-style | Underline style change |
text-decoration-thickness | Underline weight change |
background-color | Background color change (on .foldpage-bg elements) |
Backgrounds: a hover background-color change animates if the element declares a background-color transition; otherwise it changes instantly.
CSS Transforms
Fold.page applies CSS transform values to the 3D objects. data-foldpage-scale is applied on top of the CSS transform.
| CSS Property / Function | 3D Effect |
|---|---|
transform: translateX(n) | Offset on X axis |
transform: translateY(n) | Offset on Y axis |
transform: translateZ(n) | Offset on Z axis |
transform: translate(x, y) | XY offset |
transform: translate3d(x, y, z) | Full 3D offset |
transform: rotateX(deg) | Rotation around X |
transform: rotateY(deg) | Rotation around Y |
transform: rotateZ(deg) | Rotation around Z |
transform: rotate(deg) | Z rotation shorthand |
transform: rotate3d(x, y, z, deg) | Arbitrary-axis rotation |
transform: scale(n) | Uniform scale — negative values (mirroring) supported |
transform: scaleX(n) / scaleY(n) / scaleZ(n) | Per-axis scale — negative values (mirroring) supported |
transform: scale3d(x, y, z) | Per-axis 3D scale |
transform: matrix(...) / matrix3d(...) | Supported as long as the matrix doesn't itself encode shear or a projective (perspective) term |
transform-origin | Pivot point for rotations and scaling |
skew(), skewX(), skewY() | Not supported — read as an approximate rotation + scale, not a true shear |
perspective() | Not supported — no foreshortening |
CSS Transitions
Your CSS transition declarations animate the 3D objects the same way they would animate the flat page.
.card {
transition: transform 0.4s ease-out;
}
.card:hover {
transform: translateY(-10px) scale(1.05);
}Property Coverage
| Property | Support |
|---|---|
transform | Full — every function listed under CSS Transforms; rotations interpolate smoothly across multiple axes |
background-color, border-color, border-width, border-radius | Full — border-color and border-width only when all four sides match |
opacity, color, box-shadow, width, height | Not animated yet — they jump to the end value |
| Anything else | Not read |
Timing
The transition shorthand and comma-separated lists work as usual:
| CSS Property | Effect |
|---|---|
transition-property | Which properties animate — see Property Coverage |
transition-duration | Animation length. Cycles per spec if the value list is shorter than transition-property's. |
transition-delay | Delay before the animation starts. |
transition-timing-function | Easing curve — see below. |
Timing Functions
| Value | Behavior |
|---|---|
linear | Constant rate |
ease (default) | Slow start, fast middle, slow end |
ease-in | Slow start |
ease-out | Slow end |
ease-in-out | Slow start and end |
cubic-bezier(x1, y1, x2, y2) | Custom curve, matching browser behavior including overshoot (y1/y2 outside [0, 1]) |
steps(n, start | end) / step-start / step-end | Discrete jumps rather than a smooth curve |
Triggers
A transition runs whenever a covered property changes because of:
:hover— mirrored via.foldpage-hover:active— mirrored via.foldpage-active:focus— mirrored via.foldpage-focus- Any class change from your own JS (
classList.add/remove/toggle), including Fold's view focus classes
Interruption
Toggling a trigger mid-animation (for example hovering on and off quickly) reverses smoothly from the current point.
See the CSS Transitions demo for live examples of every timing function, trigger and transform type.
CSS Positioning
Fold.page respects CSS position to determine where in the scene hierarchy elements are placed:
CSS position | 3D Placement |
|---|---|
static / relative | In the scrolling content group. Moves with page scroll. |
fixed | In a non-scrolling fixed group. Stays anchored to the viewport origin. |
sticky | Dual instances: one in the scroll group (normal flow), one in the fixed group (stuck position). Toggled by scroll position via the top threshold. |
absolute | Placed relative to the nearest positioned ancestor in the 3D scene graph. |
CSS Overflow
Fold.page handles overflow: hidden, clip, scroll, and auto on container elements:
overflow value | 3D Effect |
|---|---|
visible (default) | Children render normally, no clipping. |
hidden / clip | Children are clipped to the container's bounds. |
scroll / auto | Container becomes a scrollable 3D region. Canvas wheel events drive scroll. Children are masked and the scroll position is spring-animated. Also syncs with the DOM element's scrollTop. |
overflow-y is read separately from overflow. Nested overflow containers are supported.
CSS Pseudo-Elements
::before and ::after pseudo-elements are rendered in 3D. Fold.page reads their computed content, background-color, border, border-radius, width, height, and positioning properties and generates background planes and/or text meshes for them.
.icon::before {
content: "★";
color: gold;
}
.card::after {
content: "";
background-color: rgba(255,255,255,0.1);
border-radius: 8px;
}Form Element Properties
For <input> and <textarea> elements, one additional property is read:
| CSS Property | 3D Effect | Notes |
|---|---|---|
caret-color | Cursor mesh color | Colors the blinking cursor indicator in 3D. Falls back to the element's color when not set. |
All standard text properties (color, font-size, font-family, etc.) are also read for form elements using the same pipeline as other text elements.
Color and Opacity
RGBA colors are split into a color and an opacity, so rgba(…, 0.5) renders at 50% opacity. Hex, named and rgb() colors are fully opaque.
Units
All CSS pixel values are converted to Three.js world units by multiplying by Fold.getPixelSize(). You only need this when adding your own Three.js objects.

