Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                form.stopwatch
  input#start(type="checkbox")
  input#pause(type="checkbox")
  label.stopwatch__pause(for="pause")
    span Pause
  label.stopwatch__start(for="start")
    span Start
  button#reset.stopwatch__reset(type="reset")
    span Reset
  .stopwatch__restart.stopwatch__control
    .reset-button
  .stopwatch__stop-start.stopwatch__control
    .start-button
  .stopwatch__shadows
  .stopwatch__content
    img.stopwatch__branding(src="https://assets.codepen.io/605876/avatar.png")
    .stopwatch__face
      .digit.m.m--tens 0
      .digit.m.m--singles 0
      span :
      .digit.second.s.s--tens 0
      .digit.second.s.s--singles 0
      span .
      .digit.digit--small.ms.ms--tens 0
      .digit.digit--small.ms.ms--singles 0
              
            
!

CSS

              
                @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500&display=swap')

*
*:after
*:before
  box-sizing border-box
  user-select none

// By default the play state is paused
:root
  --state paused
  --bg hsl(280, 50%, 90%)
  --digit hsl(90, 50%, 90%)
  --face hsl(90, 50%, 5%)
  --content hsl(0, 0%, 40%)
  --shadow hsla(0, 0%, 0%, 0.25)
  --glare hsla(0, 0%, 100%, 0.2)
  --watch-bg hsl(210, 80%, 50%)
  --watch-bg--light hsl(210, 80%, 90%)
  --watch-bg--dark hsl(210, 80%, 20%)
  --stroke hsl(0, 0%, 15%)
  --start hsl(10, 80%, 40%)
  --start-two hsl(10, 80%, 60%)
  --restart hsl(0, 0%, 70%)
  --restart-two hsl(0, 0%, 90%)

// Trick to stop/start the stopwatch
// If neither are checked the animation-name is "none"
// And that resets the counters to their initial value
#start:checked ~ .stopwatch__content
#pause:checked ~ .stopwatch__content
  .ms--tens
    --name ms-tens
  .ms--singles
    --name ms-singles
  .s--tens
    --name s-tens
  .s--singles
    --name s-singles
  .m--tens
    --name m-tens
  .m--singles
    --name m-singles

// What handles the playback. When "Start" is checked,
// the play state is running. Then we can use "Pause" to
// toggle the play start of the animations.
#start:checked ~ .stopwatch__content
  --state running
#pause:checked ~ .stopwatch__content
  --state paused
// Trick to hide the start button
#start:checked ~ .stopwatch__start
  z-index -1

.stopwatch__start:active ~ .stopwatch__stop-start
.stopwatch__pause:active ~ .stopwatch__stop-start
  --y 25
.stopwatch__reset:active ~ .stopwatch__restart
  --y 15

// The properties for animating each digit
// We should be able to declare these all as a chain
// But the syntax listed at: https://web.dev/at-property/#multiple-declarations
// doesn't work for me.
@property --ms-tens
  initial-value 0
  inherits false
  syntax '<integer>'

@property --ms-singles
  initial-value 0
  inherits false
  syntax '<integer>'

@property --s-tens
  initial-value 0
  inherits false
  syntax '<integer>'

@property --s-singles
  initial-value 0
  inherits false
  syntax '<integer>'

@property --m-tens
  initial-value 0
  inherits false
  syntax '<integer>'

@property --m-singles
  initial-value 0
  inherits false
  syntax '<integer>'

body
  min-height 100vh
  display grid
  font-family 'Orbitron', sans-serif
  background var(--bg)
  place-items center

form
  margin 0

button
  appearance none
  border 0
  outline transparent
  background none

label span
button span
[type="checkbox"]
  position absolute
  width 1px
  height 1px
  padding 0
  margin -1px
  overflow hidden
  clip rect(0, 0, 0, 0)
  white-space nowrap
  border-width 0

label
button
  cursor pointer

.reset-button
  width 100%
  height 50%
  position absolute
  top 10%
  left 50%
  transform translate(-50%, 0)
  border 0.5vmin solid var(--stroke)
  border-radius 1vmin
  background var(--restart)
  overflow hidden

  &:after
    height 100%
    width 100%
    position absolute
    top 0
    left 0
    background repeating-linear-gradient(90deg, transparent 0 18%, var(--stroke) 18% 22%) 50% 0 / 100% 30% no-repeat,
               repeating-linear-gradient(90deg, transparent 0 18%, var(--stroke) 18% 22%) 50% 100% / 100% 30% no-repeat
    content ''

  &:before
    content ''
    height 100%
    width 100%
    border-radius 1vmin
    background var(--restart-two)
    position absolute
    bottom 100%
    left 0
    transform translate(-20%, 45%)

.start-button
  width 100%
  height 60%
  position absolute
  bottom 0
  border 0.5vmin solid var(--stroke)
  border-radius 1vmin
  background var(--start)
  overflow hidden

  &:after
    content ''
    height 100%
    width 100%
    border-radius 1vmin
    background var(--start-two)
    position absolute
    bottom 100%
    left 0
    transform translate(-20%, 35%)

.stopwatch
  height 45vmin
  width 45vmin
  background-color var(--watch-bg)
  border-radius 50%
  border 0.5vmin solid var(--stroke)
  position relative

  &__pause
  &__start
  &__reset
  &__control
    --size min(48px, 10vmin)
    height var(--size)
    width var(--size)
    position absolute
    top 50%
    left 50%
    transition transform 0.05s
    transform translate(-50%, -50%) rotate(var(--rotation, 0deg)) translate(0, -25vmin) translateY(calc(var(--y, 0) * 1%))
    z-index 10

  &__control
    z-index -1

  &__restart:before
    content ''
    position absolute
    bottom 0
    left 50%
    transform translate(-50%, 0)
    width 60%
    height 75%
    border 0.5vmin solid var(--stroke)
    background linear-gradient(90deg, var(--restart-two) 0 80%, transparent 81%) 50% 50% / 100% 100% no-repeat
    background-color var(--restart)
    z-index -1

  &__start
  &__pause
  &__stop-start
    --rotation 40deg

  &__shadows
    height 100%
    width 100%
    border-radius 100%
    position absolute
    top 50%
    left 50%
    transform translate(-50%, -50%)
    overflow hidden

    &:after
      content ''
      position absolute
      height 100%
      width 106%
      top 50%
      left 50%
      border-radius 50%
      transform translate(-50%, -50%) translate(0, 2%)
      box-shadow 0 0 0 5vmin var(--watch-bg--light)

    &:before
      content ''
      position absolute
      height 100%
      width 100%
      top 50%
      left 50%
      border-radius 50%
      transform translate(-50%, -50%) translate(0, -2%)
      box-shadow 0 0 0 5vmin var(--watch-bg--dark)

  &__content
    height 40vmin
    border 0.5vmin solid var(--stroke)
    width 40vmin
    background-color var(--content)
    border-radius 50%
    position absolute
    top 50%
    left 50%
    transform translate(-50%, -50%)
    overflow hidden

    &:before
      box-shadow 0 0 0 5vmin var(--shadow)
      border-radius 50%
      content ''
      position absolute
      top 50%
      left 50%
      height 100%
      width 100%
      transform translate(-50%, -50%) translate(0, 2%)

    &:after
      content ''
      position absolute
      top 50%
      left 50%
      height 100%
      width 100%
      transform translate(-50%, -50%) rotate(-50deg)
      background linear-gradient(transparent 0 15%, var(--glare) 16% 35%, transparent 36% 40%, var(--glare) 41% 45%, transparent 46%)

  &__branding
    height 7vmin
    position absolute
    left 50%
    top 75%
    transform translate(-50%, 0)
    opacity 0.5
    filter saturate(0)

  &__face
    color var(--digit)
    display flex
    font-size 6vmin
    position absolute
    top 50%
    left 50%
    transform translate(-50%, -50%)
    padding 1.75vmin
    border-radius 1vmin
    background var(--face)

.digit
  position relative
  color transparent
  counter-reset var(--counter-name) var(--counter-variable)
  animation var(--name, none) var(--duration, 1s) infinite steps(var(--steps)) var(--state)

  &:after
    content counter(var(--counter-name))
    font-variant tabular-nums
    color var(--digit)
    position absolute
    bottom 0
    right 0

.ms
  font-size 4vmin
  transform translate(0, -6%)

  &--tens
    --duration 1s
    --steps 10
    --counter-name ms-tens
    --counter-variable var(--ms-tens)

  &--singles
    --duration 0.1s
    --steps 10
    --counter-name ms-singles
    --counter-variable var(--ms-singles)

.s
  &--tens
    --duration 60s
    --steps 6
    --counter-name s-tens
    --counter-variable var(--s-tens)

  &--singles
    --duration 10s
    --steps 10
    --counter-name s-singles
    --counter-variable var(--s-singles)

.m
  &--tens
    --duration 3600s
    --steps 6
    --counter-name m-tens
    --counter-variable var(--m-tens)

  &--singles
    --duration 600s
    --steps 10
    --counter-name m-singles
    --counter-variable var(--m-singles)

// The different animations requires for each digit
@keyframes ms-tens
  to
    --ms-tens 10

@keyframes ms-singles
  to
    --ms-singles 10

@keyframes s-tens
  to
    --s-tens 6

@keyframes s-singles
  to
    --s-singles 10

@keyframes m-tens
  to
    --m-tens 6

@keyframes m-singles
  to
    --m-singles 10
              
            
!

JS

              
                // 404
              
            
!
999px

Console