Tôi có thể sử dụng phần tử: trước hoặc: sau phần tử giả trên trường nhập không?


685

Tôi đang cố gắng sử dụng :afterphần tử giả CSS trên một inputtrường, nhưng nó không hoạt động. Nếu tôi sử dụng nó với a span, nó hoạt động tốt.

<style type="text/css">
.mystyle:after {content:url(smiley.gif);}
.mystyle {color:red;}
</style>

Điều này hoạt động (đặt nụ cười sau "buu!" Và trước "một số nữa")

<span class="mystyle">buuu!</span>a some more

Điều này không hoạt động - nó chỉ tô màu một số giá trị màu đỏ, nhưng không có nụ cười.

<input class="mystyle" type="text" value="someValue">

Tôi đang làm gì sai? Tôi có nên sử dụng một bộ chọn giả khác?

Lưu ý: Tôi không thể thêm spanxung quanh mình input, vì nó được tạo bởi kiểm soát của bên thứ ba.


Nếu bạn đã hoàn toàn không có kiểm soát đối với HTML, hãy thử thay đổi border-colorcủa inputthay thế. Tôi thấy nó được chú ý nhiều hơn.
Blazemonger

Câu trả lời:


254

:after:beforekhông được hỗ trợ trong Internet Explorer 7 trở xuống, trên bất kỳ yếu tố nào.

Nó cũng không có nghĩa là được sử dụng trên các yếu tố thay thế, chẳng hạn như yếu tố hình thức (đầu vào) và yếu tố hình ảnh .

Nói cách khác, điều đó là không thể với CSS thuần túy.

Tuy nhiên nếu sử dụng jquery bạn có thể sử dụng

$(".mystyle").after("add your smiley here");

Tài liệu API trên .after

Để nối thêm nội dung của bạn với javascript. Điều này sẽ hoạt động trên tất cả các trình duyệt.


Alex, tôi đang sử dụng IE8 và FF mới nhất, vì vậy IE7 không phải là vấn đề. Tôi đã tìm kiếm bất kỳ tài liệu nào về việc giới hạn: sau đó, nhưng không thể tìm thấy nó. w3.org/TR/CSS2/generate.html tuyên bố rằng nó được chèn sau nút hiện tại trong cây tài liệu để nó hoạt động trong cả hai trường hợp.
matra

3
Trừ khi bạn đang xây dựng trang chỉ cho riêng bạn sử dụng, phần lớn internet vẫn sử dụng các trình duyệt đó. Thông số w3c nói điều này có; nhưng như bạn cũng biết các trình duyệt thực hiện việc giải thích riêng về thông số kỹ thuật. Việc sử dụng: sau khi nhập vào sẽ chỉ hoạt động trong Opera 9+, nhưng không được triển khai trong IE, FF, safari hoặc chrome do cách chúng xây dựng bên trong DOM - một lần nữa không thể thực hiện được bằng CSS thuần túy.
Alex

3
Tôi không chắc liệu đây có phải là trường hợp vào tháng Tư hay không, nhưng Webkit :afternói chung hỗ trợ , mặc dù nó không hỗ trợ :beforehoặc :afterđầu vào.
coreyward

258
Theo như tôi hiểu các yếu tố W3C :after:beforegiả, chúng chỉ có thể được đặt trên các phần tử container. Tại sao? Bởi vì chúng được gắn vào bên trong yếu tố đặc biệt đó. inputkhông phải là một container buttonví dụ là do đó bạn có thể đặt chúng vào. Hoạt động như mong đợi. Đặc tả thực sự nói: trước và sau nội dung cây tài liệu của phần tử Nó nói rõ NỘI DUNG . Vì vậy, một yếu tố phải là một container.
Robert Koritnik

29
Câu trả lời tiếp theo là cách tốt hơn .. Đưa ra lý do thực tế thay vì nói về IE 7 (người quan tâm) và jQuery (ý tưởng tồi)
Rowan

1304

:before:after kết xuất bên trong một container

và <input> không thể chứa các yếu tố khác.


Các phần tử giả chỉ có thể được xác định (hoặc nói tốt hơn là chỉ được hỗ trợ) trên các phần tử container. Bởi vì cách chúng được hiển thị nằm trong chính vùng chứa như là một phần tử con. inputkhông thể chứa các yếu tố khác do đó chúng không được hỗ trợ. Mộtbutton mặt khác đó cũng là một yếu tố hình thức hỗ trợ cho họ, bởi vì đó là một container của sub-yếu tố khác.

Nếu bạn hỏi tôi, nếu một số trình duyệt không hiển thị hai giả yếu tố trên yếu tố phi container, đó là một lỗi và một sự phù hợp không chuẩn. Đặc điểm kỹ thuật nói trực tiếp về nội dung phần tử ...

Đặc điểm kỹ thuật của W3C

Nếu chúng ta đọc kỹ kỹ đặc tả thì nó thực sự nói rằng chúng được chèn vào bên trong một phần tử có chứa:

Tác giả chỉ định kiểu và vị trí của nội dung được tạo bằng: trước và sau phần tử giả. Như tên của chúng chỉ ra, các phần tử giả: trước và sau chỉ định vị trí của nội dung trước và sau nội dung của cây tài liệu. Thuộc tính 'nội dung', kết hợp với các phần tử giả này, chỉ định nội dung được chèn.

Xem? nội dung cây tài liệu của một phần tử . Theo tôi hiểu điều này có nghĩa là trong một container.


119
+1 Tốt hơn nhiều so với câu trả lời được chấp nhận. Cảm ơn đã giải thích rõ ràng về tiêu chuẩn. Quá nhiều cho [required]::before { content "*"; color: red; }: P
Kevin Peno

93
Mẹo: Nếu bạn gặp sự cố chỉ với một đầu vào gửi như thế <input type="submit" value="Send"/>, hãy sử dụng <button type="submit">Send</button>thay thế. Bài thuyết trình giống hệt nhau nhưng <button>là một container và do đó hỗ trợ :before:after.
cúm

15
Thế còn <hr />? Tôi nghĩ rằng nó không phải là một phần tử container, nhưng nó có thể kết xuất :after:before jsfiddle.net/Uf88j/1
deathlock

7
@deathlock: điều đó thực sự thú vị. Tôi có thể nói nó phải là một dạng bất thường và tôi sẽ không dựa vào nó hoạt động trên trình duyệt chéo hoặc phiên bản chéo ... HR không phải là một yếu tố chứa do đó không nên cho phép các yếu tố giả. Ngay cả tiêu chuẩn W3C nói rằng nó cho phép không có nội dung. Và nếu bạn kiểm tra phần tử void, bạn có thể thấy rằng các phần tử này không nên có bất kỳ nội dung nào trong bất kỳ trường hợp nào. Các yếu tố giả là nội dung vì vậy mong muốn phiên bản trình duyệt trong tương lai không hiển thị chúng.
Robert Koritnik

5
" : before và: after render bên trong một container " The: before và: after các phần tử giả đến " trước và sau nội dung ". Không "ở đầu hoặc cuối" của container. Thông số kỹ thuật không đề cập đến một container . Với các thẻ như ph1, nội dung nằm trong thẻ, vì vậy trước / sau cũng xuất hiện bên trong. Với các yếu tố như inputhr,: trước và: sau vẫn sẽ xuất hiện trước hoặc sau nội dung, nhưng không có thùng chứa nào liên quan (đặc biệt là cho input). đầu vào: đã chọn: trước được sử dụng rộng rãi để chỉ ra các hộp kiểm được kiểm tra qua css.
Radley Sustaire

60

Điều kỳ lạ là nó hoạt động với một số loại đầu vào. Ít nhất là trong Chrome,

<input type="checkbox" />

hoạt động tốt, giống như

<input type="radio" />

Nó chỉ type=textvà một số người khác không hoạt động.


1
@ANeves, nó hoạt động trong Chromium cho tôi, nhưng không phải trong Firefox.
kcpr

45

Đây là một cách tiếp cận khác (giả sử bạn có quyền kiểm soát HTML): thêm một khoảng trống <span></span>ngay sau đầu vào và nhắm mục tiêu trong CSS bằng cách sử dụnginput.mystyle + span:after

.field_with_errors {
  display: inline;
  color: red;
}
.field_with_errors input+span:after {
  content: "*"
}
<div class="field_with_errors">Label:</div>
<div class="field_with_errors">
  <input type="text" /><span></span> 
</div>

Tôi đang sử dụng phương pháp này trong AngularJS bởi vì nó sẽ .ng-invalidtự động thêm các lớp để <input>tạo thành các phần tử và cho biểu mẫu, nhưng không phải cho <label>.


1
Nó cho phép thêm các hành động di chuột, như : input:hover+span:after{color: blue}. Upvote.
krassowski

2
Tại sao câu trả lời này có rất ít upvote? Tôi nghĩ kiến ​​thức lý thuyết là quan trọng, nhưng điều này giải quyết vấn đề.
jorgefpastor

Lựa chọn tốt đẹp để đi cùng để giải quyết vấn đề.
Jester

39

:before:afterđược áp dụng bên trong một thùng chứa, có nghĩa là bạn có thể sử dụng nó cho các phần tử có thẻ kết thúc.

Nó không áp dụng cho các yếu tố tự đóng.

Mặt khác, các yếu tố tự đóng (chẳng hạn như img / giờ / đầu vào) cũng được gọi là Elements Các thành phần thay thế ', vì chúng được thay thế bằng nội dung tương ứng. "Đối tượng bên ngoài" cho việc thiếu một thuật ngữ tốt hơn. Đọc tốt hơn ở đây


Câu trả lời này là chính xác, súc tích và cung cấp bối cảnh quan trọng. Nên ở trên đỉnh, imo.
Paul

31

Tôi đã sử dụng background-imageđể tạo dấu chấm màu đỏ cho các trường bắt buộc.

input[type="text"][required] {
  background-image: radial-gradient(red 15%, transparent 16%);
  background-size: 1em 1em;
  background-position: top right;
  background-repeat: no-repeat
}

Xem trên Codepen


20

Bạn không thể đặt phần tử giả trong phần tử đầu vào, nhưng có thể đặt phần tử bóng, như phần giữ chỗ!

input[type="text"] {   
  &::-webkit-input-placeholder {
    &:before {
      // your code
    }
  }
}

Để làm cho nó làm việc trong các trình duyệt khác, sử dụng :-moz-placeholder, ::-moz-placeholder:-ms-input-placeholder trong bộ chọn khác nhau . Không thể nhóm các bộ chọn, bởi vì nếu trình duyệt không nhận ra bộ chọn sẽ làm mất hiệu lực toàn bộ câu lệnh.

CẬP NHẬT : Đoạn mã trên chỉ hoạt động với bộ xử lý trước CSS (SASS, LESS ...), mà không sử dụng bộ xử lý trước:

input[type="text"]::-webkit-input-placeholder:before { // your code }

3
Đẹp! Lưu ý rằng phần tử giả giữ chỗ có hỗ trợ thuộc tính hạn chế: màu sắc, nền, khoảng cách từ, khoảng cách chữ, trang trí văn bản, căn chỉnh dọc, chuyển đổi văn bản, chiều cao dòng, thụt lề văn bản, độ mờ. Xem css-tricks.com/almanac/selector/p/placeholder
henry

Cảm ơn đã gợi ý. Chỉ cần nhớ rằng mọi thứ bên trong phần tử giả sẽ biến mất khi hộp đầu vào được điền bởi người dùng. Đó là một vấn đề UX nếu tất cả những gì bạn muốn, như tôi, đang hiển thị glyphicon-searchmà không chạm vào đánh dấu.
Davi Lima

2
Một số bối cảnh về lý do tại sao điều này không còn hoạt động: bug.chromium.org/p/chromium/issues/detail?id=582301
Oliver Joseph Ash

17

Các phần tử giả như :after, :beforechỉ dành cho các phần tử container. Các phần tử bắt đầu và đóng ở một nơi như <input/>, <img>v.v. không phải là phần tử chứa và do đó các phần tử giả không được hỗ trợ. Khi bạn áp dụng một phần tử giả cho phần tử container như <div>và nếu bạn kiểm tra mã (xem hình ảnh), bạn có thể hiểu ý của tôi. Trên thực tế phần tử giả được tạo bên trong phần tử container. Điều này là không thể trong trường hợp <input>hoặc<img>

nhập mô tả hình ảnh ở đây


15

Một giải pháp hoạt động trong CSS thuần:

Bí quyết là giả sử có một phần tử dom sau trường văn bản.

/*
 * The trick is here:
 * this selector says "take the first dom element after
 * the input text (+) and set its before content to the
 * value (:before).
 */
input#myTextField + *:before {
  content: "👍";
} 
<input id="myTextField" class="mystyle" type="text" value="someValue" />
<!--
  There's maybe something after a input-text
  Does'nt matter what it is (*), I use it.
  -->
<span></span>

(*) Giải pháp hạn chế, mặc dù:

  • bạn phải hy vọng rằng có một yếu tố dom sau,
  • bạn phải hy vọng không có trường đầu vào nào khác theo trường đầu vào của bạn.

Nhưng trong hầu hết các trường hợp, chúng tôi biết mã của mình nên giải pháp này có vẻ hiệu quả và 100% CSS và 0% jQuery.


2
input#myTextField ~ span:before {tốt hơn nhiều, nhưng span nên có một lớp thực sự rõ ràng hơn như .tickhoặc.icon
Val

13

Tôi tìm thấy bài đăng này vì tôi đang có cùng một vấn đề, đây là giải pháp hiệu quả với tôi. Trái với việc thay thế giá trị của đầu vào, chỉ cần loại bỏ nó và hoàn toàn định vị một khoảng phía sau nó có cùng kích thước, khoảng đó có thể có một :beforelớp giả được áp dụng cho nó với phông chữ biểu tượng bạn chọn.

<style type="text/css">

form {position: relative; }
.mystyle:before {content:url(smiley.gif); width: 30px; height: 30px; position: absolute; }
.mystyle {color:red; width: 30px; height: 30px; z-index: 1; position: absolute; }
</style>

<form>
<input class="mystyle" type="text" value=""><span class="mystyle"></span>
</form>

1
+1 - Giải pháp này hoạt động tốt nếu bạn đang sử dụng plugin hoặc khung tự động thêm các lớp xác thực vào chính phần tử, nhưng không phải cho nhãn mẹ.
Blazemonger

9

Sự hiểu lầm lớn nhất ở đây là ý nghĩa của các từ beforeafter. Họ không đề cập đến chính yếu tố đó, mà đề cập đến nội dung trong thành phần đó. Vì vậy, element:beforetrước nội dung, và element:aftersau nội dung, nhưng cả hai vẫn ở bên trong yếu tố ban đầu.

Phần inputtử không có nội dung trong chế độ xem CSS và do đó không có :beforehoặc có :afternội dung giả. Điều này đúng với nhiều yếu tố khoảng trống hoặc thay thế khác.

Không có phần tử giả đề cập đến bên ngoài phần tử.

Trong một vũ trụ khác, những yếu tố giả này có thể đã được gọi là thứ khác để làm cho sự khác biệt này rõ ràng hơn. Và ai đó thậm chí có thể đã đề xuất một yếu tố giả thực sự nằm ngoài yếu tố đó. Cho đến nay, đây không phải là trường hợp trong vũ trụ này.


Tôi có thể không hiểu ý của bạn nhưng nếu tôi làm vậy, các phần tử giả hoạt động trên hr? jsfiddle.net/demetriad/o49yn5hq
Chris

1
@Chris Điều đó làm tôi ngạc nhiên, và khi tìm kiếm, với một số người khác. Tôi nghĩ đó là một sự ngớ ngẩn. hrluôn luôn mơ hồ từ quan điểm CSS, mặc dù bạn thấy điều đó nhiều hơn trong việc thảo luận về màu sắc.
Manngo

5

Theo một ghi chú trong thông số CSS 2.1, thông số kỹ thuật này không xác định đầy đủ sự tương tác của: trước và: sau với các yếu tố được thay thế (chẳng hạn như IMG trong HTML). Điều này sẽ được xác định chi tiết hơn trong một đặc điểm kỹ thuật trong tương lai. Mặc dù inputkhông thực sự là một yếu tố thay thế nữa, nhưng tình huống cơ bản đã không thay đổi: ảnh hưởng của :before:afterđối với nó trong không xác định và thường không có tác dụng.

Giải pháp là tìm một cách tiếp cận khác cho vấn đề bạn đang cố gắng giải quyết theo cách này. Đưa nội dung được tạo vào điều khiển nhập văn bản sẽ rất sai lệch: đối với người dùng, nó dường như là một phần của giá trị ban đầu trong điều khiển, nhưng nó không thể được sửa đổi - vì vậy nó dường như là một thứ bắt buộc khi bắt đầu kiểm soát, nhưng nó sẽ không được gửi như một phần của dữ liệu biểu mẫu.


3
Đây là một bình luận, không phải là một câu trả lời - một bình luận khá dài, nhưng dù sao cũng là một bình luận.
Blazemonger

@Blazemonger, không rõ câu hỏi là gì, nhưng trong mọi trường hợp, câu trả lời này giải quyết vấn đề tương tự như câu trả lời được chấp nhận, nhưng theo cách chính xác hơn. Không thể sử dụng nội dung được tạo cho inputcác thành phần, chỉ không xác định và tùy thuộc vào trình duyệt.
Jukka K. Korpela

5

Như những người khác đã giải thích, inputs là các phần tử void được thay thế, vì vậy hầu hết các trình duyệt sẽ không cho phép bạn tạo các phần tử giả ::beforecũng như ::aftergiả.

Tuy nhiên, Nhóm làm việc CSS đang xem xét cho phép rõ ràng ::before::aftertrong trường hợp inputappearance: none.

Từ https://lists.w3.org/Archives/Public/www-style/2016Mar/0190.html ,

Cả Safari và Chrome đều cho phép các phần tử giả trên đầu vào biểu mẫu của chúng. Các trình duyệt khác thì không. Chúng tôi đã xem xét loại bỏ điều này, nhưng bộ đếm sử dụng đang ghi ~ 0,07% số trang sử dụng nó, gấp 20 lần ngưỡng loại bỏ tối đa của chúng tôi.

Trên thực tế, việc chỉ định các phần tử giả trên các đầu vào sẽ yêu cầu chỉ định cấu trúc bên trong của các đầu vào ít nhất là phần nào, điều mà chúng ta chưa quản lý được (và tôi không tin rằng chúng ta * có thể * làm được). Nhưng Boris đề nghị, trong một trong những lỗi, cho phép nó xuất hiện: không có đầu vào nào - về cơ bản chỉ biến chúng thành các phần tử <div>, thay vì các yếu tố "thay thế".


4

thử tiếp theo:

label[for="userName"] {
  position: relative;
}

label[for="userName"]::after {
  content: '[after]';
  width: 22px;
  height: 22px;
  display: inline-block;
  position: absolute;
  right: -30px;
}
<label for="userName">
	Name: 
	<input type="text" name="userName" id="userName">
	</label>


3

Bạn phải có một số loại trình bao bọc xung quanh đầu vào để sử dụng phần tử giả trước hoặc sau. Đây là một câu đố có trước trên div trình bao bọc của một đầu vào và sau đó đặt trước vào bên trong đầu vào - hoặc ít nhất là nó trông giống như nó. Rõ ràng, đây là một công việc xung quanh nhưng hiệu quả trong một nhúm và cho vay để được đáp ứng. Bạn có thể dễ dàng thực hiện điều này sau nếu bạn cần đặt một số nội dung khác.

Fiddle làm việc

Ký hiệu đô la bên trong đầu vào dưới dạng phần tử giả: http://jsfiddle.net/kapunahele/ose4r8uj/1/

HTML:

<div class="test">
    <input type="text"></input>
</div>

CSS:

input {
    margin: 3em;
    padding-left: 2em;
    padding-top: 1em;
    padding-bottom: 1em;
    width:20%; 
}


.test {
    position: relative;
    background-color: #dedede;
    display: inline;
}

.test:before {
    content: '$';
    position: absolute;
    top: 0;
    left: 40px;
    z-index: 1;
}

Thủ thuật hay, nhưng bạn có thể tạo một div cách điệu để "tiếp tục" đầu vào. Xem fiddle jsfiddle.net/ose4r8uj/31 này nhưng bạn cũng có thể làm điều đó dễ dàng hơn bằng cách sử dụng bootstrap: getbootstrap.com/css/#forms-control-validation tìm phần "Với các biểu tượng tùy chọn". Mặc dù, điều này không liên quan gì đến câu hỏi ban đầu.
Victor Ivens

1
FYI không tốt cho: tập trung ,: di chuột, v.v. của đầu vào vì bạn không thể nhắm mục tiêu phần tử cha mẹ
jordanb

2

Nếu bạn đang cố gắng tạo kiểu cho một phần tử đầu vào bằng: trước và: sau, tỷ lệ cược là bạn đang cố gắng bắt chước các hiệu ứng của nhịp, div hoặc thậm chí là một phần tử trong ngăn xếp CSS của bạn.

Như câu trả lời của Robert Koritnik chỉ ra ,: trước và sau chỉ có thể được áp dụng cho các phần tử container và phần tử đầu vào không phải là vùng chứa.

TUY NHIÊN, HTML 5 đã giới thiệu phần tử nút là một thùng chứa và hoạt động giống như một phần tử [type = "submit | reset"].

    <style>
    .happy:after { content:url(smiley.gif); }
    </style>

    <form>
    <!-- won't work -->
    <input class="happy" type="submit" value="Submit" />

    <!-- works -->
    <button class="happy">Submit</button>
    </form>

HTML 4 thực sự đã giới thiệu phần tử <button>.
Ông Lister

1

Tóm lược

Nó không hoạt động với <input type="button">, nhưng nó hoạt động tốt với <input type="checkbox">.

Câu đố : http://jsfiddle.net/gb2wY/50/

HTML :

<p class="submit">
    <input id="submit-button" type="submit" value="Post">
    <br><br>
    <input id="submit-cb" type="checkbox" checked>
</p>

CSS :

#submit-button::before,
#submit-cb::before {
    content: ' ';
    background: transparent;
    border: 3px solid crimson;
    display: inline-block;
    width: 100%;
    height: 100%;
    padding: 0;
    margin: -3px -3px;
}

1

:before:afterchỉ hoạt động cho các nút có thể có các nút con vì chúng chèn một nút mới làm nút đầu tiên hoặc nút cuối cùng.


0

Tôi thấy rằng bạn có thể làm điều đó như thế này:

Bạn cần phải có cha mẹ div lấy phần đệm và: sau. Cha mẹ đầu tiên cần phải tương đối và div thứ hai phải tuyệt đối để bạn có thể đặt vị trí của sau.


-1

Tôi có một ý tưởng khác sử dụng điều này thay thế:

<div>
<input type="text"></input>text can be entered here</div>

Tác giả của câu hỏi tuyên bố rõ ràng rằng họ không thể thay đổi đánh dấu HTML. Câu trả lời này không có ý nghĩa. Có lẽ nó nên bị hạ cấp thay vì chỉnh sửa, @Morpheus.
Palec
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.