【问题标题】:Get input type=text to look like type=password让输入 type=text 看起来像 type=password
【发布时间】:2013-07-20 02:48:16
【问题描述】:

tl;博士

我有一个带有 type=text 的输入,我想像带有 type=password 的输入一样仅使用 CSS 来显示星星。


基本上我有一个带有以下输入的表单:

<input type='text' value='hello' id='cake' />

我没有生成表单,我根本无法访问它的 HTML。但是,我确实可以访问应用于页面的 CSS。

我希望它的行为类似于 type=password ,也就是说 - 为用户输入的内容而不是实际输入的文本显示星标。基本上,我希望这方面(用户输入的呈现)看起来像 type=password 字段。

由于这似乎只是一个演示问题,我认为必须有一种方法可以使用 CSS 来做到这一点,因为它在其职责范围内。但是 - 我还没有找到这样的方法。我必须支持 IE8+,但我宁愿有一个仅适用于现代浏览器的解决方案,而不是根本没有解决方案。防止复制/粘贴功能的额外积分,但我可以没有它。

注意:如果不清楚,我不能在页面中添加 HTML 或 JavaScript - 只有 CSS。


(我发现的唯一东西是this question,但它正在处理与 jQuery 相关的问题并且它有一个 JavaScript 解决方案)

【问题讨论】:

标签: html css


【解决方案1】:

在基于 WebKit 的浏览器中,您可以使用 -webkit-text-security 属性来执行此操作。它甚至允许您选择子弹的形状(圆盘、圆形、方形)。

input.pw {
    -webkit-text-security: disc;
}

演示

input.pw {
  -webkit-text-security: disc;
}

input.pw2 {
  -webkit-text-security: circle;
}

input.pw3 {
  -webkit-text-security: square;
}
<input type="text" class="pw" value="secret">
<input type="text" class="pw2" value="secret">
<input type="text" class="pw3" value="secret">

但是,这显然是不标准的。至少Safari CSS docs 说它是“Apple 扩展”。它在 Chrome 中运行良好 - 显然 - 但我认为任何其他渲染引擎都不支持它......

【讨论】:

  • "但我宁愿有一个仅适用于现代浏览器的解决方案,而不是根本没有解决方案"
  • 微软应该将 internet explorer 重命名为 internet explorer... 会更有意义 :-)
【解决方案2】:

如果你想阻止复制粘贴功能,那么你可以使用:

-webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: moz-none; -ms-user-select: none; user-select: none;

这不会让其他人选择文本,因此他们将无法复制。

【讨论】:

  • 你为什么认为这就是 OP 想要的?说真的,不能复制和粘贴通常是密码字段最不重要的功能。人们在看你的屏幕时看不到输入的密码,浏览器也没有将密码存储为简单的表单字段自动完成,这是人们通常想要的。
  • 这是一些很好的信息,可以发布在这个页面上。也许 OP 不想阻止复制和粘贴,但是将来有人会来这里寻找他们想要隐藏的输入字段,并查看此复制和粘贴预防并将其合并。 @ThiefMaster,为什么你认为 OP、DenverCoder92 或未来的其他人不想要这些信息?
【解决方案3】:

正如@ThiefMaster 建议的那样

input.pw {
    -webkit-text-security: disc;
}

但是,这将在 webkit 后代的浏览器中工作。Opera、Chrome 和 Safari,但对其余的支持不多,另一种解决方案是使用 webfonts。

使用任何字体编辑实用程序,如FontForge,创建一个所有字符为*(或您想要的任何符号)的字体。然后使用 CSS 网络字体将它们用作自定义字体。

【讨论】:

  • 这不是解决方案。这不适用于所有浏览器。目前,这不适用于 Mozilla Fire Fox。
  • 奇怪的是,这适用于 Firefox 移动版,但不适用于 Firefox 桌面版
【解决方案4】:

您可以创建仅由点组成的字体

@font-face
    {
    font-family:'dotsfont';
    src:url('dotsfont.eot');
    src:url('dotsfont.eot?#iefix')  format('embedded-opentype'),
        url('dotsfont.svg#font')    format('svg'),
        url('dotsfont.woff')        format('woff'),
        url('dotsfont.ttf')         format('truetype');
    font-weight:normal;
    font-style:normal;
}

input.myclass
    {-webkit-text-security:disc;font-family:dotsfont;}

这可能就是你要找的……

有许多字形需要定义,但可能有更简单的方法来定义。 您可以创建一个完全空的字体并仅定义 .notdef 字形 (glyph ID 0),当另一个字形未定义时用作替换

您可能知道,它通常如下所示:

因此,您应该将其替换为点/星号并测试浏览器会发生什么... 因为我不确定它是否适用于所有这些(有些人可能想使用他们自己丢失的字形替换)。如果您尝试,请告诉我...

HTH

【讨论】:

【解决方案5】:

基本上你可以做到

input { -webkit-text-security: disc; }

在您的 css 文件中。

但是注意,有人可以在 Chrome 中简单地“inspect element”并将 css 元素从“disc”更改为“none”,真实文本将被视为清晰天。

至于禁用选择/复制参考这篇文章: How to disable text selection highlighting using CSS?

【讨论】:

  • 有人可以将类型更改为text 并查看它。或者看看.value
  • 是的,但即使对于 type="password" 字段也是如此。或者,他可以使用 autocomplete="new-password" 这是 chrome 的一项新功能,您可以在此处进一步了解它:link
【解决方案6】:

这仅适用于text 字段(:

input { -webkit-text-security: none; } 
input { -webkit-text-security: circle; } 
input { -webkit-text-security: square; } 
input { -webkit-text-security: disc; /* Default */ }

【讨论】:

    【解决方案7】:

    我最近多次出现在这个线程中。我的解决方案是利用JQuery 输入事件(虽然它也可以写成原始JS 甚至C# (Blazor) 如果你需要它,想法是一样的):

    核心部分是:

    if (isPasswordVisible) { // if password is visible, then simply update value stored in the dictionary
        value = newValue;
        passwordInputsValues[$passwordInput.attr("my-guid")] = value;
    } else { // else compute and update stored value
        const newValueUntilCaret = newValue.take(caretPosition); // take chars before the caret
        const unchangedCharsAtStart = newValueUntilCaret.takeWhile(c => c === "●").length; // count unchanged chars from the beginning
        const unchangedCharsAtEnd = newValue.skip(caretPosition).length; // count unchanged chars after the caret
        const insertedValue = newValueUntilCaret.skip(unchangedCharsAtStart); // get newly added string if any
        value = oldValue.take(unchangedCharsAtStart) + insertedValue + oldValue.takeLast(unchangedCharsAtEnd); // create new value as concatenation of old value left part, new string and old value right part
        passwordInputsValues[$passwordInput.attr("my-guid")] = value; // store newly created value in the dictionary
        $passwordInput.prop("value", value.split("").map(_ => "●").join("")); // set value of the input to new masked value
        $passwordInput[0].setSelectionRange(caretPosition, caretPosition); // set caret position to match the appropriate position 
    }
    

    下面是一个示例密码控制的完整代码(如果有问题我会尝试更新它):

    // Utils 
    
    var guid = () => {
        return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
            const r = Math.random() * 16 | 0;
            const v = c === "x" ? r : r & 0x3 | 0x8;
            return v.toString(16);
        });
    }
    
    // Array Extensions
    
    Object.defineProperty(Array.prototype, "skip", {
        value: function (n) {
            if (typeof (n) !== "number") {
                throw new Error("n is not a number");
            }
            return this.slice(n);
        },
        writable: true,
        configurable: true
    });
    
    Object.defineProperty(Array.prototype, "take", {
        value: function (n) {
            if (typeof (n) !== "number") {
                throw new Error("n is not a number");
            }
            return this.slice(0, n);
        },
        writable: true,
        configurable: true
    });
    
    Object.defineProperty(Array.prototype, "takeLast", {
        value: function (n) {
            if (typeof (n) !== "number") {
                throw new Error("n is not a number");
            }
            return this.slice(Math.max(this.length - n, 0));
        },
        writable: true,
        configurable: true
    });
    
    Object.defineProperty(Array.prototype, "takeWhile", {
        value: function (condition) {
            if (typeof (condition) !== "function") {
                throw new Error("condition is not a function");
            }
    
            const arr = [];
            for (let el of this) {
                if (condition(el))
                    arr.push(el);
                else
                    break;
            }
            return arr;
        },
        writable: true,
        configurable: true
    });
    
    // String Extensions
    
    Object.defineProperty(String.prototype, "skip", {
        value: function (n) {
            return this.split("").skip(n).join("");
        },
        writable: true,
        configurable: true
    });
    
    Object.defineProperty(String.prototype, "take", {
        value: function (n) {
            return this.split("").take(n).join("");
        },
        writable: true,
        configurable: true
    });
    
    Object.defineProperty(String.prototype, "takeLast", {
        value: function (n) {
            return this.split("").takeLast(n).join("");
        },
        writable: true,
        configurable: true
    });
    
    Object.defineProperty(String.prototype, "takeWhile", {
        value: function (condition) {
            return this.split("").takeWhile(condition).join("");
        },
        writable: true,
        configurable: true
    });
    
    // JQuery Document Ready
    
    $(document).ready(function() {
        let isPasswordVisible = false;
        const passwordInputsValues = {};
    
        for (let $pi of $(".my-password-input").toArray().map(pi => $(pi))) {
            const uid = guid();
            $pi.attr("my-guid", uid);
            passwordInputsValues[uid] = $pi.prop("value");
        }
    	
        $(document).on("input", ".my-password-input", async function(e) {
            const $passwordInput = $(this);
            const newValue = $passwordInput.prop("value");
            const oldValue = passwordInputsValues[$passwordInput.attr("my-guid")] || ""; // first time it will be undefined
            const caretPosition = Math.max($passwordInput[0].selectionStart, $passwordInput[0].selectionEnd);
            let value;
    
            if (isPasswordVisible) {
                value = newValue;
                passwordInputsValues[$passwordInput.attr("my-guid")] = value;
            } else {
                const newValueUntilCaret = newValue.take(caretPosition);
                const unchangedCharsAtStart = newValueUntilCaret.takeWhile(c => c === "●").length;
                const unchangedCharsAtEnd = newValue.skip(caretPosition).length;
                const insertedValue = newValueUntilCaret.skip(unchangedCharsAtStart);
                value = oldValue.take(unchangedCharsAtStart) + insertedValue + oldValue.takeLast(unchangedCharsAtEnd);
                passwordInputsValues[$passwordInput.attr("my-guid")] = value;
                $passwordInput.prop("value", value.split("").map(_ => "●").join(""));
                $passwordInput[0].setSelectionRange(caretPosition, caretPosition);
            }
        });
    
        $(document).on("click", ".my-btn-toggle-password-visibility", function() {
            const $btnTogglePassword = $(this);
            const $iconPasswordShown = $btnTogglePassword.find(".my-icon-password-shown");
            const $iconPasswordHidden = $btnTogglePassword.find(".my-icon-password-hidden");
            const $passwordInput = $btnTogglePassword.parents(".my-input-group").first().children(".my-password-input").first();
            const value = passwordInputsValues[$passwordInput.attr("my-guid")];
    
            if (!isPasswordVisible) {
                $iconPasswordHidden.removeClass("my-d-flex").addClass("my-d-none");
                $iconPasswordShown.removeClass("my-d-none").addClass("my-d-flex");
                $passwordInput.prop("value", value);
                isPasswordVisible = true;
            } else {
                $iconPasswordShown.removeClass("my-d-flex").addClass("my-d-none");
                $iconPasswordHidden.removeClass("my-d-none").addClass("my-d-flex");
                $passwordInput.prop("value", value.split("").map(_ => "●").join(""));
                isPasswordVisible = false;
            }
        });
    });
    body {
        padding-top: 0;
        color: white;
        margin: 0;
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
        font-size: 16px;
        font-weight: 400;
        line-height: 1.5;
        text-align: left;
        height: 100%;
        max-height: 100%;
        background-image: linear-gradient(rgba(0,0,0,0.2), rgba(0,0,0,0.2)), url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAABGCAAAAABURb1YAAAFnklEQVR4AWWXCY4cwXbE6h4JMhCvMPc/ov+3Ox9QsLCGpKlFHILd+UQ559AGDkBSFXWmomonqkL/XuUcIPUcONjHCJyE36KaqNiaRnVCG9TGpgIU9hIfohCBVGj24ammo04lU3Fy0NZDAyZi5AElHjgEGlRbG1WjraIt7TmADQkAaoEHsOXAAaeqat9RVTqjosyEH5W+DQCQt8BzIJMfXJI3e5tGRefSlRn3NrO3scnvNl26FN5RITGNfjm3GM/+FhQgnlQeImC+dEm8rzHVTNGL9EADVsTAIfGJBziRy7RlmcZU1IYpHIj+4JrWym8/XSwzompmFNVOFdTOAAfs61KZ6eXcp57fykQUOxNBmTesz2HpCnCg3UV/bA7VRpWGNqKtrYLTs0ilCjgxiZxjeLC5dDPBFn4Pn2ja6BRUL10DTgET4Focq8rn8casxV4E5tIlZvytqtfivCOKZrqc38G7egnkXecyPZdzubc57VtUnbfL+a0u3b1N3d9Mci7cKocHoh3xihLQ6fXUlgTOOfVkXSUFINoWHhqxE23RTmCqtoEJaITkIrUCkU9fnqpqm+40VSXS3CLaSzfGBb4rPuOSfN0ylLve6/jpcrbL2dTlnOdv5AamKjLvLN1XruMNS/cul/hx8twKpKYRaE2DOp8+c+lW7uVXVQ7Vx0x1G3HXjNocsHCac7NbWc6egwJVHu2kRTVNC2pqv2U4XNsv5/yWJlV9+NJ1C7xluInlcr7rK+Kg+qy7onQqgnbi7UHcS3qXjdw3bO5tumycYlVssMI5EXXpRnatPK362KodtVU60cm+eQT10sVLFwJYlVaf7UGSoi5dQF3DvnTX3UvXTPO8quKH7jsXhm/PxfKWZXqBM5sS33kmKtC31Q05fI095i5IPpyzRXqSy1Sr17p1F7NE8vMtnNbLpVVtk8c0OrfF0sKxHnIpYgHW4puMomTz8mgmrSjpvrxhX97l7LqLpl7bW9BH9/MNzF8XwRqL8/m7c30eFYV5VX3QTquK06XbLt16F4ks+8Z9m6gPtpcuk3OvibCekng4lzMHi9MoqZmKj9tdbQCbc7bcEA+oEJduRNNL1waf1tuI9MDBUK8t3k9uFz3rrqadO9Ln9TL/ezlwDvky3TW7ZmXfpc77TN0yhOXnP939LvVDV9s+tgLTm0TqYd1lea3PRFuVjLa562HdPbCfascGrvO3DMeIATVqVRO8vfHrbupdfo1dzlXUdkVLZsS1mLPG3rWcl+4B1l1537h0VXzU1tyLG7cCu+LSrSqo06hocy3WCcil65qHDbuEYzQN2HpT3jFt9LEFvHTP1nxbXOEkbhkKmd+6BTfVZ/I143z/Fyz6Za92o0I7I6gzfeYAHPwy/Rb43L9TLtMt8CtwW1xvQvbR1g9n7qJRNN1kdxcdH7cM58Szxq679MdLOhE72t6VNEpHHkzwRyjBcGth+dE99pIkVbWaEWmvnQ8Yl7Mp59zpRWXdNo6odrO754Zzvxf/010nP7onb1TR+bgbVPB9PcADJvH/043Kvk0UzLRxQ6UiaeTAcyxYl2lyrrvZv8v2wE7U1uVcST0821jJeIDKWuyxiqnuko7q3+zJYXJ46nV3D67EyL+lQ9F2qkr+3kUafQpwYE8T329p6y7OX1TF97fQv/c+l87zj7Hsgpig4qRLd9fMPs74rLGyCzRbhmVqpy7nqvPmTD1gvKe7b2U8u1QzmtuDuEtbgT3c8QBJveo6cueFkUwv59nVmfFw1jl4/unuOT9qERV76ers8n23z/c8/Xy7a4lwwLplmGusbRp33Up13+ZDN3KPxNVMhY62vUQyRTse6+cKHtZYjIfDh260Cjbb3Vy6R8H8SMBzqSwrsB1UTacoknlnOb8V4JD9Njfpwz/fHjpBUeevcAtcl65sqXPX9D87RUTLc/dfOgAAAABJRU5ErkJggg==);
        background-clip: border-box;
        background-origin: padding-box;
        background-attachment: scroll;
        background-repeat: repeat;
        background-size: auto;
        background-position: left top;
    }
    
    .snippet-container {
        background: linear-gradient(135deg, #202020, black);
        position: relative;
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100%;
        height: 200px;
    }
    
    .my-password-input {
        background: linear-gradient(to bottom, #303030, #000000);
        color: white;
        display: block;
        position: relative;
        box-sizing: border-box;
        padding: 5px 9px;
        line-height: 24px;
        height: 34px;
        box-shadow: inset 0 0 0 1px #404040;
        font-size: 16px;
        font-weight: 400;
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
        transition: all .15s ease-in-out;
        width: 100%;
        border: none;
    }
    
    .my-password-input:enabled:focus {
        color: white;
        box-shadow: inset 0 0 0 1px #404040, 0 0 6px 2px blue;
        outline: none;
    }
    
    .my-input-group {
        position: relative;
    }
    
        .my-input-group > .my-input-group-prepend {
            display: flex;
            position: absolute;
            left: 0;
            top: 0;
        }
    
        .my-input-group > .my-input-group-append {
            display: flex;
            position: absolute;
            right: 0;
            top: 0;
        }
    
    .my-icon {
        display: flex;
        align-items: center;
        justify-content: center;
        overflow: hidden;
    }
    
    .my-input-group > .my-input-group-prepend > .my-icon,
    .my-input-group > .my-input-group-append > .my-icon {
        width: auto;
        height: 16px;
        max-width: none;
        max-height: 16px;
        flex: 0 0 auto;
        margin: 9px;
    }
    
        .my-input-group > .my-input-group-prepend > .my-icon > svg,
        .my-input-group > .my-input-group-append > .my-icon > svg {
            height: 100%;
            width: auto;
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
    
    .my-input-group > .my-input-group-prepend > .my-btn,
    .my-input-group > .my-input-group-append > .my-btn {
        height: 100% !important;
        width: auto;
    }
    
    button:enabled {
        cursor: pointer;
    }
    
    .my-btn {
        background: linear-gradient(to bottom, #303030, #000000);
        color: white;
        position: relative;
        box-sizing: border-box;
        padding: 5px;
        line-height: 24px;
        height: 34px;
        font-size: 16px;
        font-weight: 400;
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
        transition: all .15s ease-in-out;
        width: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        border: none;
        box-shadow: 0 0 0 0 #FFFFFF, inset 0 0 0 1px #404040;
    }
    
    .my-btn-primary {
        color: #fff;
        background: linear-gradient(to bottom, #00008B, #000000);
        box-shadow: 0 0 0 0 #FFFFFF, inset 0 0 0 1px #0000FF;
    }
    
        .my-btn-primary:hover:enabled {
            box-shadow: 0 0 6px 2px #FFFFFF, inset 0 0 0 1px #FFFFFF;
            background: linear-gradient(to top, #00008B, #000000);
        }
    
    .my-btn > .my-icon {
        margin: 4px;
        width: auto;
        height: 16px;
        max-width: none;
        max-height: 16px;
        flex: 0 0 auto;
    }
    
        .my-btn > .my-icon > svg {
            height: 100%;
            width: auto;
        }
    
    .my-d-none {
        display: none !important;
    }
    
    .my-d-flex {
        display: flex !important;
    }
    
    ::-webkit-input-placeholder {
        color: #404040;
        font-style: italic;
    }
    
    :-moz-placeholder {
        color: #404040;
        font-style: italic;
    }
    
    ::-moz-placeholder {
        color: #404040;
        font-style: italic;
    }
    
    :-ms-input-placeholder {
        color: #404040;
        font-style: italic;
    }
    
    ::-moz-selection {
        background-color: #f8b700;
        color: #352011;
    }
    
    ::selection {
        background-color: #f8b700;
        color: #352011;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <div class="snippet-container">
        <div class="my-input-group">
            <input type="text" placeholder="Password..." class="my-password-input" style="padding-left: 38px; padding-right: 47px;">
            <div class="my-input-group-prepend">
                <div class="my-icon" style="">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="">
                        <path d="M336 32c79.529 0 144 64.471 144 144s-64.471 144-144 144c-18.968 0-37.076-3.675-53.661-10.339L240 352h-48v64h-64v64H32v-80l170.339-170.339C195.675 213.076 192 194.968 192 176c0-79.529 64.471-144 144-144m0-32c-97.184 0-176 78.769-176 176 0 15.307 1.945 30.352 5.798 44.947L7.029 379.716A24.003 24.003 0 0 0 0 396.686V488c0 13.255 10.745 24 24 24h112c13.255 0 24-10.745 24-24v-40h40c13.255 0 24-10.745 24-24v-40h19.314c6.365 0 12.47-2.529 16.971-7.029l30.769-30.769C305.648 350.055 320.693 352 336 352c97.184 0 176-78.769 176-176C512 78.816 433.231 0 336 0zm48 108c11.028 0 20 8.972 20 20s-8.972 20-20 20-20-8.972-20-20 8.972-20 20-20m0-28c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z" style="fill: white"></path>
                    </svg>
                </div>
            </div>
            <div class="my-input-group-append">
                <button class="my-btn my-btn-primary my-btn-toggle-password-visibility" style="width: 38px">
                    <div class="my-icon my-icon-password-shown my-d-none" style="">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" style="">
                            <path d="M288 288a64 64 0 0 0 0-128c-1 0-1.88.24-2.85.29a47.5 47.5 0 0 1-60.86 60.86c0 1-.29 1.88-.29 2.85a64 64 0 0 0 64 64zm284.52-46.6C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 96a128 128 0 1 1-128 128A128.14 128.14 0 0 1 288 96zm0 320c-107.36 0-205.46-61.31-256-160a294.78 294.78 0 0 1 129.78-129.33C140.91 153.69 128 187.17 128 224a160 160 0 0 0 320 0c0-36.83-12.91-70.31-33.78-97.33A294.78 294.78 0 0 1 544 256c-50.53 98.69-148.64 160-256 160z" style="fill: white"></path>
                        </svg>
                    </div>
    
                    <div class="my-icon my-icon-password-hidden" style="">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" style="">
                            <path d="M637 485.25L23 1.75A8 8 0 0 0 11.76 3l-10 12.51A8 8 0 0 0 3 26.75l614 483.5a8 8 0 0 0 11.25-1.25l10-12.51a8 8 0 0 0-1.25-11.24zM320 96a128.14 128.14 0 0 1 128 128c0 21.62-5.9 41.69-15.4 59.57l25.45 20C471.65 280.09 480 253.14 480 224c0-36.83-12.91-70.31-33.78-97.33A294.88 294.88 0 0 1 576.05 256a299.73 299.73 0 0 1-67.77 87.16l25.32 19.94c28.47-26.28 52.87-57.26 70.93-92.51a32.35 32.35 0 0 0 0-29.19C550.3 135.59 442.94 64 320 64a311.23 311.23 0 0 0-130.12 28.43l45.77 36C258.24 108.52 287.56 96 320 96zm60.86 146.83A63.15 63.15 0 0 0 320 160c-1 0-1.89.24-2.85.29a45.11 45.11 0 0 1-.24 32.19zm-217.62-49.16A154.29 154.29 0 0 0 160 224a159.39 159.39 0 0 0 226.27 145.29L356.69 346c-11.7 3.53-23.85 6-36.68 6A128.15 128.15 0 0 1 192 224c0-2.44.59-4.72.72-7.12zM320 416c-107.36 0-205.47-61.31-256-160 17.43-34 41.09-62.72 68.31-86.72l-25.86-20.37c-28.48 26.28-52.87 57.25-70.93 92.5a32.35 32.35 0 0 0 0 29.19C89.71 376.41 197.07 448 320 448a311.25 311.25 0 0 0 130.12-28.43l-29.25-23C389.06 408.84 355.15 416 320 416z" style="fill: white"></path>
                        </svg>
                    </div>
                </button>
            </div>
        </div>
    </div>

    【讨论】:

      【解决方案8】:

      您可以使用自定义字体输入带有类型文本的虚假密码。以下适用于 chromefirefoxedge ...

      @font-face {
        font-family: 'password';
        font-style: normal;
        font-weight: 400;
        src: url(https://jsbin-user-assets.s3.amazonaws.com/rafaelcastrocouto/password.ttf);
      }
      
      input.key {
        font-family: 'password';
        width: 100px; height: 16px;  
      }
      &lt;p&gt;Password: &lt;input class="key" type="text" autocomplete="off" /&gt;&lt;/p&gt;

      感谢@rafaelcastrocouto Original Answer

      【讨论】:

        【解决方案9】:

        我希望输入类型文本和密码看起来相同,同时仍为密码输入字段提供 ***** 的安全性

        CSS

        input[type="text"],
        select {
          width: 90%;
          padding: 10px 20px;
          margin: 8px 0;
          display: inline-block;
          border: 1px solid #ccc;
          border-radius: 1px;
          box-sizing: border-box;
        }
        input[type="password"],
        select {
          width: 90%;
          padding: 10px 20px;
          margin: 8px 0;
          display: inline-block;
          border: 1px solid #ccc;
          border-radius: 1px;
          box-sizing: border-box;
        }
        

        HTML

        <input
            type="text"
            name="email"
            placeholder="user@email.com"
        />
        
        <input
            type="password"
            name="password"
            placeholder="*********************"
        />
        
        

        【讨论】:

          【解决方案10】:

          我使用了这个项目中的字体https://github.com/noppa/text-security。以下是“圆盘”的样式(“圆形”或“方形”也可以这样做)

          @font-face {
            font-family: 'text-security-disc';
            src: url('fonts/text-security-disc.woff2') format('woff2'),
              url('fonts/text-security-disc.woff') format('woff');
          }
          
          .text-security-disc {
            font-family: text-security-disc;
            /* Use -webkit-text-security if the browser supports it */
            -webkit-text-security: disc;
          }
          

          【讨论】:

            猜你喜欢
            • 2013-06-13
            • 1970-01-01
            • 2013-06-28
            • 2013-06-05
            • 2010-10-02
            • 2015-03-18
            • 2013-03-20
            • 2012-06-10
            • 1970-01-01
            相关资源
            最近更新 更多