sự cố với <select> và: after với CSS trong WebKit


123

Tôi muốn thêm một số kiểu trên hộp chọn với giả: sau (để tạo kiểu cho hộp chọn của tôi có 2 phần và không có hình ảnh). Đây là HTML:

<select name="">
  <option value="">Test</option>
</select>

Và nó không hoạt động. Tôi không biết tại sao và tôi không tìm thấy câu trả lời trong thông số kỹ thuật của W3C. Đây là CSS:

select {
  -webkit-appearance: none;
  background: black;
  border: none;
  border-radius: 0;
  color: white;
}

select:after {
  content: " ";
  display: inline-block;
  width: 24px; height: 24px;
  background: blue;
}

Như vậy là bình thường hay là bị lừa vậy?


Tôi tưởng tượng rằng điều này sẽ không, không nên có, nếu không, nó sẽ làm cho việc thay đổi nội dung của biểu mẫu trở nên quá dễ dàng. Hãy tưởng tượng một chút CSS đơn giản thay đổi giá hiển thị cho một thứ gì đó. Nó có thể được chứng minh là rẻ hơn thực tế, lừa mọi người mua thứ gì đó với giá cao hơn mức họ mong đợi. (Hoặc Tất nhiên, nếu ai đó có quyền truy cập vào CSS của một trang / userstylesheet, sau đó họ có thể có thể làm tương tự bằng cách khác ...)
Synetech

22
@Synetech - Điều này không chính xác, tác giả của trang phải có toàn quyền kiểm soát tất cả các khía cạnh của việc tạo kiểu trang. Các nhà sản xuất trình duyệt cố gắng ngăn chặn việc tạo kiểu của một số phần tử nhất định vì chúng có thể được sử dụng để đánh lừa người dùng sẽ không hiệu quả vì có gần như vô hạn cách để đánh lừa hệ thống hoặc tạo ra kết quả dương tính giả.
Jonathan Cross

1
Có thể trùng lặp của các yếu tố giả và SELECT thẻ
Tessa

Câu trả lời:


132

Tôi chưa kiểm tra kỹ điều này, nhưng tôi có ấn tượng rằng điều này chưa (?) Khả thi, do cách selectcác phần tử được tạo bởi hệ điều hành mà trình duyệt chạy, chứ không phải chính trình duyệt.


62
Bây giờ là năm 2019 và nó vẫn vậy
Placido

40
Bây giờ là năm 2020 và nó vẫn vậy
Joeri Minnekeer

3
Nếu tôi nhìn thấy bình luận của bạn về bài đăng 10 năm tuổi này một giờ trước, tôi sẽ tiết kiệm cho mình một giờ thời gian. : C
ericek111

66

Tôi đang tìm kiếm thứ tương tự vì nền của lựa chọn của tôi giống với màu mũi tên. Như đã đề cập trước đó, không thể thêm bất cứ thứ gì bằng cách sử dụng: before hoặc: after trên một phần tử được chọn. Giải pháp của tôi là tạo một phần tử trình bao bọc mà tôi đã thêm phần sau: trước mã.

.select-wrapper {
    position: relative;
}

.select-wrapper:before {
    content: '\f0d7';
    font-family: FontAwesome;
    color: #fff;
    display: inline-block;
    position: absolute;
    right: 20px;
    top: 15px;
    pointer-events: none;
}

Và đây là lựa chọn của tôi

select {
    box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    width: 100%;
    padding: 10px 20px;
    background: #000;
    color: #fff;
    border: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}

select::-ms-expand {
    display: none;
}

Tôi đã sử dụng FontAwesome.io cho mũi tên mới của mình, nhưng bạn có thể sử dụng bất kỳ thứ gì khác mà bạn muốn. Rõ ràng đây không phải là một giải pháp hoàn hảo, nhưng tùy thuộc vào nhu cầu của bạn, nó có thể là đủ.


4
Điều này là hoàn hảo về mặt trực quan. Nhưng bạn không thể nhấp qua biểu tượng đó và chọn phần tử sẽ không mở: / Có đề xuất nào không?
Schovi

11
sự kiện con trỏ: không có; nên chăm sóc điều đó. Đã xảy ra sự cố với mã của tôi ở trên. Tôi sẽ thay đổi bất kỳ sass nào ở trên thành css để loại bỏ bất kỳ sự nhầm lẫn nào.
sroy

Có vấn đề là bộ chọn giả (trước và sau) được sử dụng không?
eddiegroves

Bạn có thể sử dụng cái này hoặc cái kia
sroy

2
Đây là một giải pháp tuyệt vời nhưng khi thực hiện nó, tôi thấy rằng vì một số lý do: trước khi làm việc và KHÔNG: sau khi. Tôi không biết tại sao.
Lee Probert

32

Theo kinh nghiệm của tôi, nó chỉ đơn giản là không hoạt động, trừ khi bạn sẵn sàng bọc của bạn <select>trong một cái gì đó. Nhưng những gì bạn có thể làm thay vào đó là sử dụng SVG hình nền. Ví dụ

    .archive .options select.opt {
    -moz-appearance: none;
    -webkit-appearance: none;
    padding-right: 1.25EM;
    appearance: none;
    position: relative;
    background-color: transparent;
    background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' height='10px' width='15px'%3E%3Ctext x='0' y='10' fill='gray'%3E%E2%96%BE%3C/text%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-size: 1.5EM 1EM;
    background-position: right center;
    background-clip: border-box;
    -moz-background-clip: border-box;
    -webkit-background-clip: border-box;
}

    .archive .options select.opt::-ms-expand {
        display: none;
    }

Chỉ cần cẩn thận với mã hóa URL thích hợp vì IE. Bạn phải sử dụng charset=utf8(không chỉ utf8), không sử dụng dấu ngoặc kép (") để phân tách các giá trị thuộc tính SVG, thay vào đó hãy sử dụng dấu nháy đơn (') để đơn giản hóa cuộc sống của bạn. Mã hóa URL (% 3E). Trong trường hợp bạn phải in bất kỳ ký tự nào không phải ASCII mà bạn phải có được biểu diễn UTF-8 của chúng (ví dụ: BabelMap có thể giúp bạn điều đó) và sau đó cung cấp biểu diễn đó ở dạng được mã hóa URL - ví dụ: đối với ▾ ( U+25BETAM GIÁC NHỎ XUỐNG ĐIỂM ĐEN) Biểu diễn UTF-8 là \xE2\x96\xBEđó là %E2%96%BEkhi được mã hóa URL.


1
Đây là một giải pháp tốt đẹp và thanh lịch
JosFabre

1
Đây là một giải pháp tuyệt vời, đơn giản và thanh lịch mà không cần thêm HTML, chính xác là những gì tôi đang tìm kiếm! Cảm ơn! Đây phải là câu trả lời được chọn IMO.
KyleFarris,


13

Đối mặt với cùng một vấn đề. Có lẽ nó có thể là một giải pháp:

<select id="select-1">
    <option>One</option>
    <option>Two</option>
    <option>Three</option>
</select>
<label for="select-1"></label>

#select-1 {
    ...
}

#select-1 + label:after {
    ...
}

Bạn có thể thêm các kiểu bắt buộc để làm cho nhãn nằm trên phần tử được chọn không?
bafromca

7

Giải pháp này tương tự như giải pháp từ sroy, nhưng với tam giác css thay vì phông chữ web:

.select-wrapper {
  position: relative;
  width: 200px;
}
.select-wrapper:after {
  content: "";
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid #666;
  position: absolute;
  right: 8px;
  top: 8px;
  pointer-events: none;
}
select {
  background: #eee;
  border: 0 !important;
  border-radius: 0;
  -webkit-appearance:none;
  -moz-appearance:none;
  appearance:none;
  text-indent: 0.01px;
  text-overflow: "";
  font-size: inherit;
  line-height: inherit;
  width: 100%;
}
select::-ms-expand {
  display: none;
}
<div class="select-wrapper">
  <select>
    <option value="1">option 1</option>
    <option value="2">option 2</option>
    <option value="3">option 3</option>
  </select>
</div>


6

Điều gì sẽ xảy ra nếu việc sửa đổi đánh dấu không phải là một tùy chọn?

Đây là một giải pháp không có yêu cầu đối với trình bao bọc: nó sử dụng SVG trong hình nền. Bạn có thể cần sử dụng bộ giải mã thực thể HTML để hiểu cách thay đổi màu tô.

-moz-appearance: none;
-webkit-appearance: none;
appearance: none;

background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23000000%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E');
background-repeat: no-repeat;
background-position: right .7em top 50%;
background-size: .65em auto;

Được chèn từ CSS-Tricks .


Đây là một thủ thuật hay.
Thật

5

Đây là một giải pháp hiện đại mà tôi đã tạo ra bằng cách sử dụng font-awesome . Tiện ích mở rộng nhà cung cấp đã bị bỏ qua cho ngắn gọn.

HTML

<fieldset>
    <label for="color">Select Color</label>
    <div class="select-wrapper">
        <select id="color">
            <option>Red</option>
            <option>Blue</option>
            <option>Yellow</option>
        </select>
        <i class="fa fa-chevron-down"></i>
    </div>
</fieldset>

SCSS

fieldset {
    .select-wrapper {
        position: relative;

        select {
            appearance: none;
            position: relative;
            z-index: 1;
            background: transparent;

            + i {
                position: absolute;
                top: 40%;
                right: 15px;
            }
        }
    }

Nếu phần tử được chọn của bạn có màu nền xác định, thì điều này sẽ không hoạt động vì đoạn mã này về cơ bản đặt biểu tượng Chevron phía sau phần tử được chọn (để cho phép nhấp vào trên cùng của biểu tượng để vẫn bắt đầu hành động chọn).

Tuy nhiên, bạn có thể tạo kiểu cho select-wrapper có cùng kích thước với phần tử được chọn và tạo kiểu cho nền của nó để đạt được hiệu ứng tương tự.

Hãy xem CodePen của tôi để biết bản trình diễn đang hoạt động hiển thị đoạn mã này trên cả hộp chọn theo chủ đề tối và sáng bằng cách sử dụng nhãn thông thường và nhãn "trình giữ chỗ" và các kiểu đã làm sạch khác như đường viền và chiều rộng.

Tái bút Đây là một câu trả lời tôi đã đăng cho một câu hỏi khác, trùng lặp vào đầu năm nay.


1
<div class="select">
<select name="you_are" id="dropdown" class="selection">
<option value="0" disabled selected>Select</option>
<option value="1">Student</option>
<option value="2">Full-time Job</option>
<option value="2">Part-time Job</option>
<option value="3">Job-Seeker</option>
<option value="4">Nothing Yet</option>
</select>
</div>

Chèn tạo kiểu cho lựa chọn tại sao bạn không thêm một div bên ngoài vùng chọn.

và tạo kiểu sau đó trong CSS

.select{
    width: 100%;
    height: 45px;
    position: relative;
}
.select::after{
    content: '\f0d7';
    position: absolute;
    top: 0px;
    right: 10px;
    font-family: 'Font Awesome 5 Free';
    font-weight: 900;
    color: #0b660b;
    font-size: 45px;
    z-index: 2;

}
#dropdown{
    -webkit-appearance: button;
       -moz-appearance: button;
            appearance: button;
            height: 45px;
            width: 100%;
        outline: none;
        border: none;
        border-bottom: 2px solid #0b660b;
        font-size: 20px;
        background-color: #0b660b23;
        box-sizing: border-box;
        padding-left: 10px;
        padding-right: 10px;
}
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.