获取输入type = text看起来像type = password

时间:2013-07-21 05:36:42

标签: html css

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解决方案)

8 个答案:

答案 0 :(得分:27)

好像@ThiefMaster建议

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

但是,这将适用于webkit后代的浏览器.. Opera,Chrome和Safari,但对其余部分的支持不多,另一个解决方案是使用webfonts。

使用FontForge之类的任何字体编辑工具创建一个字体,其中所有字符都是*(或您想要的任何符号)。然后使用CSS Web字体将它们用作自定义字体。

答案 1 :(得分:18)

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

@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字形(字形ID 0 ),当未定义另一个字形时,该字形用作替换

您可能知道,它通常看起来像这样: missing glyph icons

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

HTH

答案 2 :(得分:9)

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

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

演示:http://jsfiddle.net/ThiefMaster/6uJJw/1/

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

答案 3 :(得分:0)

这仅适用于text字段(:

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

答案 4 :(得分:0)

最近我多次进入这个线程。我的解决方案是利用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>

答案 5 :(得分:0)

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

return products.WhereAnyMatch(trimmedTags, (p, t) => 
    ("," + p.Categories + ",").Contains("," + t + ",") ||
    ("," + p.Categories + ",").Contains(", " + t + ",") ||
    ("," + p.Categories + ",").Contains("," + t + " ,") ||
    ("," + p.Categories + ",").Contains(", " + t + " ,"));
@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;  
}

感谢@rafaelcastrocouto Original Answer

答案 6 :(得分:-1)

基本上你可以做到

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

在你的css文件中。

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

关于禁用选择/复制,请参阅此帖子: How to disable text selection highlighting using CSS?

答案 7 :(得分:-4)

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

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

不允许其他人选择文字,因此他们将无法复制。