ควบคุมความยาวเส้นขอบเส้นประและระยะห่างระหว่างจังหวะ


124

เป็นไปได้ไหมที่จะควบคุมความยาวและระยะห่างระหว่างเส้นขอบเส้นประใน CSS

ตัวอย่างด้านล่างนี้แสดงแตกต่างกันระหว่างเบราว์เซอร์:

div {
  border: dashed 4px #000;
  padding: 20px;
  display: inline-block;
}
<div>I have a dashed border!</div>

ความแตกต่างใหญ่: IE 11 / Firefox / Chrome

เส้นขอบ IE 11Firefox Borderเส้นขอบ Chrome

มีวิธีการใดบ้างที่สามารถควบคุมลักษณะของเส้นขอบประ

คำตอบ:



157

ค่าคุณสมบัติเส้นขอบแบบเนทีฟไม่สามารถควบคุมขีดกลางได้เอง ... ดังนั้นนำborder-imageคุณสมบัตินี้มา!

ชงชายแดนของคุณเองด้วย border-image

ความเข้ากันได้ : ให้การสนับสนุนเบราว์เซอร์ที่ยอดเยี่ยม (IE 11 และเบราว์เซอร์ที่ทันสมัยทั้งหมด) เส้นขอบปกติสามารถตั้งค่าเป็นทางเลือกสำหรับเบราว์เซอร์รุ่นเก่าได้

มาสร้างสิ่งเหล่านี้

เส้นขอบเหล่านี้จะแสดงข้ามเบราว์เซอร์เดียวกันเป๊ะ!

ตัวอย่างเป้าหมาย ตัวอย่างเป้าหมายที่มีช่องว่างกว้างขึ้น

ขั้นตอนที่ 1 - สร้างภาพที่เหมาะสม

ตัวอย่างนี้กว้าง 15 พิกเซลสูง 15 พิกเซลและปัจจุบันช่องว่างกว้าง 5px เป็น. png ที่โปร่งใส

นี่คือสิ่งที่ดูเหมือนใน photoshop เมื่อซูมเข้า:

ตัวอย่างภาพพื้นหลังเส้นขอบปลิวขึ้น

นี่คือสิ่งที่ดูเหมือนว่าจะปรับขนาด:

ตัวอย่างภาพพื้นหลังเส้นขอบขนาดจริง

การควบคุมช่องว่างและระยะชัก

ในการสร้างช่องว่างหรือจังหวะที่กว้างขึ้น / สั้นลงให้ขยาย / ลดช่องว่างหรือเส้นขีดในภาพ

นี่คือภาพที่มีช่องว่างกว้าง 10px:

ช่องว่างที่ใหญ่ขึ้น ปรับขนาดอย่างถูกต้อง = ช่องว่างที่ใหญ่ขึ้นในการปรับขนาด

ขั้นตอนที่ 2 - สร้าง CSS - ตัวอย่างนี้ต้องใช้ขั้นตอนพื้นฐาน 4 ขั้นตอน

  1. กำหนดขอบภาพแหล่งที่มา :

    border-image-source:url("http://i.stack.imgur.com/wLdVc.png");  
  2. ทางเลือก - กำหนดเส้นขอบภาพกว้าง :

    border-image-width: 1;

    ค่าดีฟอลต์คือ 1 นอกจากนี้ยังสามารถตั้งค่าด้วยค่าพิกเซลค่าเปอร์เซ็นต์หรือเป็นค่าหลาย ๆ (1x, 2x, 3x เป็นต้น) สิ่งนี้จะแทนที่border-widthชุดใด ๆ

  3. กำหนดเส้นขอบภาพชิ้น :

    ในตัวอย่างนี้ความหนาของเส้นขอบด้านบนขวาล่างและด้านซ้ายคือ 2px และไม่มีช่องว่างด้านนอกดังนั้นค่าชิ้นของเราคือ 2:

    border-image-slice: 2; 

    ชิ้นจะมีลักษณะดังนี้ 2 พิกเซลจากด้านบนขวาล่างและซ้าย:

    ตัวอย่างชิ้น

  4. กำหนดเส้นขอบภาพซ้ำ :

    ในตัวอย่างนี้เราต้องการให้รูปแบบทำซ้ำรอบ div ของเราอย่างเท่าเทียมกัน ดังนั้นเราจึงเลือก:

    border-image-repeat: round;

การเขียนชวเลข

คุณสมบัติข้างต้นสามารถตั้งค่าทีละรายการหรือชวเลขโดยใช้border-image :

border-image: url("http://i.stack.imgur.com/wLdVc.png") 2 round;

ตัวอย่างที่สมบูรณ์

หมายเหตุทางborder: dashed 4px #000เลือก เบราว์เซอร์ที่ไม่รองรับจะได้รับเส้นขอบนี้

.bordered {
  display: inline-block;
  padding: 20px;
  /* Fallback dashed border
     - the 4px width here is overwritten with the border-image-width (if set)
     - the border-image-width can be omitted below if it is the same as the 4px here
  */
  border: dashed 4px #000;
  
  /* Individual border image properties */
  border-image-source: url("http://i.stack.imgur.com/wLdVc.png");
  border-image-slice: 2;
  border-image-repeat: round;  
  
  /* or use the shorthand border-image */
  border-image: url("http://i.stack.imgur.com/wLdVc.png") 2 round;
}


/*The border image of this one creates wider gaps*/
.largeGaps {
  border-image-source: url("http://i.stack.imgur.com/LKclP.png");
  margin: 0 20px;
}
<div class="bordered">This is bordered!</div>

<div class="bordered largeGaps">This is bordered and has larger gaps!</div>


โปรดทราบว่าคุณต้องระบุborder-style: solid(หรือสิ่งที่คล้ายกัน) หากคุณละเว้นทางเลือก
Robbendebiene

โซลูชันนี้ใช้ไม่ได้กับแอตทริบิวต์ "border-color"
Michael Rovinsky

102

นอกจากborder-imageคุณสมบัติแล้วยังมีวิธีอื่น ๆ อีกสองสามวิธีในการสร้างเส้นขอบประกับการควบคุมความยาวของเส้นขีดและระยะห่างระหว่างพวกเขา มีคำอธิบายด้านล่าง:

วิธีที่ 1: การใช้ SVG

เราสามารถสร้างเส้นประโดยใช้ a pathหรือpolygonองค์ประกอบและตั้งค่าstroke-dasharrayคุณสมบัติ คุณสมบัติรับพารามิเตอร์สองตัวโดยที่พารามิเตอร์หนึ่งกำหนดขนาดของเส้นประและอีกตัวกำหนดช่องว่างระหว่างพารามิเตอร์เหล่านั้น

ข้อดี:

  1. SVG โดยธรรมชาติเป็นกราฟิกที่ปรับขนาดได้และสามารถปรับให้เข้ากับขนาดคอนเทนเนอร์ใดก็ได้
  2. สามารถทำงานได้เป็นอย่างดีแม้ว่าจะมีborder-radiusส่วนเกี่ยวข้องก็ตาม เราจะแทนที่pathด้วยcirclelike ในคำตอบนี้ (หรือ) แปลงค่าpathเป็นวงกลม
  3. การรองรับเบราว์เซอร์สำหรับ SVGนั้นค่อนข้างดีและสามารถใช้ทางเลือกอื่นได้โดยใช้ VML สำหรับ IE8-

จุดด้อย:

  1. เมื่อขนาดของคอนเทนเนอร์ไม่เปลี่ยนแปลงตามสัดส่วนเส้นทางมักจะปรับขนาดส่งผลให้ขนาดของเส้นประและช่องว่างระหว่างทั้งคู่เปลี่ยนไป (ลองวางเมาส์ที่ช่องแรกในข้อมูลโค้ด) สิ่งนี้สามารถควบคุมได้โดยการเพิ่มvector-effect='non-scaling-stroke'(ดังในช่องที่สอง) แต่การรองรับเบราว์เซอร์สำหรับคุณสมบัตินี้ไม่มีใน IE


วิธีที่ 2: ใช้การไล่ระดับสี

เราสามารถใช้linear-gradientภาพพื้นหลังหลายภาพและวางตำแหน่งให้เหมาะสมเพื่อสร้างเอฟเฟกต์เส้นขอบแบบประ สิ่งนี้สามารถทำได้ด้วยrepeating-linear-gradientแต่ไม่มีการปรับปรุงมากนักเนื่องจากการใช้การไล่ระดับสีซ้ำเนื่องจากเราต้องการให้การไล่ระดับสีแต่ละครั้งทำซ้ำในทิศทางเดียวเท่านั้น

ข้อดี:

  1. ปรับขนาดได้และปรับเปลี่ยนได้แม้ว่าขนาดของคอนเทนเนอร์จะเป็นแบบไดนามิก
  2. ห้ามใช้ประโยชน์จากองค์ประกอบหลอกพิเศษใด ๆ ซึ่งหมายความว่าสามารถเก็บไว้เพื่อการใช้งานอื่น ๆ ที่เป็นไปได้

จุดด้อย:

  1. การสนับสนุนเบราว์เซอร์สำหรับการไล่ระดับสีเชิงเส้นนั้นค่อนข้างต่ำกว่าและนี่ไม่ใช่เรื่องง่ายหากคุณต้องการรองรับ IE 9- แม้แต่ไลบรารีเช่น CSS3 PIE ก็ไม่รองรับการสร้างรูปแบบการไล่ระดับสีใน IE8-
  2. ไม่สามารถนำมาใช้เมื่อมีส่วนเกี่ยวข้องเพราะภูมิหลังที่ไม่ได้อยู่บนพื้นฐานของเส้นโค้งborder-radius border-radiusพวกเขาถูกตัดแทน

วิธีที่ 3: Box Shadows

เราสามารถสร้างแถบเล็ก ๆ (ในรูปของเส้นประ) โดยใช้องค์ประกอบหลอกจากนั้นสร้างหลาย ๆbox-shadowเวอร์ชันเพื่อสร้างเส้นขอบเหมือนในตัวอย่างด้านล่าง

หากเส้นประเป็นรูปทรงสี่เหลี่ยมองค์ประกอบหลอกเพียงชิ้นเดียวก็เพียงพอแล้ว แต่ถ้าเป็นรูปสี่เหลี่ยมผืนผ้าเราจะต้องมีองค์ประกอบหลอกหนึ่งชิ้นสำหรับเส้นขอบบน + ล่างและอีกชิ้นหนึ่งสำหรับเส้นขอบซ้าย + ขวา เนื่องจากความสูงและความกว้างของเส้นประบนเส้นขอบด้านบนจะแตกต่างจากทางด้านซ้าย

ข้อดี:

  1. ขนาดของเส้นประสามารถควบคุมได้โดยการเปลี่ยนขนาดขององค์ประกอบหลอก ระยะห่างสามารถควบคุมได้โดยการปรับเปลี่ยนช่องว่างระหว่างแต่ละเงา
  2. สามารถสร้างเอฟเฟกต์ที่ไม่เหมือนใครได้โดยการเพิ่มสีที่แตกต่างกันสำหรับแต่ละเงาของกล่อง

จุดด้อย:

  1. เนื่องจากเราต้องกำหนดขนาดของเส้นประและระยะห่างด้วยตนเองวิธีนี้จึงไม่ดีเมื่อมิติของกล่องหลักเป็นแบบไดนามิก
  2. IE8 และลดไม่สนับสนุนเงากล่อง อย่างไรก็ตามสิ่งนี้สามารถเอาชนะได้โดยใช้ไลบรารีเช่น CSS3 PIE
  3. สามารถใช้ได้border-radiusแต่การวางตำแหน่งจะยุ่งยากมากเมื่อต้องหาจุดบนวงกลม (และอาจเป็นได้transform)


หากคุณจะใช้โซลูชัน svg ฉันแนะนำให้เพิ่มpointer-events:nonesvg inorder เพื่อให้สามารถโต้ตอบกับเนื้อหาได้
Sodj

คำตอบมหัศจรรย์
Deviance

22

สั้น ๆ : ไม่มันไม่ใช่ คุณจะต้องทำงานกับรูปภาพแทน


5
คำตอบนี้ล้าสมัยในปี 2018
godblessstrawberry

2
@WilliamHampshire ฉันจะใช้เทคนิคนี้youtu.be/vs34f9FiHps?t=779แต่ตรวจสอบคำตอบที่ยอมรับคุณอาจชอบโซลูชันอื่นที่ดีกว่า
godblessstrawberry

1
@godblessstrawberry ขอบคุณ !! แต่นั่นใช้ SVG จึงยังไม่ใช้แค่ css ...
Kyle Krzeski

1
@WilliamHampshire มีวิธีแก้ปัญหากล่องเงาในกระทู้ที่ฉันหมายถึงคำตอบโดยแฮร์รี่
godblessstrawberry

@godblessstrawberry ลองแก้แล้วหรือยัง? วิธีแก้ปัญหาวาดส่วนของเส้นประตามส่วน เป็นเพียง POC และไร้ประโยชน์ในทางปฏิบัติ!
Yu Jianrong

6

มีเครื่องมือที่เย็นที่ทำโดยเป็น@kovartเรียกว่ากำเนิดประชายแดน

ใช้ svg เป็นภาพพื้นหลังเพื่อให้สามารถตั้งค่าอาร์เรย์เส้นประจังหวะที่คุณต้องการและค่อนข้างสะดวก

จากนั้นคุณจะใช้มันเป็นคุณสมบัติพื้นหลังขององค์ประกอบของคุณแทนเส้นขอบ:

div {
  background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' stroke='black' stroke-width='4' stroke-dasharray='6%2c 14' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e");
  padding: 20px;
  display: inline-block;
}

นี่เป็นวิธีแก้ปัญหาที่ง่ายสะดวกและรวดเร็ว
jamesioppolo

มันทำงานได้ดี!
Kevin Raffay

3

ระยะชักขึ้นอยู่กับความกว้างของจังหวะ คุณสามารถเพิ่มความยาวได้โดยเพิ่มความกว้างและซ่อนส่วนของเส้นขอบตามองค์ประกอบด้านใน

.thin {
    background: #F4FFF3;
    border: 2px dashed #3FA535;  
    position: relative;
}

.thin:after {
    content: '';
    position: absolute;
    left: -1px;
    top: -1px;
    right: -1px;
    bottom: -1px;
    border: 1px solid #F4FFF3;
}

https://jsfiddle.net/ok6srt2z/


แต่ด้วยวิธีนี้คุณจะไม่สามารถคลิกเนื้อหาขององค์ประกอบดั้งเดิมได้เนื่องจาก pseudoelement "after" จะปิดทับ ดังนั้นวิธีที่ดีที่สุดคือใช้ SVG
ili4

คุณสามารถเพิ่มpointer-events: noneเพื่อป้องกันปัญหาการซ้อนทับ
benJ

0

ฉันเพิ่งมีปัญหาเดียวกันเมื่อไม่นานมานี้

ฉันจัดการเพื่อแก้ปัญหาด้วย div สองตำแหน่งที่มีเส้นขอบ (อันหนึ่งสำหรับแนวนอนและอีกอันสำหรับแนวตั้ง) จากนั้นจึงเปลี่ยนมัน กล่องด้านนอกจะต้องอยู่ในตำแหน่งที่ค่อนข้างเหมาะสม

<div class="relative">
    <div class="absolute absolute--fill overflow-hidden">
        <div class="absolute absolute--fill b--dashed b--red"
            style="
                border-width: 4px 0px 4px 0px;
                transform: scaleX(2);
        "></div>
        <div class="absolute absolute--fill b--dashed b--red"
            style="
                border-width: 0px 4px 0px 4px;
                transform: scaleY(2);
        "></div>
    </div>

    <div> {{Box content goes here}} </div>
</div>

หมายเหตุ: ฉันใช้ tachyons ในตัวอย่างนี้ แต่ฉันเดาว่าชั้นเรียนเป็นแบบที่อธิบายตัวเองได้


-1

สิ่งนี้จะสร้างเส้นขอบสีส้มและสีเทาโดยใช้ class = "myclass" บน div

.myclass {
    outline:dashed darkorange  12px;
    border:solid slategray  14px;
    outline-offset:-14px;
}

ด้วยการ "ให้การควบคุมลักษณะเส้นประ" OP (โปสเตอร์ต้นฉบับ) หมายความว่าเขาต้องการควบคุมความยาวของแต่ละขีดตามที่ระบุไว้ตอนต้นของคำถาม ขออภัยในความสับสน
Skylar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.