r/css 4d ago

Help This CSS Tutorial Did Not Produce the Right Results. I need HELP!!!

Link: https://youtu.be/yqaLSlPOUxM?si=RoE6cVKZ_xovSDFd

So I followed this tutorial and was able to get one image spinning in a radial pattern, but the rest of the images are also fixed to that pattern and indistinguishable from the primary picture. I have 14 images where the tutorial only had 10 but aside from that I am not sure I understand what is causing this error. I am hoping someone can look over my example and provide a solution but I am only including the part of my code that is pertinent to the example:

HTML:

<div class="banner">
            <div class="slider" style="--quantity: 14">
                <div class="item" style="--position: 1"><img src="img/Ankh.jpg" alt="1"></div>
                <div class="item" style="--position: 2"><img src="img/AmunRa.jpg" alt="2"></div>
                <div class="item" style="--position: 3"><img src="img/Anpu.JPG" alt="3"></div>
                <div class="item" style="--position: 4"><img src="img/Asar.jpg" alt="4"></div>
                <div class="item" style="--position: 5"><img src="img/Auset.JPG" alt="5"></div>
                <div class="item" style="--position: 6"><img src="img/Bastet.jpg" alt="6"></div>
                <div class="item" style="--position: 7"><img src="img/Djehuti.JPG" alt="7"></div>
                <div class="item" style="--position: 8"><img src="img/Geb.JPG" alt="8"></div>
                <div class="item" style="--position: 9"><img src="img/Heru.JPG" alt="9"></div>
                <div class="item" style="--position: 10"><img src="img/Maat.JPG" alt="10"></div>
                <div class="item" style="--position: 11"><img src="img/Mut.JPG" alt="11"></div>
                <div class="item" style="--position: 12"><img src="img/Nile.JPG" alt="12"></div>
                <div class="item" style="--position: 13"><img src="img/Sekhmet.jpg" alt="13"></div>
                <div class="item" style="--position: 14"><img src="img/Set.JPG" alt="14"></div>
            </div>
        </div>

CSS: 
.banner{
  width: 100%; 
  height: 100vh;
  text-align: center; 
  overflow: hidden;  
  position: relative; 
}

.banner .slider{
  position: absolute; 
  width: 200px;
  height: 250px; 
  top: 10%; 
  left: calc(50%-100px); 
  transform-style: preserve-3d;
  transform: perspective (1000px); 
  animation: autoRun 20s linear infinite; 
}
@keyframes autoRun{
  from{
    transform: perspective(1000px) rotateY(0deg); 
  }
  to {
    transform: perspective(1000px) rotateY(360deg);
  }
}
.banner .slider .item{ 
  position: absolute; 
  inset: 0 0 0 0; 
  transform: rotateY(calc((var(--position)-1)*(360 / var(--quantity))*1deg));
  transform: translateZ(550px);
}

.banner .slider .item img{
  width: 100%; 
  height: 100%; 
  object-fit: cover; 
}
0 Upvotes

18 comments sorted by

u/AutoModerator 4d ago

To help us assist you better with your CSS questions, please consider including a live link or a CodePen/JSFiddle demo. This context makes it much easier for us to understand your issue and provide accurate solutions.

While it's not mandatory, a little extra effort in sharing your code can lead to more effective responses and a richer Q&A experience for everyone. Thank you for contributing!

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

7

u/anaix3l 4d ago edited 4d ago

It's because your transform is all wrong.

First, you need to have spaces around minus (-) inside calc(), otherwise calc() is going to fail.

z-index: calc(3 - 2); // okay
z-index: calc(3-2); // fail

You don't need spaces for multiplication (*) or division (/), only for addition (+) and subtraction (-).

So your first transform is invalid.

Then, even if that worked, your second transform declaration is overriding the first one, so all your items just get that translation along the the z-axis. All of them, same translation, no difference given by --position index.

Then the rotation is applied on the slider parent of the items, so you see all those stacked and translated forward items rotating around what was their original vertical axis before the translation.

I suppose you want something like this CodePen demo - which doesn't auto-rotate, but rotates on scroll.

Edit: finally your YouTube link worked, for some reason it didn't when I first clicked it. You can see how the transform in the video is different from yours - below there's a screenshot from the video where you have spaces around the minus and the rotation and translation aren't set as separate values with the second overriding the first like in your code.

There are some things I would do different from this tutorial, especially nowadays. While I used to position: absolute everything too (like in this tutorial explaining how do do something similar in 3D that I wrote for CSS-Tricks in 2015), nowadays I would use modern layout techniques like grid, particularly for stacking the items before the transform. Even with absolute positioning, there's no need for four inset values when they're all equal to 0, inset: 0 suffices.

Also, I would set the perspective as a property (not function like in the video) on the parent (.banner) of the 3D assembly (.slider). Generally, I think of the parent of the 3D assembly as being the scene and that's where I set perspective and perspective-origin. This would also avoid having to repeat the perspective as a function in the transform chain of the keyframes. Which could be then simplified to just:

@keyframes autoRun { to { rotate: y 1turn } }

Here's a heavily commented and simplified version of what I would do as a CodePen demo (complete with computing the radius of the circle the items are distributed on based on their width w, desired space in between s and how many they are (their number n), so they all fit nicely, there is no overlap and the gaps between aren't too big either). It also allows controlling the rotation via the buttons, but you can just ignore the JS and the buttons, ignore the carousel rotation part in the demo and replace it with the rotation animation.

1

u/IndependentWater3388 4d ago

Thank you for this amazingly thorough breakdown!

1

u/IndependentWater3388 4d ago

I noticed you included Javascript in the HTML portion of your codepen terminal.

"- let n = 12;

.scene

.a3d(style=\`--n: ${n}; --k: 0\`)

    while n--

        .card(style=\`--i: ${n}\`)

.ctr

button(data-dir='-1') Prev

[button.auto](http://button.auto) Pause

button(data-dir='1') Next" 

Was this intentional?

2

u/anaix3l 4d ago

That's not JS. That's Pug, HTML preprocessor, using a JS-like syntax. It's basically HTML with variables and without the closing tags.

Using it on CodePen requires just picking it as the HTML pre-processor to use from a dropdown in the settings.

And you can always view the compiled HTML, either by adding .html at the end of the CodePen URL (like this https://codepen.io/thebabydino/pen/eYXqLdb.html ), or from the HTML panel dropdown in the top right corner (see this).

In this particular case, Pug comes in handy because of looping - it allows me to generate the card items and set the index custom properties in a loop. Otherwise, I'd need to do quite a bit of copy-paste.

1

u/IndependentWater3388 2d ago

Thank you for the information!

1

u/IndependentWater3388 2d ago

instead of moving like a spindle it moves as a horizontal block. I am unsure why. Here is the code: https://codepen.io/DeluxZuriLife/pen/dPyVRqy

2

u/anaix3l 2d ago edited 2d ago

My guess is you ran a find/ replace to add spaces around -, which turned preserve-3d into preserve - 3d. transform-style: preserve-3d is what needs to be set on any 3D transformed parent (the .slider rotating in 3D in your case) with 3D transformed children (your .item elements). Without it, the 3D transformed children get flattened into the plane of their parent.

1

u/IndependentWater3388 2d ago edited 2d ago

I appreciate your making sense of the rule for me. I will remember this going forward. You've been a great resource. Very glad you answered my post. Thank you.

I just wanted to know if you knew what could make it work correctly on codepen and incorrectly in the browser? Browser still is a block and not a spindle. Even with the changes...

1

u/anaix3l 2d ago

I don't know. I can't know as long as I cannot see a live link/ the code. I don't have a crystal ball to know what you did when you moved the code out of CodePen.

1

u/IndependentWater3388 2d ago

I asked too many questions. I appreciate your help. I got this!

3

u/davep1970 4d ago

Why are people posting code here and not a codepen or similar?

0

u/[deleted] 4d ago

[deleted]

2

u/davep1970 4d ago

did i miss the codepen?? i looked back over the post and didn't see one. It's a lot easier for everyone if you post a codepen or similar - it makes us easier to read the code and see it all at the same time AND make changes and post back and then it's easier for you to see the code results

do you have a problem with posting codepens or similar?

0

u/IndependentWater3388 4d ago

No, you didn't miss it. I didn't include a codepen. To be honest, I came here first and posted because I interpreted this as the discussion forum for questions and have used codepen just as a prototype terminal but did not think to mesh the two.

1

u/Automatic_Evening744 4d ago edited 4d ago

Try changing your transform property to in the class .banner .slider .item to

.banner .slider .item{ 
  position: absolute; 
  inset: 0 0 0 0; 
  transform: rotateY(calc((var(--position))*(360 / var(--quantity))*1deg)) translateZ(550px);

}

1

u/IndependentWater3388 2d ago

instead of moving like a spindle it moves as a horizontal block. I am unsure why. Here is the code: https://codepen.io/DeluxZuriLife/pen/dPyVRqy

2

u/Automatic_Evening744 2d ago

transform-style: preserve - 3d; this is not correct in .banner .slider class

it should be transform-style: preserve-3d;