25% off ProSNIPC25OFF

Fundraising Goal Progress Bar

Shortcode-driven animated progress bar showing a fundraising amount raised versus a goal.

Module3 parts · by SnipCraft

PHPLogic

php
<?php
if ( ! function_exists( 'scseed_progress_bar_shortcode' ) ) {
    function scseed_progress_bar_shortcode( $atts ) {
        $atts = shortcode_atts( array(
            'raised'    => 0,
            'goal'      => 1000,
            'currency'  => '
#x27;, 'label' => 'Raised toward our goal', ), $atts, 'fundraising_progress' ); $raised = max( 0, floatval( $atts['raised'] ) ); $goal = max( 1, floatval( $atts['goal'] ) ); $currency = esc_html( $atts['currency'] ); $label = esc_html( $atts['label'] ); $pct = min( 100, round( ( $raised / $goal ) * 100, 1 ) ); ob_start(); ?> <div class="scseed-progress-wrap"> <div class="scseed-progress-header"> <span class="scseed-progress-raised"><?php echo $currency . number_format( $raised ); ?></span> <span class="scseed-progress-label"><?php echo $label; ?></span> </div> <div class="scseed-progress-track" role="progressbar" aria-valuenow="<?php echo esc_attr( $pct ); ?>" aria-valuemin="0" aria-valuemax="100"> <div class="scseed-progress-fill" data-pct="<?php echo esc_attr( $pct ); ?>" style="width:0%"></div> </div> <div class="scseed-progress-footer"> <span class="scseed-progress-pct"><?php echo $pct; ?>% complete</span> <span class="scseed-progress-goal">Goal: <?php echo $currency . number_format( $goal ); ?></span> </div> </div> <?php return ob_get_clean(); } add_shortcode( 'fundraising_progress', 'scseed_progress_bar_shortcode' ); }

CSSStyles

css
.scseed-progress-wrap {
  max-width: 560px;
  margin: 1.5rem auto;
  font-family: inherit;
}
.scseed-progress-header {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  margin-bottom: .5rem;
}
.scseed-progress-raised {
  font-size: 1.9rem;
  font-weight: 800;
  color: #16a34a;
  line-height: 1;
}
.scseed-progress-label {
  font-size: .9rem;
  color: #6b7280;
}
.scseed-progress-track {
  background: #e5e7eb;
  border-radius: 999px;
  height: 18px;
  overflow: hidden;
}
.scseed-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #16a34a, #4ade80);
  border-radius: 999px;
  transition: width 1.2s cubic-bezier(.25,.8,.25,1);
}
.scseed-progress-footer {
  display: flex;
  justify-content: space-between;
  margin-top: .4rem;
  font-size: .82rem;
  color: #6b7280;
}
.scseed-progress-pct { font-weight: 600; color: #374151; }

JavaScriptScript

js
(function () {
  function animateBars() {
    document.querySelectorAll('.scseed-progress-fill').forEach(function (fill) {
      if (fill.dataset.animated) return;
      var rect = fill.closest('.scseed-progress-wrap').getBoundingClientRect();
      if (rect.top < window.innerHeight - 40) {
        fill.dataset.animated = '1';
        fill.style.width = fill.dataset.pct + '%';
      }
    });
  }
  window.addEventListener('scroll', animateBars, { passive: true });
  animateBars();
})();
#shortcode#animation#progress#fundraising#nonprofit