sibling-index:我用这个画时钟表盘

如果你需要画一个时钟表盘,你会怎么做?用12个div元素,使用CSS的transform属性来旋转它们,来将他们放在正确的位置。但是,你会发现,你需要使用JavaScript来计算每个div元素的旋转角度, 当前你也可以提前计算好,但终究是要计算的。一但钟表半径变化,你就需要重新计算。

那如何我们现在添加一些限制条件呢

html 复制代码
<div class="panel">
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
</div>

使用上面的html片段,不使用nth-*之类的选择器,不使用+选择器。纯CSS应该如何实现一个表盘呢

先添加一些基础样式

css 复制代码
.panel {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  border: 3px solid #000;
  position: relative;
}
.digit {
  position: absolute;
  left: 90px;
  top: 90px;
  width: 20px;
  height: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 14px;
}

填充12个刻度

再没有JS的情况下,我们可以使用::after伪元素来实现向页面添加显示内容。那1-12这些数字应该实现如何呢。在html中有什么情况会自动为元素填充序号呢?没错,有序列表。那我们这里其实也类似,在CSS中有counter功能

css 复制代码
.panel {
  counter-reset: digit;
}
.digit {
  counter-increment: digit;

  &::after {
    content: counter(digit);
  }
}

这样每个div中都会显示一个数字。接下来,我们需要将这些数字旋转到正确的位置。我们可以使用transform属性来实现。问题是,我们如何知道每个数字的旋转角度呢?我们可以使用sibling-index函数来实现。这个函数可以返回一个元素在兄弟元素当中的索引。我们可以使用这个函数来计算每个数字的旋转角度。

css 复制代码
.digit {
  --angle: calc((sibling-index() - 3) * 30deg);
  transform: translate(calc(cos(var(--angle)) * 90px), calc(sin(var(--angle)) * 90px));
}

附上完整代码

html 复制代码
<style>
  .panel {
    width: 200px;
    height: 200px;
    border-radius: 50%;
    border: 3px solid #000;
    position: relative;

    counter-reset: digit;
  }

  .digit {
    position: absolute;
    left: 90px;
    top: 90px;
    width: 20px;
    height: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 14px;

    counter-increment: digit;

    --angle: calc((sibling-index() - 3) * 30deg);
    transform: translate(calc(cos(var(--angle)) * 90px), calc(sin(var(--angle)) * 90px));

    &::after {
      content: counter(digit);
    }
  }
</style>

<div class="panel">
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
  <div class="digit"></div>
</div>

效果如下

兼容性

目前只有chrome最新版本支持这个函数,其他浏览器还没有支持。谨慎使用

相关推荐
小码哥_常3 小时前
一套自己部署的 IM,客户端是同一份 Flutter
前端·后端
蜗牛攻城狮5 小时前
微前端四大方案选型对比与最佳实践:qiankun、micro-app、wujie、Module Federation
前端·微前端·qiankun·前端架构·micro-app·wujie
她说可以呀7 小时前
Vue插槽
前端·javascript·vue.js
qq_448011167 小时前
Vue + Jinja2两套模版与法冲突造成undefinedError
前端·javascript·vue.js
aixingpan7 小时前
aixingpan.cn API开发文档:前端查询夏令时和时区接口指南
前端·php
2601_958352908 小时前
23.5×19mm 换掉一整条音频链?|A-68 集成了什么:ADC / DAC / 24.576MHz 时钟 / AEC / 波束降噪,主控仅需 6 根线
前端·音视频·ai降噪·回声消除·语音模块
志尊宝8 小时前
AI原生前端开发(039):AI辅助的Nuxt 4全栈开发
前端·vue.js·ai-native
FRing039 小时前
JavaScript入门到精通三十二(深拷贝、浅拷贝、递归函数)
开发语言·前端·javascript
excel9 小时前
双 Token 与前端使用 Crypto 公私钥鉴权换 Token,哪种方案更好?
前端·后端
外收内放9 小时前
Python基础语法练习题(73)
java·前端·python