CSS 伪元素 input-placeholder::after 在文本框中显示有无值
CSS pseudo-element input-placeholder::after to show with or without value in text box
我正在尝试在验证后为用户在表单元素上添加一些 UI 标记,以便使用占位符伪元素(从文本框开始)工作。我想要的是 ::input-placeholder::after
伪元素,当文本框中既有值又有文本框中没有值时(例如,存在无效值时或当值是必需的 - 应通过 ::input-placeholder::after
伪元素在文本框的最右侧显示红色 "X"。
这是 fiddle:
https://jsfiddle.net/edsinek/L8u7s25d/
这是我用来显示 "X" 无效值的 CSS 的片段:
.input-invalid input[type=text]::-webkit-input-placeholder::after {
content: "16"; // "X"
font-size: 18px;
color: #ff0000;
padding-right: 0;
float: right;
}
注意:目前我只是在为 Chrome 编码,所以请原谅 webkit 特定的东西。
有什么想法吗?或者这是不可能的并且依赖于 UA?
原答案:(不适用于Chrome v47及更高版本+)
当您开始在文本框中键入内容时,::-webkit-input-placeholder
元素的可见性设置为 hidden
。要在输入框有值时显示其 ::after
元素,我们需要覆盖它并将 visibility
设置为 visible
.
.input-invalid input[type=text]::-webkit-input-placeholder::after {
visibility: visible;
}
var addFormFocusEventHandler = function() {
var placeholder;
// using the document syntax in case input & container added to DOM dynamically
$(document).on("focus", "div.input-container :input", function() {
$(this).closest("div.input-container").addClass("input-focused");
placeholder = $(this).prop("placeholder");
$(this).prop("placeholder", " ");
}).on("blur", "div.input-container :input", function() {
$(this).closest("div.input-container").removeClass("input-focused");
$(this).prop("placeholder", placeholder);
placeholder = "";
});
};
var addFormValueEventHandler = function() {
// using the document syntax in case input & container added to DOM dynamically
$(document).on("blur", "div.input-container :input", function() {
if ($(this).val()) {
$(this).closest("div.input-container").addClass("input-has-value");
} else {
$(this).closest("div.input-container").removeClass("input-has-value");
}
});
};
var initialize = function() {
addFormFocusEventHandler();
addFormValueEventHandler();
};
initialize();
label {
color: transparent;
display: block;
}
input[type=text] {
display: block;
border-width: 0 0 1px !important;
border-radius: 0;
border-style: solid;
border-color: rgba(0, 0, 0, 0.12);
}
.input-focused:not(.input-invalid) label {
color: rgb(16, 108, 200);
}
.input-focused:not(.input-invalid) input[type=text] {
border-color: rgb(16, 108, 200);
}
.input-has-value:not(.input-invalid):not(.input-focused) label {
color: #595959;
}
.input-invalid.input-focused label,
.input-invalid.input-has-value label {
color: #ff0000;
}
.input-invalid input[type=text] {
border-color: #ff0000;
}
.input-invalid input[type=text]::-webkit-input-placeholder {
color: #ff0000;
}
.input-invalid input[type=text]::-webkit-input-placeholder::after {
content: "16";
/* "X" */
font-size: 18px;
color: #ff0000;
padding-right: 0;
float: right;
}
.input-valid input[type=text]::-webkit-input-placeholder::after {
content: "14";
/* checkmark */
font-size: 18px;
color: #438D5B;
padding-right: 0;
float: right;
}
.input-invalid input[type=text]::-webkit-input-placeholder::after {
visibility: visible;
}
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class="col-xs-12 input-container input-required">
<label for="merchantAddress">Merchant Address</label>
<input type="text" class="full-width" id="merchantAddress" placeholder="Merchant Address" />
</div>
<div class="col-xs-12 input-container input-valid">
<label for="merchantCity">Merchant City</label>
<input type="text" class="full-width" id="merchantCity" placeholder="Merchant City" value="" />
</div>
<div class="col-xs-12 input-container input-invalid">
<label for="merchantState">Merchant State Code</label>
<input type="text" class="full-width" id="merchantState" placeholder="Merchant State Code" value="" />
</div>
<div class="col-xs-12 input-container input-invalid input-required">
<label for="merchantZip">Merchant Zip Code</label>
<input type="text" class="full-width" id="merchantZip" placeholder="Merchant Zip Code" value="Bad Data" />
</div>
</div>
</div>
Note: I would not recommend using the placeholder pseudo-element or its child pseudo-element for this purpose but then if you still wish to proceed the above answer would work for you.
+为什么以上在 Chrome v47 及更高版本中不起作用?
正如 Pete Talks Web 在评论中指出的那样,上述内容在 Chrome v47 中似乎不起作用,而在 Chrome v43 中有效。这似乎是因为占位符伪元素 (::-webkit-input-placeholder
) 在键入文本后的隐藏方式存在关键差异。在 v43 中,visibility
属性 用于隐藏它,而在 v47 中,似乎使用了 display:none
。我无权访问 v47,但假设这是基于在也使用 WebKit 的 Opera 中观察到的行为。 !important
也被添加到它。这一点以及 属性 作为内联样式添加的事实意味着不可能单独使用 CSS 进行覆盖。 UA's shadow DOM elements cannot be accessed through JS also 因此一旦输入文本就无法使伪元素可见。
最近的 Chrome 发生了什么?
在Chrome v50.0.2638.0 dev-m中,问题中提供的fiddle本身不起作用。也就是说,既不显示十字也不显示刻度线。似乎 WebKit 已经开始禁止向 ::-webkit-input-placeholder
添加伪元素。这是我一直期待发生的一件事,这正是我在回答中添加该注释的原因。
备选方案:
另一种解决方案是将伪元素添加到包装器 div
并将其定位为 apt。在下面的代码片段中,我将 input
和伪元素更改为 inline-block,相对定位伪元素并向其添加负值 margin-left
。这些使它出现在输入框的右边缘附近。 (我还在 label
中添加了 width: 100%
以使其跨越整行。)
var addFormFocusEventHandler = function() {
var placeholder;
// using the document syntax in case input & container added to DOM dynamically
$(document).on("focus", "div.input-container :input", function() {
$(this).closest("div.input-container").addClass("input-focused");
placeholder = $(this).prop("placeholder");
$(this).prop("placeholder", " ");
}).on("blur", "div.input-container :input", function() {
$(this).closest("div.input-container").removeClass("input-focused");
$(this).prop("placeholder", placeholder);
placeholder = "";
});
};
var addFormValueEventHandler = function() {
// using the document syntax in case input & container added to DOM dynamically
$(document).on("blur", "div.input-container :input", function() {
if ($(this).val()) {
$(this).closest("div.input-container").addClass("input-has-value");
} else {
$(this).closest("div.input-container").removeClass("input-has-value");
}
});
};
var initialize = function() {
addFormFocusEventHandler();
addFormValueEventHandler();
};
initialize();
label {
color: transparent;
display: block;
width: 100%; /* add this */
}
input[type=text] {
display: inline-block; /* modify this */
border-width: 0 0 1px !important;
border-radius: 0;
border-style: solid;
border-color: rgba(0, 0, 0, 0.12);
}
.input-focused:not(.input-invalid) label {
color: rgb(16, 108, 200);
}
.input-focused:not(.input-invalid) input[type=text] {
border-color: rgb(16, 108, 200);
}
.input-has-value:not(.input-invalid):not(.input-focused) label {
color: #595959;
}
.input-invalid.input-focused label,
.input-invalid.input-has-value label {
color: #ff0000;
}
.input-invalid input[type=text] {
border-color: #ff0000;
}
.input-invalid input[type=text]::-webkit-input-placeholder {
color: #ff0000;
}
.input-invalid::after { /* change the selector */
position: relative; /* add this */
display: inline-block; /* add this */
margin-left: -1em; /* add this */
content: "16"; /* "X" */
font-size: 18px;
color: #ff0000;
}
.input-valid::after {/* change the seletor */
position: relative; /* add this */
display: inline-block; /* add this */
margin-left: -1em; /* add this */
content: "14"; /* checkmark */
font-size: 18px;
color: #438D5B;
}
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class="col-xs-12 input-container input-required">
<label for="merchantAddress">Merchant Address</label>
<input type="text" class="full-width" id="merchantAddress" placeholder="Merchant Address" />
</div>
<div class="col-xs-12 input-container input-valid">
<label for="merchantCity">Merchant City</label>
<input type="text" class="full-width" id="merchantCity" placeholder="Merchant City" value="" />
</div>
<div class="col-xs-12 input-container input-invalid">
<label for="merchantState">Merchant State Code</label>
<input type="text" class="full-width" id="merchantState" placeholder="Merchant State Code" value="" />
</div>
<div class="col-xs-12 input-container input-invalid input-required">
<label for="merchantZip">Merchant Zip Code</label>
<input type="text" class="full-width" id="merchantZip" placeholder="Merchant Zip Code" value="Bad Data" />
</div>
</div>
</div>
一旦用户开始在输入框中键入内容,浏览器就会隐藏占位符以及您的 X。
不幸的是,您不能将它放在带有 :after 的输入旁边,因为目前不支持它。
如果您喜欢将 X 放在输入旁边,我建议在输入旁边放置一个 div,必要时 adding/showing X。
否则,我会像移动占位符一样移动 X。
在焦点上,您将占位符设置为“”并为标签指定颜色。这使得标签对用户可见,并保留一个占位符,你可以在 :after 中使用它。您可以改为将占位符设置为“”,这将从输入框中删除您的 X,但添加一个 :after 或 :before 到您的标签,并在那里显示 X。
CSS 在标签后显示 X
.input-invalid.input-focused label:after,
.input-invalid.input-has-value label:after {
content: " 16";
}
我正在尝试在验证后为用户在表单元素上添加一些 UI 标记,以便使用占位符伪元素(从文本框开始)工作。我想要的是 ::input-placeholder::after
伪元素,当文本框中既有值又有文本框中没有值时(例如,存在无效值时或当值是必需的 - 应通过 ::input-placeholder::after
伪元素在文本框的最右侧显示红色 "X"。
这是 fiddle: https://jsfiddle.net/edsinek/L8u7s25d/
这是我用来显示 "X" 无效值的 CSS 的片段:
.input-invalid input[type=text]::-webkit-input-placeholder::after {
content: "16"; // "X"
font-size: 18px;
color: #ff0000;
padding-right: 0;
float: right;
}
注意:目前我只是在为 Chrome 编码,所以请原谅 webkit 特定的东西。
有什么想法吗?或者这是不可能的并且依赖于 UA?
原答案:(不适用于Chrome v47及更高版本+)
当您开始在文本框中键入内容时,::-webkit-input-placeholder
元素的可见性设置为 hidden
。要在输入框有值时显示其 ::after
元素,我们需要覆盖它并将 visibility
设置为 visible
.
.input-invalid input[type=text]::-webkit-input-placeholder::after {
visibility: visible;
}
var addFormFocusEventHandler = function() {
var placeholder;
// using the document syntax in case input & container added to DOM dynamically
$(document).on("focus", "div.input-container :input", function() {
$(this).closest("div.input-container").addClass("input-focused");
placeholder = $(this).prop("placeholder");
$(this).prop("placeholder", " ");
}).on("blur", "div.input-container :input", function() {
$(this).closest("div.input-container").removeClass("input-focused");
$(this).prop("placeholder", placeholder);
placeholder = "";
});
};
var addFormValueEventHandler = function() {
// using the document syntax in case input & container added to DOM dynamically
$(document).on("blur", "div.input-container :input", function() {
if ($(this).val()) {
$(this).closest("div.input-container").addClass("input-has-value");
} else {
$(this).closest("div.input-container").removeClass("input-has-value");
}
});
};
var initialize = function() {
addFormFocusEventHandler();
addFormValueEventHandler();
};
initialize();
label {
color: transparent;
display: block;
}
input[type=text] {
display: block;
border-width: 0 0 1px !important;
border-radius: 0;
border-style: solid;
border-color: rgba(0, 0, 0, 0.12);
}
.input-focused:not(.input-invalid) label {
color: rgb(16, 108, 200);
}
.input-focused:not(.input-invalid) input[type=text] {
border-color: rgb(16, 108, 200);
}
.input-has-value:not(.input-invalid):not(.input-focused) label {
color: #595959;
}
.input-invalid.input-focused label,
.input-invalid.input-has-value label {
color: #ff0000;
}
.input-invalid input[type=text] {
border-color: #ff0000;
}
.input-invalid input[type=text]::-webkit-input-placeholder {
color: #ff0000;
}
.input-invalid input[type=text]::-webkit-input-placeholder::after {
content: "16";
/* "X" */
font-size: 18px;
color: #ff0000;
padding-right: 0;
float: right;
}
.input-valid input[type=text]::-webkit-input-placeholder::after {
content: "14";
/* checkmark */
font-size: 18px;
color: #438D5B;
padding-right: 0;
float: right;
}
.input-invalid input[type=text]::-webkit-input-placeholder::after {
visibility: visible;
}
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class="col-xs-12 input-container input-required">
<label for="merchantAddress">Merchant Address</label>
<input type="text" class="full-width" id="merchantAddress" placeholder="Merchant Address" />
</div>
<div class="col-xs-12 input-container input-valid">
<label for="merchantCity">Merchant City</label>
<input type="text" class="full-width" id="merchantCity" placeholder="Merchant City" value="" />
</div>
<div class="col-xs-12 input-container input-invalid">
<label for="merchantState">Merchant State Code</label>
<input type="text" class="full-width" id="merchantState" placeholder="Merchant State Code" value="" />
</div>
<div class="col-xs-12 input-container input-invalid input-required">
<label for="merchantZip">Merchant Zip Code</label>
<input type="text" class="full-width" id="merchantZip" placeholder="Merchant Zip Code" value="Bad Data" />
</div>
</div>
</div>
Note: I would not recommend using the placeholder pseudo-element or its child pseudo-element for this purpose but then if you still wish to proceed the above answer would work for you.
+为什么以上在 Chrome v47 及更高版本中不起作用?
正如 Pete Talks Web 在评论中指出的那样,上述内容在 Chrome v47 中似乎不起作用,而在 Chrome v43 中有效。这似乎是因为占位符伪元素 (::-webkit-input-placeholder
) 在键入文本后的隐藏方式存在关键差异。在 v43 中,visibility
属性 用于隐藏它,而在 v47 中,似乎使用了 display:none
。我无权访问 v47,但假设这是基于在也使用 WebKit 的 Opera 中观察到的行为。 !important
也被添加到它。这一点以及 属性 作为内联样式添加的事实意味着不可能单独使用 CSS 进行覆盖。 UA's shadow DOM elements cannot be accessed through JS also 因此一旦输入文本就无法使伪元素可见。
最近的 Chrome 发生了什么?
在Chrome v50.0.2638.0 dev-m中,问题中提供的fiddle本身不起作用。也就是说,既不显示十字也不显示刻度线。似乎 WebKit 已经开始禁止向 ::-webkit-input-placeholder
添加伪元素。这是我一直期待发生的一件事,这正是我在回答中添加该注释的原因。
备选方案:
另一种解决方案是将伪元素添加到包装器 div
并将其定位为 apt。在下面的代码片段中,我将 input
和伪元素更改为 inline-block,相对定位伪元素并向其添加负值 margin-left
。这些使它出现在输入框的右边缘附近。 (我还在 label
中添加了 width: 100%
以使其跨越整行。)
var addFormFocusEventHandler = function() {
var placeholder;
// using the document syntax in case input & container added to DOM dynamically
$(document).on("focus", "div.input-container :input", function() {
$(this).closest("div.input-container").addClass("input-focused");
placeholder = $(this).prop("placeholder");
$(this).prop("placeholder", " ");
}).on("blur", "div.input-container :input", function() {
$(this).closest("div.input-container").removeClass("input-focused");
$(this).prop("placeholder", placeholder);
placeholder = "";
});
};
var addFormValueEventHandler = function() {
// using the document syntax in case input & container added to DOM dynamically
$(document).on("blur", "div.input-container :input", function() {
if ($(this).val()) {
$(this).closest("div.input-container").addClass("input-has-value");
} else {
$(this).closest("div.input-container").removeClass("input-has-value");
}
});
};
var initialize = function() {
addFormFocusEventHandler();
addFormValueEventHandler();
};
initialize();
label {
color: transparent;
display: block;
width: 100%; /* add this */
}
input[type=text] {
display: inline-block; /* modify this */
border-width: 0 0 1px !important;
border-radius: 0;
border-style: solid;
border-color: rgba(0, 0, 0, 0.12);
}
.input-focused:not(.input-invalid) label {
color: rgb(16, 108, 200);
}
.input-focused:not(.input-invalid) input[type=text] {
border-color: rgb(16, 108, 200);
}
.input-has-value:not(.input-invalid):not(.input-focused) label {
color: #595959;
}
.input-invalid.input-focused label,
.input-invalid.input-has-value label {
color: #ff0000;
}
.input-invalid input[type=text] {
border-color: #ff0000;
}
.input-invalid input[type=text]::-webkit-input-placeholder {
color: #ff0000;
}
.input-invalid::after { /* change the selector */
position: relative; /* add this */
display: inline-block; /* add this */
margin-left: -1em; /* add this */
content: "16"; /* "X" */
font-size: 18px;
color: #ff0000;
}
.input-valid::after {/* change the seletor */
position: relative; /* add this */
display: inline-block; /* add this */
margin-left: -1em; /* add this */
content: "14"; /* checkmark */
font-size: 18px;
color: #438D5B;
}
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class="col-xs-12 input-container input-required">
<label for="merchantAddress">Merchant Address</label>
<input type="text" class="full-width" id="merchantAddress" placeholder="Merchant Address" />
</div>
<div class="col-xs-12 input-container input-valid">
<label for="merchantCity">Merchant City</label>
<input type="text" class="full-width" id="merchantCity" placeholder="Merchant City" value="" />
</div>
<div class="col-xs-12 input-container input-invalid">
<label for="merchantState">Merchant State Code</label>
<input type="text" class="full-width" id="merchantState" placeholder="Merchant State Code" value="" />
</div>
<div class="col-xs-12 input-container input-invalid input-required">
<label for="merchantZip">Merchant Zip Code</label>
<input type="text" class="full-width" id="merchantZip" placeholder="Merchant Zip Code" value="Bad Data" />
</div>
</div>
</div>
一旦用户开始在输入框中键入内容,浏览器就会隐藏占位符以及您的 X。
不幸的是,您不能将它放在带有 :after 的输入旁边,因为目前不支持它。
如果您喜欢将 X 放在输入旁边,我建议在输入旁边放置一个 div,必要时 adding/showing X。
否则,我会像移动占位符一样移动 X。
在焦点上,您将占位符设置为“”并为标签指定颜色。这使得标签对用户可见,并保留一个占位符,你可以在 :after 中使用它。您可以改为将占位符设置为“”,这将从输入框中删除您的 X,但添加一个 :after 或 :before 到您的标签,并在那里显示 X。
CSS 在标签后显示 X
.input-invalid.input-focused label:after,
.input-invalid.input-has-value label:after {
content: " 16";
}