ปัญหาเกี่ยวกับ <select> และ: after with CSS ใน WebKit


124

ฉันต้องการเพิ่มสไตล์บางอย่างในกล่องเลือกด้วยหลอก: หลัง (เพื่อจัดสไตล์กล่องเลือกของฉันด้วย 2 ส่วนและไม่มีภาพ) นี่คือ HTML:

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

และไม่ได้ผล ฉันไม่รู้ว่าทำไมและฉันไม่พบคำตอบในข้อกำหนด W3C นี่คือ 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;
}

จึงเป็นเรื่องปกติหรือมีอุบาย?


ฉันคิดว่าสิ่งนี้จะไม่ควรเป็นไปไม่ได้มิฉะนั้นจะทำให้ง่ายเกินไปที่จะเปลี่ยนเนื้อหาของแบบฟอร์ม ลองนึกภาพง่ายๆของ CSS ที่เปลี่ยนราคาที่แสดงสำหรับบางสิ่ง อาจแสดงได้ว่าถูกกว่าที่เป็นจริงโดยหลอกให้คนซื้อของในราคาที่มากกว่าที่พวกเขาคาดไว้ (หรือแน่นอนถ้ามีคนเข้าถึง CSS ของเพจ / userstylesheet พวกเขาก็อาจทำเช่นเดียวกันในรูปแบบอื่น…)
Synetech

22
@Synetech - สิ่งนี้ไม่ถูกต้องผู้เขียนเพจควรมีอำนาจควบคุมการจัดรูปแบบหน้าได้อย่างสมบูรณ์ ผู้ผลิตเบราว์เซอร์ที่พยายามป้องกันการจัดรูปแบบขององค์ประกอบบางอย่างเนื่องจากอาจใช้เพื่อทำให้ผู้ใช้เข้าใจผิดจะไม่ได้ผลเนื่องจากมีวิธีการหลอกล่อระบบหรือสร้างผลบวกที่ผิดพลาดได้ไม่ จำกัด
Jonathan Cross

คำตอบ:


133

ฉันไม่ได้ตรวจสอบสิ่งนี้อย่างละเอียด แต่ฉันรู้สึกว่าสิ่งนี้ยังไม่เป็นไปได้ (ยัง?) เนื่องจากวิธีการselectสร้างองค์ประกอบโดยระบบปฏิบัติการที่เบราว์เซอร์ทำงานแทนที่จะเป็นเบราว์เซอร์เอง


63
ตอนนี้เป็นปี 2019 และก็ยังเหมือนเดิม
Placido

41
ตอนนี้เป็นปี 2020 และก็ยังเหมือนเดิม
Joeri Minnekeer

3
ถ้าฉันเห็นความคิดเห็นของคุณในโพสต์เก่า ๆ เมื่อ 10 ปีที่แล้วฉันจะช่วยตัวเองได้หนึ่งชั่วโมง : C
ericek111

66

ฉันกำลังมองหาสิ่งเดียวกันเนื่องจากพื้นหลังของการเลือกของฉันเหมือนกับสีลูกศร ตามที่กล่าวไว้ก่อนหน้านี้ยังไม่สามารถเพิ่มสิ่งใดโดยใช้: before หรือ: after ในองค์ประกอบที่เลือกได้ วิธีแก้ปัญหาของฉันคือสร้างองค์ประกอบ Wrapper ซึ่งฉันได้เพิ่มสิ่งต่อไปนี้: ก่อนโค้ด

.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;
}

และนี่คือสิ่งที่ฉันเลือก

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;
}

ฉันใช้ FontAwesome.io สำหรับลูกศรใหม่ของฉันแล้ว แต่คุณสามารถใช้อะไรก็ได้ที่คุณต้องการ เห็นได้ชัดว่านี่ไม่ใช่วิธีแก้ปัญหาที่สมบูรณ์แบบ แต่ขึ้นอยู่กับความต้องการของคุณอาจเพียงพอ


4
นี่เป็นภาพที่สมบูรณ์แบบ แต่คุณไม่สามารถคลิกผ่านไอคอนนั้นและเลือกองค์ประกอบโดยไม่เปิด: / ข้อเสนอแนะใด ๆ ?
Schovi

11
ตัวชี้เหตุการณ์: ไม่มี; ควรดูแลสิ่งนั้น มีปัญหากับรหัสของฉันด้านบน ฉันจะเปลี่ยน sass ด้านบนเป็น css เพื่อลบความสับสน
sroy

ตัวเลือกหลอก (before vs after) ถูกใช้หรือไม่?
eddiegroves

คุณสามารถใช้อย่างใดอย่างหนึ่ง
sroy

2
นี่เป็นวิธีแก้ปัญหาที่ยอดเยี่ยม แต่เมื่อนำไปใช้ฉันพบว่าด้วยเหตุผลบางประการ: ก่อนทำงานและไม่: หลัง ฉันไม่รู้ว่าทำไม
Lee Probert

32

จากประสบการณ์ของฉันมันไม่ได้ผลเว้นแต่คุณจะเต็มใจห่อของคุณ<select>ด้วยกระดาษห่อหุ้ม แต่สิ่งที่คุณทำได้คือใช้ SVG ภาพพื้นหลัง เช่น

    .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;
    }

ระวังด้วยการเข้ารหัส URL ที่เหมาะสมเนื่องจาก IE คุณต้องใช้charset=utf8(ไม่ใช่แค่utf8) อย่าใช้เครื่องหมายอัญประกาศคู่ (") เพื่อคั่นค่าแอตทริบิวต์ SVG ใช้เครื่องหมายวรรคตอน (') แทนเพื่อทำให้ชีวิตของคุณง่ายขึ้น URL-encode s (% 3E) ในกรณีที่คุณต้องพิมพ์ อักขระที่ไม่ใช่ ASCII ใด ๆ ที่คุณต้องได้รับการแสดง UTF-8 (เช่น BabelMap สามารถช่วยคุณได้) จากนั้นให้การแทนค่านั้นในรูปแบบที่เข้ารหัส URL - เช่นสำหรับ▾ ( U+25BEBLACK DOWN-POINTING SMALL TRIANGLE) การแสดง UTF-8 คือ\xE2\x96\xBEซึ่งเป็น%E2%96%BEตอนที่เข้ารหัส URL


1
นี่เป็นทางออกที่ดีและสวยงาม
JosFabre

1
นี่เป็นโซลูชันที่ยอดเยี่ยมเรียบง่ายและสวยงามโดยไม่ต้องใช้ HTML เพิ่มเติมซึ่งเป็นสิ่งที่ฉันกำลังมองหา! ขอบคุณ! นี่ควรเป็นคำตอบ IMO ที่เลือก
KyleFarris


13

ประสบปัญหาเดียวกัน. อาจเป็นวิธีแก้ปัญหา:

<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 {
    ...
}

คุณสามารถเพิ่มสไตล์ที่จำเป็นเพื่อให้ป้ายกำกับอยู่ด้านบนขององค์ประกอบที่เลือกได้หรือไม่
bafromca

7

โซลูชันนี้คล้ายกับจาก sroy แต่มีรูปสามเหลี่ยม css แทนแบบอักษรของเว็บ:

.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

จะเกิดอะไรขึ้นหากการปรับเปลี่ยนมาร์กอัปไม่ใช่ตัวเลือก

นี่คือวิธีแก้ปัญหาที่ไม่มีข้อกำหนดสำหรับกระดาษห่อหุ้ม: ใช้ SVG ในภาพพื้นหลัง คุณอาจต้องใช้ตัวถอดรหัสเอนทิตี HTMLเพื่อทำความเข้าใจวิธีเปลี่ยนสีเติม

-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;

Pinched จากCSS-เคล็ดลับ


นี่เป็นเคล็ดลับที่ดี น่ารำคาญสุด ๆ ที่เรายังเลือกสไตล์ไม่ได้ในปี 2020
ramijames

5

นี่เป็นวิธีแก้ปัญหาสมัยใหม่ที่ฉันปรุงขึ้นโดยใช้ฟอนต์ที่ยอดเยี่ยม ส่วนขยายผู้ให้บริการถูกละเว้นเพื่อความกะทัดรัด

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;
            }
        }
    }

หากองค์ประกอบที่คุณเลือกมีสีพื้นหลังที่กำหนดไว้สิ่งนี้จะไม่ทำงานเนื่องจากข้อมูลโค้ดนี้จะวางไอคอนเชฟรอนไว้ด้านหลังองค์ประกอบที่เลือกเป็นหลัก (เพื่อให้การคลิกที่ด้านบนของไอคอนยังคงเริ่มต้นการกระทำที่เลือกได้)

อย่างไรก็ตามคุณสามารถกำหนดรูปแบบของกระดาษห่อเลือกให้มีขนาดเท่ากับองค์ประกอบที่เลือกและจัดรูปแบบพื้นหลังเพื่อให้ได้เอฟเฟกต์เดียวกัน

ตรวจสอบCodePenของฉันเพื่อดูการสาธิตที่ใช้งานได้ซึ่งแสดงบิตของโค้ดนี้ทั้งในกล่องเลือกที่มีธีมสีเข้มและสีอ่อนโดยใช้ป้ายกำกับปกติและป้ายกำกับ "ตัวยึดตำแหน่ง" และรูปแบบอื่น ๆ ที่ล้างข้อมูลเช่นเส้นขอบและความกว้าง

ปล. นี่คือคำตอบที่ฉันเคยโพสต์ไปยังอีกคำถามที่ซ้ำกันเมื่อต้นปีนี้


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>

ในการกำหนดรูปแบบการเลือกเหตุใดคุณจึงไม่เพิ่ม div ด้านนอกที่เลือก

และสไตล์จากนั้นใน 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;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.