TheAndersMan TheAndersMan - 10 months ago 39
Javascript Question

Divs overlapping and going wrong speed

I am making a mini game on codepen, and you can upgrade reload and shoot, however when you shoot more than twice, the bullets go at different speeds and overlap each other.
You can see for yourself here:

Here is my HTML:

<div class="wrap">
<div class="body"></div>
<div class="barrel"></div>
<div class="bullets">

Here is my CSS:

.wrap {
position: absolute;
top: 30vh;
left: 40vw;
display: flex;
.wrap .body {
width: 200px;
height: 200px;
background: #00b2e1;
border-radius: 100%;
border: 6px solid black;
z-index: 1;
.wrap .barrel {
width: 150px;
height: 125px;
background: #666;
margin-top: calc(75px / 2);
margin-left: -50px;
z-index: 0;
border: 6px solid black;
.wrap .bullets {
margin-top: calc(75px / 2);
margin-left: -125px;
display: flex;
.wrap .bullets .bullet {
width: 125px;
height: 125px;
border-radius: 100%;
background: #F14E54;
border: 6px solid black;
animation: bulletMove 3s linear 1;

@keyframes bulletMove {
0% {
margin-left: -125px;
100% {
margin-left: 60vw;

And my JS:

var fireRate = 1,
fireInterval = null,
loadNum = 0;

function fire() {
let bullet = document.createElement("div");
setTimeout(function() {
}, 2000)

function startFire() {
fireInterval = setInterval(fire, 1000 / fireRate);

function stopFire() {

Sorry, it's a lot, I just want to give you the (almost) full picture, It would probably make more sense if you actually went to the pen and saw it yourself.

So if you can help me fix why the bullets change speeds and overlap that would be great.

Answer Source

My variant.

So here's what I think is going on.

You create div.bullet and attach it to the .bullets container. Then you use left-margin to animate them. The thing is, the margin will push the item and all later siblings because it affects inline flow, essentially creating a gap rather than truly moving anything. (display:flex makes them essentially inline rather than block-level.)

Imagine you have three elements that are siblings and are set as display:inline. Setting margin-left on the second one would cause both the second and third one to change position.

In my variant, I switched to absolute positioning and used left to position them. This brings them out of the normal flow of the document so that they no longer have an impact on their surrounding elements. (I also changed z-index a little.)

I notice it looked like you tried doing this, but it also looks like you didn't put position:absolute on the parent and so the positioning was messed up.