Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pure CSS Loading indicator fit to container size

I want to use the following loading indicator for containers while data is being loaded. The problem is, that the slider has a fixed width and height (300px & 300px), but I want it to fit dynamically into a container. When I try to add width: 140px; and height: 140px; to the main-container class the loading indicator looks awful and the proportions are not correct.

EDIT by Rickard
I added a slider and border so it's easier to see what's going wrong.

let sliderElement = document.getElementById("slider");
let mainContainerDiv = document.querySelector(".main-container");

sliderElement.oninput = function() {
  changeContainerSize(this.value);
}

function changeContainerSize(value) {
  mainContainerDiv.style.width = value + "px";
  mainContainerDiv.style.height = value + "px";
}

changeContainerSize(sliderElement.value);
.main-container {
  border: 1px solid; /* for demo purpose :: Rickard */
}
.reverse-spinner {
  position: relative;
  height: 100px;
  width: 100px;
  border: 4px solid transparent;
  border-top-color: #1976d2;
  border-left-color: #1976d2;
  border-radius: 50%;
  -webkit-animation: spin 1.5s linear infinite;
  animation: spin 1.5s linear infinite;
}
.reverse-spinner::before {
  position: absolute;
  top: 15px;
  left: 15px;
  right: 15px;
  bottom: 15px;
  content: "";
  border: 4px solid transparent;
  border-top-color: #03a9f4;
  border-left-color: #03a9f4;
  border-radius: 50%;
  -webkit-animation: spinBack 1s linear infinite;
  animation: spinBack 1s linear infinite;
}

.flexbox {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
}

.flexbox > div {
  width: 140px;
  height: 140px;
  -webkit-box-flex: 0;
  -ms-flex: 0 0 25%;
  flex: 0 0 25%;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border: 2px dashed green; /* for demo purpose :: Rickard */
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  margin: 0;
  position: relative;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  overflow: hidden;
}

-webkit-@keyframes spin {
  -webkit-from {
    -webkit-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  -webkit-to {
    -webkit-transform: rotate(360deg);
    -ms-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}

@-webkit-keyframes spin {
  from {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  to {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}

@keyframes spin {
  from {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  to {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}

@-webkit-keyframes spinBack {
  from {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  to {
    -webkit-transform: rotate(-720deg);
    transform: rotate(-720deg);
  }
}

@keyframes spinBack {
  from {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  to {
    -webkit-transform: rotate(-720deg);
    transform: rotate(-720deg);
  }
}
<input id="slider" type="range" min="100" max="500" value="500">

<div class="main-container">
  <div class="flexbox">
    <div>
      <div class="reverse-spinner"></div>
    </div>
  </div>
</div>
like image 647
WhiteIntel Avatar asked Dec 31 '22 08:12

WhiteIntel


1 Answers

You can change the code of the spinner like below to rely on percentage values and on the padding trick to maintain the ratio then you can easily adjust the dimension by changing only the width:

.reverse-spinner {
  width: 100px;
  border: 4px solid transparent;
  border-top-color: #1976d2;
  border-left-color: #1976d2;
  border-radius: 50%;
  animation: spin 1.5s linear infinite;
}

.reverse-spinner::before {
  content: "";
  display:block;
  padding-top:calc(70% - 8px);
  margin:15%;
  border: inherit;
  border-top-color: #03a9f4;
  border-left-color: #03a9f4;
  border-radius: inherit;
  animation: spin 0.5s linear infinite reverse;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
<div class="reverse-spinner"></div>


<div class="reverse-spinner" style="width:80px;"></div>

<div class="reverse-spinner" style="width:40px;"></div>

<div class="reverse-spinner" style="width:40%;"></div>

Another version with less of code and without the use of calc()

.reverse-spinner {
  width: 100px;
  background:
    radial-gradient(farthest-side at bottom,transparent 95%,#1976d2 96%) 
    top/100% 50% no-repeat;
  border-radius: 50%;
  overflow:hidden;
  animation: spin 1.5s linear infinite;
}

.reverse-spinner::before {
  content: "";
  display:block;
  padding-top:70%;
  margin:15%;
  background:
      radial-gradient(farthest-side at bottom,transparent 93%,#03a9f4 94%) 
      top/100% 50% no-repeat;
  border-radius: inherit;
  animation: spin 0.5s linear infinite reverse;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
<div class="reverse-spinner"></div>


<div class="reverse-spinner" style="width:80px;"></div>

<div class="reverse-spinner" style="width:40px;"></div>

<div class="reverse-spinner" style="width:40%;"></div>

Another one still with less of code:

.reverse-spinner {
  width: 100px;
  background: top/100% 50% no-repeat;
  background-image:
    radial-gradient(farthest-side at bottom,transparent 95%,#1976d2 96% 99%,transparent 100%);
  animation: spin 1.5s linear infinite;
}

.reverse-spinner::before {
  content: "";
  display:block;
  padding-top:100%;
  background:inherit;
  background-image:
    radial-gradient(farthest-side at bottom,transparent 73%,#03a9f4 74% 79%,transparent 80%);
  animation: spin 0.5s linear infinite reverse;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
<div class="reverse-spinner"></div>


<div class="reverse-spinner" style="width:80px;"></div>

<div class="reverse-spinner" style="width:50px;"></div>

<div class="reverse-spinner" style="width:40%;"></div>
like image 79
Temani Afif Avatar answered Jan 05 '23 16:01

Temani Afif