Matrix

Palette

HTML Matrix

Transformation Matrixes are broadly supported in HTML.

We can use Matrix to transform any element using it's style property.

We can use Matrix to write CSS Compatible transforms.

There are numerous things we can do with SVG transforms.

For example, we can use a scale transform to give object apparent depth.

If we want an object to appear twice as far away, we can scale it down by 0.5.

If we want an object to appear four times as far away, we can scale it by 0.25.

The general formula for apparent distance scaling is:

1/[Math]::Pow(2, `$scale - 1)

We can make any object look like it is Z away by applying a scale of that formula.

This page show some experiments with the technique.

To get things to overlap property, we need to put things into the same frame of reference.

We can do this with a little bit of css

/* Make an overlapping grid */
.overlap {
    place-items: center; display: grid; grid-template-rows: 1fr; grid-template-columns: 1fr;        
}
/* Make every item in the grid be in row 1, column 1 */
.overlap * { 
    grid-row: 1;grid-column: 1;
}

The inner element's box helps determine how much space the grid will occupy.

Use an inline element, like <span>, if we want the grid to occupy only one line of space.

1 2 3 4 5 6 7 8

If we want the overlapping grid to block off more space, Use a block element, like <h1>

1

2

3

4

5

6

7

8

Looking Around

We can change where the scaling is centered by changing transform-origin.

This means we can perform the same animated look around we can in svg.

@keyframes look-around {
    0%, 100% {
        transform-origin: 50% 50%;
    }
    20% {
        transform-origin: 0% 0%;
    }
    40% {
        transform-origin: 100% 0%;
    }
    60% {
        transform-origin: 0% 100%;
    }
    80% {
        transform-origin: 100% 100%;
    }    
}
.look-around {
    animation-name: look-around;
    animation-duration: 8.4s;
    animation-iteration-count: infinite;
}

1

2

3

4

5

6

7

8

z trick

Since there is a uniform method of scaling, we can simplify it in a CSS class or two.

If only there was some way for elements to let us know where they are in z space 🤔.

z-index will work, but it has some cannonical drawbacks:

  1. z-index is an integer, not a number
  2. A larger z-index is more visible, not less.

I believe a better approach is using a CSS property to repesent z


@property --z {
    syntax: '<number>';
    inherits: true;
    initial-value: 1;
}

With this property in hand, we can easily calculate a dynamic scale content.

calc(
    1 / pow( 2,
        calc(
            var(--z) - 1
        )
    )
)

Now we just need a class we can apply.

Let us call it z

.z {
    transform: scale(calc(
    1 / pow( 2,
        calc(
            var(--z) - 1
        )
    )
));
    opacity: calc(
    1 / pow( 2,
        calc(
            var(--z) - 1
        )
    )
)
}

Putting it all together:


@property --z {
    syntax: '<number>';
    inherits: true;
    initial-value: 1;
}

.z {
    transform: scale(calc(
    1 / pow( 2,
        calc(
            var(--z) - 1
        )
    )
));
    opacity: calc(
    1 / pow( 2,
        calc(
            var(--z) - 1
        )
    )
)
}

Let's see z trick in action:

1

2

3

4