SVG ไล่ระดับโดยใช้ CSS


105

ฉันกำลังพยายามนำการไล่ระดับสีไปใช้กับrectองค์ประกอบSVG

ขณะนี้ฉันใช้fillแอตทริบิวต์ ในไฟล์ CSS ของฉัน:

rect {
    cursor: pointer;
    shape-rendering: crispEdges;
    fill: #a71a2e;
}

และrectองค์ประกอบมีสีเติมที่ถูกต้องเมื่อดูในเบราว์เซอร์

อย่างไรก็ตามฉันต้องการทราบว่าฉันสามารถใช้การไล่ระดับสีเชิงเส้นกับองค์ประกอบนี้ได้หรือไม่

คำตอบ:


99

เพียงใช้ใน CSS สิ่งที่คุณจะใช้ในfillแอตทริบิวต์ แน่นอนว่าคุณต้องกำหนดการไล่ระดับสีเชิงเส้นไว้ที่ใดที่หนึ่งใน SVG ของคุณ

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

rect {
    cursor: pointer;
    shape-rendering: crispEdges;
    fill: url(#MyGradient);
}
<svg width="100" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
      <style type="text/css">
        rect{fill:url(#MyGradient)}
      </style>
      <defs>
        <linearGradient id="MyGradient">
          <stop offset="5%" stop-color="#F60" />
          <stop offset="95%" stop-color="#FF6" />
        </linearGradient>
      </defs>
      
      <rect width="100" height="50"/>
    </svg>


2
ดังนั้นฉันจึงสร้างการไล่ระดับสีนั้นในไฟล์แยกต่างหากและใช้fillวิธีนี้: fill: url(../js/gradient.svg#MyGradient);. เป็นวิธีที่ถูกต้องหรือไม่?
Hrishikesh Choudhari

@HrishikeshChoudhari: ใช่นี่ถูกต้อง แต่ Chrome และฉันคิดว่า Safari เช่นกันไม่รองรับการอ้างอิงองค์ประกอบจากไฟล์อื่น ไม่แน่ใจเกี่ยวกับ IE9 (ไม่สามารถทดสอบได้ในขณะนี้ลองดู)
Thomas W

54
สำหรับทุกคนที่อ่านข้อความนี้และถามว่าfill: linear-gradient (...)"แล้ว" fillต้องการสิ่ง<paint>ที่สร้างขึ้นจาก<color>คลาสCSS2 กล่าวอีกนัยหนึ่งคำตอบนี้เป็นวิธีเดียวที่จะทำได้ผ่าน CSS ในขณะที่ฉันเขียนความคิดเห็นนี้ คุณต้องเพิ่มlinearGradientองค์ประกอบ สุดท้ายเมื่อดำเนินการผ่าน w3 Working Draft สำหรับSVG2ดูเหมือนว่าการสนับสนุนสำหรับlinear-gradientกฎการเติม css ไม่มีและอาจไม่ทำให้เป็นข้อมูลจำเพาะ
Arthur Weborg

จะเปลี่ยนทิศทางอย่างไรในกรณีนี้?
AGamePlayer

1
@AwQiruiGuo ดูMDN (โดยเฉพาะgradientTransformแอตทริบิวต์)
Thomas W

37

2019 คำตอบ

ด้วยคุณสมบัติ css ใหม่ล่าสุดคุณสามารถมีความยืดหยุ่นมากยิ่งขึ้นด้วยตัวแปรที่เรียกว่า custom properties

.shape {
  width:500px;
  height:200px;
}

.shape .gradient-bg {
  fill: url(#header-shape-gradient) #fff;
}

#header-shape-gradient {
  --color-stop: #f12c06;
  --color-bot: #faed34;
}
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" class="shape">
  <defs>
    <linearGradient id="header-shape-gradient" x2="0.35" y2="1">
        <stop offset="0%" stop-color="var(--color-stop)" />
        <stop offset="30%" stop-color="var(--color-stop)" />
        <stop offset="100%" stop-color="var(--color-bot)" />
      </linearGradient>
  </defs>
  <g>
    <polygon class="gradient-bg" points="0,0 100,0 0,66" />
  </g>
</svg>

เพียงตั้งชื่อตัวแปรสำหรับแต่ละตัวstopไล่ระดับสีแล้วปรับแต่งตามที่คุณต้องการใน css คุณยังสามารถเปลี่ยนค่าแบบไดนามิกด้วยจาวาสคริปต์เช่น:

document.querySelector('#header-shape-gradient').style.setProperty('--color-stop', "#f5f7f9");

3
ไม่รองรับใน IE
aoakeson

3
คุณสมบัติที่กำหนดเองของ CSS อยู่ที่นี่เป็นเวลานานมากหากมีคนยังไม่พร้อมที่จะใช้งานคุณสมบัติเหล่านี้เขาก็จะไม่พร้อมสำหรับการเปลี่ยนแปลง
Maciej Kwas

2
@MaciejKwas คุณคิดผิด เบราว์เซอร์เก่าจะไม่อยู่ตลอดไปดังนั้น บริษัท ที่ยังไม่พร้อมในตอนนี้ก็พร้อม และถ้าใครไม่พร้อมที่จะละทิ้งผู้ชมบางส่วนก็ไม่ได้หมายความว่าเขายังไม่พร้อมสำหรับการเปลี่ยนแปลงนั่นหมายความว่าเขาชอบที่จะใช้ประโยชน์จากการเปลี่ยนแปลงในภายหลังเพื่อรักษาผู้ชมจำนวนมากขึ้น
กลเม็ดเด็ดพราย

22
@aoakeson IE ตายแล้ว สิ้นสุดอายุการใช้งาน Edge ก็กำลังจะตายนี่คือคำตอบในปี 2019 ดังนั้น IE จึงไม่ควรนับ IE สามารถย่อยสลายได้อย่างสวยงามโดยใช้สีทึบ
Ciprian

5
@aoakeson ฉันประหลาดใจที่น่าอัศจรรย์ใจที่จะเจอชนิดของการตอบสนองใน 2019 ที่คุณต้องการจะไร้เดียงสาเป็นนักพัฒนาที่จะถือว่าการสนับสนุน SVG ใน IE ในระดับนี้จะเคยได้รับการสนับสนุนให้คนเดียวนักพัฒนารุ่นที่ดังนั้นให้คุณป่อง คำตอบแบบ polyfilled สำหรับบางสิ่งที่จำเป็นโดยไม่จำเป็นหากคุณตั้งใจจะสนับสนุน IE
James Martin-Davies

21

จากสิ่งที่ Finesse เขียนไว้นี่เป็นวิธีที่ง่ายกว่าในการกำหนดเป้าหมาย svg และเปลี่ยนการไล่ระดับสี

นี่คือสิ่งที่คุณต้องทำ:

  1. กำหนดคลาสให้กับแต่ละสีหยุดที่กำหนดไว้ในองค์ประกอบไล่ระดับสี
  2. กำหนดเป้าหมาย css และเปลี่ยนสีหยุดสำหรับแต่ละการหยุดโดยใช้คลาสธรรมดา
  3. ชนะ!

ประโยชน์บางประการของการใช้คลาสแทน:nth-childคือจะไม่ได้รับผลกระทบหากคุณจัดลำดับการหยุดใหม่ นอกจากนี้ยังทำให้เจตนาของแต่ละชั้นชัดเจน - คุณจะสงสัยว่าคุณต้องการสีฟ้าสำหรับเด็กคนแรกหรือคนที่สอง

ฉันได้ทดสอบกับ Chrome, Firefox และ IE11 ทั้งหมด:

.main-stop {
  stop-color: red;
}
.alt-stop {
  stop-color: green;
}
<svg class="green" width="100" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <linearGradient id="gradient">
    <stop class="main-stop" offset="0%" />
    <stop class="alt-stop" offset="100%" />
  </linearGradient>
  <rect width="100" height="50" fill="url(#gradient)" />
</svg>

ดูตัวอย่างที่แก้ไขได้ที่นี่: https://jsbin.com/gabuvisuhe/edit?html,css,output


สิ่งที่ขาดคือคุณไม่รู้แน่ชัดว่าชื่อคลาสหยุดคืออะไรและมีลำดับอะไร อันที่จริงวิธีแก้ปัญหาก็เหมือนกันข้อแตกต่างเพียงอย่างเดียวคือตัวเลือก CSS
กลเม็ดเด็ดพราย

3
ฉันคิดว่านี่เป็นคำตอบที่ทันสมัยที่สุดสำหรับคำถาม OPs
Elemental

10

นี่คือวิธีแก้ปัญหาที่คุณสามารถเพิ่มการไล่ระดับสีและเปลี่ยนสีโดยใช้ CSS เท่านั้น:

// JS is not required for the solution. It's used only for the interactive demo.
const svg = document.querySelector('svg');
document.querySelector('#greenButton').addEventListener('click', () => svg.setAttribute('class', 'green'));
document.querySelector('#redButton').addEventListener('click', () => svg.setAttribute('class', 'red'));
svg.green stop:nth-child(1) {
  stop-color: #60c50b;
}
svg.green stop:nth-child(2) {
  stop-color: #139a26;
}

svg.red stop:nth-child(1) {
  stop-color: #c84f31;
}
svg.red stop:nth-child(2) {
  stop-color: #dA3448;
}
<svg class="green" width="100" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <linearGradient id="gradient">
    <stop offset="0%" />
    <stop offset="100%" />
  </linearGradient>
  <rect width="100" height="50" fill="url(#gradient)" />
</svg>

<br/>
<button id="greenButton">Green</button>
<button id="redButton">Red</button>


2

ขอบคุณทุกคนสำหรับการตอบกลับที่แม่นยำของคุณ

การใช้ svg ใน shadow dom ฉันเพิ่มการไล่ระดับสี 3 เส้นที่ฉันต้องการภายใน svg ภายใน a. ฉันวางกฎการเติม css บนส่วนประกอบของเว็บและการสืบทอด od fill ทำงาน

    <svg viewbox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
      <path
        d="m258 0c-45 0-83 38-83 83 0 45 37 83 83 83 45 0 83-39 83-84 0-45-38-82-83-82zm-85 204c-13 0-24 10-24 23v48c0 13 11 23 24 23h23v119h-23c-13 0-24 11-24 24l-0 47c0 13 11 24 24 24h168c13 0 24-11 24-24l0-47c0-13-11-24-24-24h-21v-190c0-13-11-23-24-23h-123z"></path>
    </svg>
    
    <svg height="0" width="0">
      <defs>
        <linearGradient id="lgrad-p" gradientTransform="rotate(75)"><stop offset="45%" stop-color="#4169e1"></stop><stop offset="99%" stop-color="#c44764"></stop></linearGradient>
        <linearGradient id="lgrad-s" gradientTransform="rotate(75)"><stop offset="45%" stop-color="#ef3c3a"></stop><stop offset="99%" stop-color="#6d5eb7"></stop></linearGradient>
        <linearGradient id="lgrad-g" gradientTransform="rotate(75)"><stop offset="45%" stop-color="#585f74"></stop><stop offset="99%" stop-color="#b6bbc8"></stop></linearGradient>
      </defs>
    </svg>
    
    <div></div>

    <style>
      :first-child {
        height:150px;
        width:150px;
        fill:url(#lgrad-p) blue;
      }
      div{
        position:relative;
        width:150px;
        height:150px;
        fill:url(#lgrad-s) red;
      }
    </style>
    <script>
      const shadow = document.querySelector('div').attachShadow({mode: 'open'});
      shadow.innerHTML="<svg viewbox=\"0 0 512 512\">\
        <path d=\"m258 0c-45 0-83 38-83 83 0 45 37 83 83 83 45 0 83-39 83-84 0-45-38-82-83-82zm-85 204c-13 0-24 10-24 23v48c0 13 11 23 24 23h23v119h-23c-13 0-24 11-24 24l-0 47c0 13 11 24 24 24h168c13 0 24-11 24-24l0-47c0-13-11-24-24-24h-21v-190c0-13-11-23-24-23h-123z\"></path>\
      </svg>\
      <svg height=\"0\">\
      <defs>\
        <linearGradient id=\"lgrad-s\" gradientTransform=\"rotate(75)\"><stop offset=\"45%\" stop-color=\"#ef3c3a\"></stop><stop offset=\"99%\" stop-color=\"#6d5eb7\"></stop></linearGradient>\
        <linearGradient id=\"lgrad-g\" gradientTransform=\"rotate(75)\"><stop offset=\"45%\" stop-color=\"#585f74\"></stop><stop offset=\"99%\" stop-color=\"#b6bbc8\"></stop></linearGradient>\
      </defs>\
    </svg>\
    ";
    </script>

อันแรกคือ SVG ปกติอันที่สองอยู่ในโดมเงา


-4

นี่คือวิธีตั้งค่าlinearGradientบนองค์ประกอบเป้าหมาย:

<style type="text/css">
    path{fill:url('#MyGradient')}
</style>
<defs>
    <linearGradient id="MyGradient">
        <stop offset="0%" stop-color="#e4e4e3" ></stop>
        <stop offset="80%" stop-color="#fff" ></stop>
    </linearGradient>
</defs>

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