CSS content: attr() on HTML5 progress doesn't work

The CSS content: attr() function doesn't work directly with HTML5 <progress> elements due to browser rendering limitations. Here's how to work around this issue.

The Problem

When you try to use content: attr() with progress elements, it fails because progress bars use special internal pseudo-elements that don't support generated content in the same way as regular elements.

HTML Structure

<!DOCTYPE html>
<html>
<head>
    <style>
        .progress-container {
            position: relative;
            display: inline-block;
        }
        
        progress {
            width: 200px;
            height: 20px;
        }
        
        .progress-label {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            font-size: 12px;
            color: #333;
            pointer-events: none;
        }
    </style>
</head>
<body>
    <div class="progress-container">
        <progress max="100" value="60" data-value="60"></progress>
        <span class="progress-label">60%</span>
    </div>
</body>
</html>

JavaScript Solution

The most reliable approach is to use JavaScript to dynamically update the progress display:

<!DOCTYPE html>
<html>
<head>
    <style>
        .progress-wrapper {
            position: relative;
            display: inline-block;
            width: 200px;
        }
        
        progress {
            width: 100%;
            height: 25px;
        }
        
        .progress-text {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            font-size: 14px;
            font-weight: bold;
            color: #fff;
            text-shadow: 1px 1px 1px rgba(0,0,0,0.5);
            pointer-events: none;
        }
    </style>
</head>
<body>
    <div class="progress-wrapper">
        <progress id="myProgress" max="100" value="75"></progress>
        <span class="progress-text" id="progressText">75%</span>
    </div>
    
    <script>
        function updateProgress(value) {
            const progress = document.getElementById('myProgress');
            const text = document.getElementById('progressText');
            
            progress.value = value;
            text.textContent = value + '%';
        }
        
        // Example: Update progress dynamically
        let currentValue = 0;
        const interval = setInterval(() => {
            if (currentValue <= 100) {
                updateProgress(currentValue);
                currentValue += 10;
            } else {
                clearInterval(interval);
            }
        }, 500);
    </script>
</body>
</html>

Alternative CSS-Only Solution

For a pure CSS approach, create a custom progress bar using div elements:

<!DOCTYPE html>
<html>
<head>
    <style>
        .custom-progress {
            position: relative;
            width: 200px;
            height: 25px;
            background-color: #e0e0e0;
            border-radius: 12px;
            overflow: hidden;
        }
        
        .custom-progress::before {
            content: attr(data-value) '%';
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            z-index: 2;
            font-size: 14px;
            font-weight: bold;
            color: #333;
        }
        
        .progress-fill {
            height: 100%;
            background: linear-gradient(90deg, #4CAF50, #45a049);
            transition: width 0.3s ease;
        }
        
        .custom-progress[data-value="60"] .progress-fill {
            width: 60%;
        }
        
        .custom-progress[data-value="80"] .progress-fill {
            width: 80%;
        }
    </style>
</head>
<body>
    <div class="custom-progress" data-value="60">
        <div class="progress-fill"></div>
    </div>
    
    <br><br>
    
    <div class="custom-progress" data-value="80">
        <div class="progress-fill"></div>
    </div>
</body>
</html>

Comparison

Method Pros Cons
JavaScript + Progress Uses semantic HTML5, Dynamic updates Requires JavaScript
Custom CSS Progress Pure CSS, attr() works Less semantic, Manual width classes
Native Progress Only Simple, Semantic No text display support

Conclusion

HTML5 progress elements don't support content: attr() reliably. Use JavaScript for dynamic updates or create custom progress bars with divs for pure CSS solutions with text display.

Updated on: 2026-03-15T23:18:59+05:30

295 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements