3
\$\begingroup\$

I am fairly new to HTML and CSS and have been trying to make things with whatever knowledge I have. I created a 'loader', but I'm certain that I have done things in ways more complicated than they need to be. Is there an easier solution to centering my elements? Is there an easier solution to add a bounce class to all three elements? How can I simplify my code?

body{
  background: #0BCCCA;
}
.cont {
  position: absolute;
  width: 100px;
  height: 100px;
  top: 50%;
  left: 50%;
  margin: -50px 0 0 -50px;
}

.element, .elem-1, .elem-2, .bounce, .bounce-2, .bounce-3 {
  position: absolute;
  width: 20px;
  height: 20px;
  top: 50%;
  left: 50%;
  opacity: .6;
  background-color: #ffffff;
  border-radius: 50%;
  animation: big 2s infinite ease-in-out;
}
.elem-1, .bounce-2 {
  position: absolute;
  width: 20px;
  height: 20px;
  top: 6%;
  left: 80%;
  background-color: #fff;
}
.elem-2, .bounce-3 {
  position: absolute;
  width: 20px;
  height: 20px;
  top: 6%;
  left: 20%;
  background-color: #fff;
}
.elem-1{
  animation-delay: -0.5s;
}
.elem-2{
  animation-delay: -.75s;
}
.bounce{
  animation-delay: -1s;
}
.bounce-2{
  animation-delay: -1.5s;
}
.bounce-3{
  animation-delay: -1.75s;
}

@keyframes big {
  0%, 100%{transform: scale(0.0)}
  50% {transform: scale(1.75)}
}
<!DOCTYPE html>

<body>
  <div class="cont">
    <span class="element"></span>
    <span class="element elem-1"></span>
    <span class="element elem-2"></span>
    <span class="bounce"></span>
    <span class="bounce-2"></span>
    <span class="bounce-3"></span>
  </div>
</body>
</html>

I've looked at different works and read articles, but because I haven't practiced much, I find it difficult implementing what I learn into my code. This is one of my first completed code, which almost all of I have done myself, without looking at other people's work or reading articles for help. I want you to evaluate the code and suggest areas of improvement, specifically where the code might be overcomplicated.

\$\endgroup\$
1
\$\begingroup\$

There can be three ways to enhance this code, it mostly depends what you aim to create.

  1. Very flexible HTML and CSS,
  2. Flexible CSS, less flexible HTML,
  3. Minimal HTML, CSS and class names (as a result minimum flexibility).

Minor change summary

  • CSS cleanup,
  • CSS animation - to make it more readable,
  • Class names - to make the logic evident,
  • HTML- to make it modular and reusable,

CSS cleanup

.element, .elem-1, .elem-2, .bounce, .bounce-2, .bounce-3 {
    position: absolute;
    width: 20px;
    height: 20px;
    top: 50%;
    left: 50%;
    opacity: .6;
    background-color: #ffffff;
    border-radius: 50%;
    animation: big 2s infinite ease-in-out;
}
.elem-1, .bounce-2 {
    position: absolute; /*Already has position attribute*/
    width: 20px; /*Already has width attribute*/
    height: 20px; /*Already has height attribute*/
    top: 6%;
    left: 80%;
    background-color: #fff; /*Already has background-color attribute*/
}
.elem-2, .bounce-3 {
    position: absolute; /*Already has position attribute*/
    width: 20px; /*Already has width attribute*/
    height: 20px; /*Already has height attribute*/
    top: 6%;
    left: 20%;
    background-color: #fff; /*Already has background-color attribute*/
}
.elem-1{
    animation-delay: -0.5s;
}
.elem-2{
    animation-delay: -.75s;
}
.bounce{
    animation-delay: -1s;
}
.bounce-2{
    animation-delay: -1.5s;
}
.bounce-3{
    animation-delay: -1.75s;
}

@keyframes big {
    0%, 100%{transform: scale(0.0)}
    50% {transform: scale(1.75)}
}

CSS animation

Instead of

@keyframes big {
    0%, 100%{transform: scale(0.0)}
    50% {transform: scale(1.75)}
}

can be used

@keyframes big {
    0% { transform: scale(0);}
    100% {transform: scale(1);}
}

There is animation-direction which can have alternate value, this reverses the animation and gets the back effect this means there is no need for 50% key-frame, as one way animation can be altered beck.

Also when you use transform: scale() with greater than 1 value can cause element blurring in some browsers. to avoid this issue I multiplicated 20px height and width of the element with 1.75 and put 35px instead in order to use scale(1) instead of scale(1.75).

Classnames - to make the logic evident

As element, elem-1, elem-2, bounce, bounce-1, bounce-2 class names can be misleading. The meaning of these 6 classes is the animation states of each circle. in this case they can be bounceIn and bounceOut states and these states can be given to any element (in this case to any circle). Also each circle has its own position and that's why I have created pos-0,pos-1,pos-2 classes.

Centering

For centering elements there are many methods, the one that you used is a classic way and can be fully legitimate for this case (it will work even on IE6).

.cont {
    position: absolute;
    width: 100px;
    height: 100px;
    top: 50%;
    left: 50%;
    margin: -50px 0 0 -50px;
}

HTML

Instead of

<span class="element"></span>
<span class="element elem-1"></span>
<span class="element elem-2"></span>
<span class="bounce"></span>
<span class="bounce-2"></span>
<span class="bounce-3"></span>

Can be used

<div class="circle pos-0 delay-0">
    <span class="bounceIn"></span>
    <span class="bounceOut"></span>
</div>
<div class="circle pos-1 delay-1">
    <span class="bounceIn"></span>
    <span class="bounceOut"></span>
</div>
<div class="circle pos-2 delay-2">
    <span class="bounceIn"></span>
    <span class="bounceOut"></span>
</div>

Or

<div class="circle pos-0 delay-0"></div>
<div class="circle pos-1 delay-1"></div>
<div class="circle pos-2 delay-2"></div>

Or

<div class="circle-0"></div>
<div class="circle-1"></div>
<div class="circle-2"></div>

Which are much more readable and maintainable.


Solution 1: Very flexible HTML and CSS

You can add separate bouncing circles with different positions and different delays, or reuse same classes. or you can add 3-rd effect too (e.g. bounceIn, bounceOut, bounceLeft... etc.)

body {background: #0BCCCA;}

.cont {
    position: absolute;
    width: 100px;
    height: 100px;
    top: 50%;
    left: 50%;
    margin: -50px 0 0 -50px;
}

.circle {position: absolute;}

.pos-0 {
    top: 50%;
    left: 50%;
}
.pos-1 {
    top: 6%;
    left: 80%;
}
.pos-2 {
    top: 6%;
    left: 20%;
}

.bounceIn, .bounceOut {
    position: absolute;
    width: 35px;
    height: 35px;
    background-color: rgba(255, 255, 255, .6);
    border-radius: 50%;
    transform-origin: center center;
    animation: ease-in-out 1s infinite big alternate;
}

.bounceIn {animation-delay: 1000ms;}

.delay-0 .bounceIn {animation-delay: .75s;}
.delay-0 .bounceOut {animation-delay: -1.75s;}

.delay-1 .bounceIn {animation-delay: -0.5s;}
.delay-1 .bounceOut {animation-delay: -1.5s;}

.delay-2 .bounceIn {animation-delay: 0s;}
.delay-2 .bounceOut {animation-delay: -1s;}

@keyframes big {
    0% {transform: scale(0);}
    100% {transform: scale(1);}
}
<div class="cont">
    <div class="circle pos-0 delay-0">
        <span class="bounceIn"></span>
        <span class="bounceOut"></span>
    </div>
    <div class="circle pos-1 delay-1">
        <span class="bounceIn"></span>
        <span class="bounceOut"></span>
    </div>
    <div class="circle pos-2 delay-2">
        <span class="bounceIn"></span>
        <span class="bounceOut"></span>
    </div>
</div>


Solution 2: Flexible CSS, less flexible HTML

This solution uses only :before and :after instead of bounceIn and bounceOut classes to minimize HTML.

body {background: #0BCCCA;}

.cont {
    position: absolute;
    width: 100px;
    height: 100px;
    top: 50%;
    left: 50%;
    margin: -50px 0 0 -50px;
}

.circle {position: absolute;}

.pos-0 {
    top: 50%;
    left: 50%;
}
.pos-1 {
    top: 6%;
    left: 80%;
}
.pos-2 {
    top: 6%;
    left: 20%;
}

.circle:after, .circle:before {
    content: '';
    position: absolute;
    width: 35px;
    height: 35px;
    background-color: rgba(255, 255, 255, .6);
    border-radius: 50%;
    transform-origin: center center;
    animation: ease-in-out 1s infinite big alternate;
}

.circle:after {animation-delay: 1000ms;}

.delay-0.circle:after {animation-delay: .75s;}
.delay-0.circle:before {animation-delay: -1.75s;}

.delay-1.circle:after {animation-delay: -0.5s;}
.delay-1.circle:before {animation-delay: -1.5s;}

.delay-2.circle:after {animation-delay: 0s;}
.delay-2.circle:before {animation-delay: -1s;}

@keyframes big {
    0% {transform: scale(0);}
    100% {transform: scale(1);}
}
<div class="cont">
    <div class="circle pos-0 delay-0"></div>
    <div class="circle pos-1 delay-1"></div>
    <div class="circle pos-2 delay-2"></div>
</div>


Solution 3: Minimal HTML, CSS and class names

In addition to Solution 2 this one adds all necessary styles to one class.

body {
  background: #0BCCCA;
}

.cont {
  position: absolute;
  width: 100px;
  height: 100px;
  top: 50%;
  left: 50%;
  margin: -50px 0 0 -50px;
}

.circle-0,
.circle-1,
.circle-2{
  position: absolute;
}

.circle-0{
  top: 50%;
  left: 50%;
}

.circle-1{
  top: 6%;
  left: 80%;
}

.circle-2{
  top: 6%;
  left: 20%;
}

.circle-0:after,
.circle-0:before,
.circle-1:after,
.circle-1:before,
.circle-2:after,
.circle-2:before{
  content:'';
  position: absolute;
  width: 35px;
  height: 35px;
  background-color: rgba(255,255,255, .6);
  border-radius: 50%;
  transform-origin: center center;
  animation: ease-in-out 1s infinite big alternate;
}

.circle-0:after,
.circle-1:after,
.circle-2:after{animation-delay: 1000ms;}

.circle-0:after{animation-delay: .75s;}
.circle-0:before{ animation-delay: -1.75s;}

.circle-1:after{animation-delay: -0.5s;}
.circle-1:before{animation-delay: -1.5s;}

.circle-2:after{animation-delay: 0s;}
.circle-2:before{animation-delay: -1s;}

@keyframes big {
  0% { transform: scale(0); }
  100% { transform: scale(1);}
}
<div class="cont">
    <div class="circle-0"></div>
    <div class="circle-1"></div>
    <div class="circle-2"></div>
</div>

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.