咨询:制作通配符映射字体及非password类型表单输入隐私方案
Nice question! Let's cover both the font-based approach you're asking about, plus some font-free alternatives that might be even better given your constraints—since modifying input content is off-limits and type="password" isn't an option.
If you're set on using a font to mask characters, these tools let you build what you need quickly:
- Online font editors with bulk replacement: Look for web-based font creation tools that support batch glyph mapping. The workflow is straightforward: start a new font project, design a single wildcard glyph (like
*), then select all non-space characters in the character set and map them to this one shape. Most tools let you export the final font as TTF or OTF for embedding in your project—no need to tweak each character individually. - Free desktop tool (FontForge): If you don't mind a desktop app, FontForge is a solid open-source option. It has built-in bulk glyph replacement features that let you quickly map every non-space character to your wildcard shape. It's more powerful than many online tools and perfect for a one-off font like this.
These frontend tricks let you mask the input display without altering the actual input value—so your component listeners won't be triggered by content changes:
Container + Fake Display Element
This is the most reliable cross-browser solution. Wrap your input in a container, then use a sibling element to show the masked version while keeping the real input fully functional:
<div class="masked-input-wrapper"> <input type="text" id="real-input" /> <span class="masked-display"></span> </div>
.masked-input-wrapper { position: relative; display: inline-block; /* Match your input's default styling here */ } #real-input { position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; z-index: 2; cursor: text; /* Ensure the input stays focusable and interactive */ } .masked-display { display: inline-block; padding: 0.5rem; border: 1px solid #ccc; min-width: 200px; border-radius: 4px; /* Mirror your input's styles to keep the UI consistent */ } .masked-display.focused { border-color: #007bff; box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25); /* Add focus styling to match your input's state */ }
const realInput = document.getElementById('real-input'); const maskedDisplay = document.querySelector('.masked-display'); // Update masked display whenever input changes realInput.addEventListener('input', () => { const maskedText = realInput.value.replace(/\S/g, '*'); maskedDisplay.textContent = maskedText; }); // Sync focus states for better UX realInput.addEventListener('focus', () => maskedDisplay.classList.add('focused')); realInput.addEventListener('blur', () => maskedDisplay.classList.remove('focused'));
The actual input value stays untouched (so your component listeners won't throw fits), but users only see * for non-space characters.
-webkit-text-security (Limited Compatibility)
If you only need to support WebKit-based browsers (Chrome, Safari), you can use this CSS property to mask text:
input { -webkit-text-security: disc; /* Shows dots instead of * */ /* Use 'circle' or 'square' if those work for your needs */ }
Note: Firefox and other non-WebKit browsers don't support this, so it's not ideal for broad compatibility.
If you absolutely need a font, go with an online bulk glyph editor for speed. But the container-based fake display method is more flexible, doesn't require loading extra font files, works across all modern browsers, and avoids potential font rendering inconsistencies—making it the better choice for most cases.
内容的提问来源于stack exchange,提问作者lordyoum

