按像素动态调整 CSS3 加载微调器的大小

Dyanmic resize a CSS3 loading spinner by pixels

有人要求我采用纯 CSS3 加载微调器并使其可按像素动态调整大小,以便在程序的不同位置使用。

我当前的代码是:(在 SO 的代码片段中显然 运行 不太好)

.loader {
  animation:spin 1s infinite linear;
  border:solid 2vmin transparent;
  border-radius:50%;
  border-right-color:#71c491;
  border-top-color:#f7941d;
  box-sizing:border-box;
  height:20vmin;
  left:calc(50% - 10vmin);
  position:fixed;
  top:calc(50% - 10vmin);
  width:20vmin;
  z-index:1;
  &:before {
    animation:spin 2s infinite linear;
    border:solid 2vmin transparent;
    border-radius:50%;
    border-right-color:#21409a;
    border-top-color:#92278f;
    box-sizing:border-box;
    content:"";
    height:16vmin;
    left:0;
    position:absolute;
    top:0;
    width:16vmin;
  }
  &:after {
    animation:spin 3s infinite linear;
    border:solid 2vmin transparent;
    border-radius:50%;
    border-right-color:#13b0e6;
    border-top-color:#18244c;
    box-sizing:border-box;
    content:"";
    height:12vmin;
    left:2vmin;
    position:absolute;
    top:2vmin;
    width:12vmin;
  }
}

@keyframes spin {
  100% {
    transform:rotate(360deg);
  }
}
<div class="loader"></div>

我用谷歌搜索并尝试了 transform:scale() 但据我所知,它只需要特定的输入和 increases/decreases 按百分比计算的大小。 (2 = 200% 大小)

我想我需要某种包装器,但我不太熟悉高级 CSS 来获得效果。当我尝试创建自己的时,只有微调器的顶部边框会被调整为奇怪的形状,而不是内部边框。我只是被难住了。如果您能指出正确的方向,我将不胜感激。谢谢。

您可以尝试混合使用 CSS var() / calc() / clamp() / grid ... 和 relative/absolute positionning 将加载器放置在您需要的父级上,如果启发你的:

在 div 大小的范围内使用一些加载程序进行演示,并可以设置一个平均大小作为起始大小,% 大小基于父级的宽度。

演示中要重置的值为 --size;您还可以根据需要调整其他 --MyVarCss 值。

* {
  box-sizing: border-box;
}

:root { /* init for the var() values */
  --size: 20;/* value used to set the loader's width and adjust border's width */
  --width: calc(var(--size) * 1%);
  --widthBorder: calc( clamp(20px, 6vw, 80px) * var(--size) * 0.005);
}

.a,/* for the demo , just a bunch of containers */
.b,
.c,
.d,
.d,
.e {
  position: relative;
  /* what the parent loader needs to be (absolute/fixed/sticky works too, static not) */
  float: left;
  border: solid;
  margin: 1em;
}

div.a {
  --size: 50; /* reset the value used to set the loader's width */
  width: 50%;
  padding-top: 50%;
}

.b {
  --size: 10;/* reset the value used to set the loader's width */
  width: 600px;
  height: 200px;
}

.c {
  --size: 15;/* reset the value used to set the loader's width */
  width: 25%;
  padding-top: 20%;
}

.d {
  --size: 30;/* reset the value used to set the loader's width */
  width: 800px;
  height: 400px;
}

.e {
  --size: 14;/* reset the value used to set the loader's width */
  width: 90%;
  min-height: 20vh;
}

div {
  width: 20%;
  padding-top: 20%;
}
/* loader styles */
.loader {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

.loader b {
  display: grid;
  animation: rotate 3s -1s infinite linear;
  border: solid var(--widthBorder) transparent;
  padding: calc(var(--widthBorder) / 2);
  border-radius: 50%;
  border-right-color: #71c491;
  border-top-color: #f7941d;
  grid-row: 1;
  grid-column: 1;
  margin: 0;
}

.loader>b {
  margin: auto;
  width: var(--width);
}

.loader>b:before {
  content: "";
  padding-top: 100%;
  grid-row: 1;
  grid-column: 1;
}

.loader b b {
  border-right-color: #21409a;
  border-top-color: #92278f;
}

.loader b b b {
  border-right-color: #13b0e6;
  border-top-color: #18244c;
  padding: 0;
}

@keyframes rotate {
  100% {
    transform: rotate(360deg);
  }
}
<div class=a>
  <div class="loader"><b><b><b></b></b>
    </b>
  </div>
</div>
<div class=b>
  <div class="loader"><b><b><b></b></b>
    </b>
  </div>
</div>
<div class=c>
  <div class="loader"><b><b><b></b></b>
    </b>
  </div>
</div>
<div class=d>
  <div class="loader"><b><b><b></b></b>
    </b>
  </div>
</div>
<div class=e>
  <div class="loader"><b><b><b></b></b>
    </b>
  </div>
</div>