Làm cách nào để tạo phần tử <svg> mở rộng hoặc hợp đồng với vùng chứa mẹ của nó?


112

Mục đích là để <svg>phần tử mở rộng đến kích thước của vùng chứa mẹ của nó, trong trường hợp này là a <div>, bất kể vùng chứa đó lớn hay nhỏ.

Mật mã:

<style>
    svg, #container{
        height: 100%;
        width: 100%;
    }
</style>

<div id="container">
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" >
         <rect x="0" y="0" width="100" height="100" />
    </svg>
</div>

Giải pháp phổ biến nhất cho vấn đề này dường như là thiết lập viewBoxthuộc tính trên <svg>phần tử.

viewBox="0 0 widthOfContainer heightOfContainer"

Tuy nhiên, điều này dường như không hoạt động trong trường hợp các phần tử bên trong <svg>phần tử có chiều rộng và / hoặc chiều cao được xác định trước. Ví dụ, <rect>phần tử, trong đoạn mã trên, có chiều rộng và chiều cao được đặt rõ ràng.

Vì vậy, giải pháp rõ ràng là sử dụng% chiều rộng và% chiều cao trên các phần tử đó. Nhưng điều này thậm chí phải được thực hiện? Đặc biệt, vì <img src=test.svg >hoạt động tốt và mở rộng / hợp đồng mà không gặp bất kỳ vấn đề nào với <rect>chiều cao và chiều rộng được thiết lập rõ ràng .

Nếu các phần tử giống <rect>và các phần tử khác giống nó, phải có chiều rộng và chiều cao của chúng được xác định theo tỷ lệ phần trăm, thì Inkscape có cách nào để đặt nó để tất cả các phần tử trong <svg>tài liệu sử dụng phần trăm chiều rộng, chiều cao, v.v. thay vì kích thước cố định không ?


1
Lưu svg dưới dạng tệp, thay vì tham chiếu nó dưới dạng hình ảnh, như <img src = "file.svg" /> và theo cách đó, bạn có thể sử dụng chiều rộng: 100% hoặc chiều cao: 100%
Burimi 11/02/15

Câu trả lời:


56

Các viewBoxkhông phải là chiều cao của container, đó là kích thước của bản vẽ của bạn. Xác định viewBoxchiều rộng của bạn là 100 đơn vị, sau đó xác định chiều rộng của bạn rectlà 10 đơn vị. Sau đó, dù bạn chia tỷ lệ SVG lớn đến đâu, thì kích thước rectsẽ bằng 10% chiều rộng của hình ảnh.


33
Nhưng câu hỏi đặt ra là: Làm thế nào để mở rộng quy mô SVG?
Adrian Heine

6
@AdrianLang Việc chia tỷ lệ xảy ra tự động khi bạn đặt kích thước trên đối tượng SVG, như đã được thực hiện trong mã trong câu hỏi. Đây là một phiên bản cố định của ví dụ .
robertc

Bạn nói đúng, tuyệt vời, điều đó thực sự hiệu quả với tôi. Tôi đoán vấn đề của tôi là thuộc tính chiều cao và chiều rộng trong phần tử gốc svg của tôi.
Adrian Heine

2
Tôi đã thực hiện một số chỉnh sửa nhỏ đối với fiddle đó để làm cho việc thay đổi kích thước bị buộc theo chiều ngang và chiều dọc mà không bảo toàn tỷ lệ khung hình và làm cho nó hoạt động trong IE, trong khi fiddle @robertc được gửi thì không. Hy vọng nó sẽ giúp một người nào đó trên đường!
Mister Crimson

3
Theo mặc định, svg của bạn sẽ chia tỷ lệ lớn nhất có thể để nó hiển thị hoàn toàn nhưng vẫn giữ nguyên tỷ lệ khung hình của nó (do đó, một viewBox hình vuông sẽ không lấp đầy hoàn toàn một hình chữ nhật mẹ). Nếu bạn thực sự muốn buộc nó che hoàn toàn vùng chứa mẹ, hãy thêm keepAspectRatio = "none" vào phần tử SVG.
Patricksurry

24

Giả sử tôi có một SVG trông giống như sau: pic1

Và tôi muốn đặt nó trong một div và làm cho nó lấp đầy div một cách phản ứng. Cách làm của tôi như sau:

Đầu tiên, tôi mở tệp SVG trong một ứng dụng như inkscape. Trong File-> Document Properties, tôi đặt chiều rộng của tài liệu là 800px và chiều cao là 600px (bạn có thể chọn các kích thước khác). Sau đó, tôi lắp SVG vào tài liệu này.

pic2

Sau đó, tôi lưu tệp này dưới dạng tệp SVG mới và lấy dữ liệu đường dẫn từ tệp này. Bây giờ trong HTML, mã thực hiện điều kỳ diệu như sau:

<div id="containerId">    
    <svg
    id="svgId" 
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
    version="1.1"
    x="0"
    y="0"
    width="100%"
    height="100%"
    viewBox="0 0 800 600"
    preserveAspectRatio="none">
       <path d="m0 0v600h800v-600h-75.07031l-431 597.9707-292.445315-223.99609 269.548825-373.97461h-271.0332z" fill="#f00"/>
    </svg>
</div>

Lưu ý rằng chiều rộng và chiều cao của SVG đều được đặt thành 100%, vì chúng tôi muốn nó lấp đầy vùng chứa theo chiều dọc và chiều ngang, nhưng chiều rộng và chiều cao của viewBox giống với chiều rộng và chiều cao của tài liệu trong inkscape là 800px X 600px. Điều tiếp theo bạn cần làm là thiết lập secureAspectRatio thành "none". Nếu bạn cần thêm thông tin về thuộc tính này, đây là một liên kết tốt . Và đó là tất cả những gì cần làm.

Một điều nữa là mã này hoạt động trên hầu hết tất cả các trình duyệt chính ngay cả những trình duyệt cũ nhưng trên một số phiên bản android và ios, bạn cần sử dụng một số mã javascrip / jQuery để giữ cho nó nhất quán. Tôi sử dụng các chức năng sau trong tài liệu sẵn sàng và thay đổi kích thước:

$('#svgId').css({
    'width': $('#containerId').width() + 'px',
    'height': $('#containerId').height() + 'px'
});

Hy vọng nó giúp!


5
+1 cho lưu ý KeepAspectRatio. Sau khi tìm kiếm cao và thấp để có được một SVG thực sự kéo dài (không phải chia tỷ lệ) thành một div, đây là câu trả lời chính xác.
adelphus

@Gazoris, Cảm ơn vì câu trả lời tuyệt vời này. có câu hỏi giống nhau. Điều gì sẽ xảy ra nếu svg của tôi được lồng vào nhau. ví dụ: <svg> <svg id = "1"> </svg> <svg id = "2"> </svg> </svg> tôi muốn hiển thị svg 1 và 2 có điều kiện và nó phải có chiều rộng và chiều cao của thùng chứa. <div id = "container" style = "width: 200px; height: 200px;"> </div> bạn có thể vui lòng giúp tôi về vấn đề này được không.
Prasad Parab

@Reza Baradaran: Thiên tài.
DanMad

6

Điều phù hợp với tôi gần đây là xóa tất cả height=""width=""thuộc tính khỏi <svg>thẻ và tất cả các thẻ con. Sau đó, bạn có thể sử dụng tính năng chia tỷ lệ bằng cách sử dụng phần trăm chiều cao hoặc chiều rộng của vùng chứa mẹ.


5
Bạn có thể đưa ra một ví dụ làm việc? Tôi không thể lấy nó để làm bất cứ điều gì.
Michael

2

@robertc nói đúng, nhưng bạn cũng cần lưu ý rằng svg, #containernguyên nhân khiến svg được thu nhỏ theo cấp số nhân đối với bất kỳ thứ gì ngoại trừ 100% (một lần #containervà một lần cho svg).

Nói cách khác, nếu tôi áp dụng 50% h / w cho cả hai yếu tố, thì nó thực sự là 50% của 50% hoặc .5 * .5, tương đương với .25 hoặc 25% tỷ lệ.

Một bộ chọn hoạt động tốt khi được sử dụng như @robertc đề xuất.

svg {
  width:50%;
  height:50%;
}

Đó là vì chọn của bạn svg, #containerphù hợp với cả những svgyếu tố dom các #containeryếu tố dom. Tôi tin rằng thay vào đó bạn đang tìm kiếm svg #container, nhưng thông số kỹ thuật của cha mẹ là không cần thiết nếu bạn vẫn đang sử dụng ID.
Nit

Đó không phải là chính xác những gì tôi đã nói, "một lần cho #container và một lần cho svg"?
Justin Putney

1
Xin lỗi, bạn nói đúng, nhưng câu trả lời của bạn hơi kỳ quặc dẫn đến sự hiểu lầm. Nghe như thể bạn đang nói về một món gotcha tiềm năng lúc đầu.
Nit

1

Đối với iPhone của bạn Bạn có thể sử dụng khi đầu của mình:

"width=device-width"
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.