Làm thế nào tôi có thể tạo một thang đo Svg với thùng chứa mẹ của nó?


235

Tôi muốn có thang đo nội dung của phần tử svg nội tuyến khi kích thước không phải là nguồn gốc. Tất nhiên tôi có thể có nó như một tập tin riêng biệt và mở rộng nó như thế.

index.html: <img src="foo.svg" style="width: 100%;" />

foo.svg: <svg width="123" height="456"></svg>

Tuy nhiên, tôi muốn thêm các kiểu bổ sung vào CSS thông qua SVG, vì vậy liên kết một kiểu bên ngoài không phải là một tùy chọn. Làm cách nào để tạo thang đo SVG nội tuyến?


2
thử các ưu tiên về chiều rộng và chiều cao của Svg.
ncm

@ncm Nó sẽ được thực hiện như thế nào với JS?
Mawg nói rằng phục hồi Monica

Câu trả lời:


456

Để chỉ định tọa độ trong ảnh SVG độc lập với kích thước tỷ lệ của ảnh, hãy sử dụng viewBoxthuộc tính trên phần tử SVG để xác định hộp giới hạn của ảnh trong hệ tọa độ của ảnh và sử dụng thuộc tính widthheightđể xác định những gì chiều rộng hoặc chiều cao liên quan đến trang chứa.

Ví dụ: nếu bạn có những điều sau đây:

<svg>
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

Nó sẽ hiển thị dưới dạng tam giác 10px x 20px:

Tam giác 10 x20

Bây giờ, nếu bạn chỉ đặt chiều rộng và chiều cao, điều đó sẽ thay đổi kích thước của phần tử SVG, nhưng không thay đổi tỷ lệ tam giác:

<svg width=100 height=50>
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

Tam giác 10 x20

Nếu bạn đặt hộp xem, điều đó khiến nó biến đổi hình ảnh sao cho hộp đã cho (trong hệ tọa độ của hình ảnh) được thu nhỏ để vừa với chiều rộng và chiều cao cho trước (trong hệ tọa độ của trang). Chẳng hạn, để mở rộng hình tam giác thành 100px x 50px:

<svg width=100 height=50 viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

Tam giác 100x50

Nếu bạn muốn mở rộng nó theo chiều rộng của khung nhìn HTML:

<svg width="100%" viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

Tam giác 300x150

Lưu ý rằng theo mặc định, tỷ lệ khung hình được giữ nguyên. Vì vậy, nếu bạn xác định rằng phần tử phải có chiều rộng 100%, nhưng chiều cao là 50px, thì thực tế nó sẽ chỉ có tỷ lệ lên tới chiều cao 50px (trừ khi bạn có cửa sổ rất hẹp):

<svg width="100%" height="50px" viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

Tam giác 100x50

Nếu bạn thực sự muốn nó kéo dài theo chiều ngang, hãy tắt bảo toàn tỷ lệ khung hình bằng preserveAspectRatio=none:

<svg width="100%" height="50px" viewBox="0 0 20 10" preserveAspectRatio="none">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

Tam giác 300x50

(lưu ý rằng trong các ví dụ của tôi, tôi sử dụng cú pháp hoạt động cho nhúng HTML, để bao gồm các ví dụ dưới dạng hình ảnh trong StackOverflow, thay vào đó tôi nhúng vào một SVG khác, vì vậy tôi cần sử dụng cú pháp XML hợp lệ)


1
Làm thế nào để bạn thực hiện không chỉ viewBox reservedAspectRatio, mà còn là hộp chính? Tôi muốn chiều rộng: 100%; chiều cao: tự động cho nó.
bjb568

1
@Dude: Tôi nghĩ rằng ví dụ có width="100%"và không có chiều cao được chỉ định sẽ làm những gì bạn muốn. Tôi đã thêm hình ảnh để chứng minh. Nó có chiều rộng 100%, và tăng tỷ lệ chiều cao theo tỷ lệ. Nếu đó không phải là những gì bạn đang tìm kiếm, bạn có thể cố gắng làm rõ ý của bạn không?
Brian Campbell

1
Oh. Không có vấn đề thực sự. Đó chỉ là một lỗi webkit. Trong Safari và Chrome, chiều cao "thực" là 100% theo mặc định, không phải tự động. Làm thế nào tôi có thể nhận được xung quanh này sau đó?
bjb568

4
@Dude Ah, vâng, tôi hiểu rồi. Nó hoạt động tốt trong Firefox, nhưng không có Chrome hoặc Safari. Theo Thông số kỹ thuật SVG , Firefox có vẻ đúng; trong khi giá trị mặc định của widthheightcho một phần tử SVG là 100%, đây không phải là định nghĩa CSS 100% (100% khối chứa), mà thay vào đó là 100% chế độ xem đã được chỉ định dựa trên tỷ lệ khung hình bên trong ( được tính từ viewBoxkhi được đưa ra). Tôi chưa tìm thấy giải pháp cho vấn đề đó hoạt động trong Chrome / Safari.
Brian Campbell

1
Điều này làm việc cho tôi. Trước tiên tôi tạo một thuộc tính viewBox trên phần tử SVG và đặt giá trị thành "0 0 [chiều rộng svg gốc] [chiều cao svg gốc]". Tiếp theo tôi thay đổi thuộc tính chiều rộng của phần tử SVG thành "auto" và thuộc tính height thành "100%". Container cũng phải có chiều cao xác định. Điều này chia tỷ lệ vectơ đến 100% chiều cao của container, cho phép chiều rộng nổi. Cuối cùng, đặt chiều rộng tối đa CSS của SVG thành 100% để ngăn chặn quá mức bộ chứa.
Ryan Griggs

28

Sau 48 giờ nghiên cứu, tôi đã kết thúc việc này để có được tỷ lệ theo tỷ lệ:

LƯU Ý: Mẫu này được viết bằng React. Nếu bạn không sử dụng điều đó, hãy thay đổi công cụ vỏ lạc đà trở lại dấu gạch nối (nghĩa là: thay đổi backgroundColorthành background-colorvà thay đổi kiểu Objecttrở lại a String).

<div
  style={{
    backgroundColor: 'lightpink',
    resize: 'horizontal',
    overflow: 'hidden',
    width: '1000px',
    height: 'auto',
  }}
>
  <svg
    width="100%"
    viewBox="113 128 972 600"
    preserveAspectRatio="xMidYMid meet"
  >
    <g> ... </g>
  </svg>
</div>

Đây là những gì đang xảy ra trong mã mẫu ở trên:

XEM

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribution/viewBox

min-x, min-y, chiều rộng và chiều cao

tức là: viewbox = "0 0 1000 1000"

Viewbox là một thuộc tính quan trọng vì về cơ bản nó cho SVG biết kích thước sẽ vẽ và ở đâu. Nếu bạn đã sử dụng CSS để tạo SVG 1000x1000 px nhưng hộp xem của bạn là 2000x2000, bạn sẽ thấy quý trên cùng bên trái của SVG.

Hai số đầu tiên, min-x và min-y, xác định xem SVG có được bù trong hộp xem không.

SVG của tôi cần thay đổi lên / xuống hoặc trái / phải

Kiểm tra cái này: viewbox = "50 50 450 450"

Hai số đầu tiên sẽ thay đổi SVG của bạn sang trái 50px và 50px, và hai số thứ hai là kích thước hộp xem: 450x450 px. Nếu SVG của bạn có kích thước 500x500 nhưng nó có thêm một số phần đệm trên đó, bạn có thể thao tác các số đó để di chuyển nó bên trong "hộp xem".

Mục tiêu của bạn tại thời điểm này là thay đổi một trong những con số đó và xem điều gì sẽ xảy ra.

Bạn cũng có thể bỏ hoàn toàn hộp xem, nhưng sau đó, số dặm của bạn sẽ thay đổi tùy thuộc vào mọi cài đặt khác bạn có tại thời điểm đó. Theo kinh nghiệm của tôi, bạn sẽ gặp phải các vấn đề với việc duy trì tỷ lệ khung hình vì hộp xem giúp xác định tỷ lệ khung hình.

BẢO TỈ LỆ

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribution/preserveAspectRatio

Dựa trên nghiên cứu của tôi, có rất nhiều cài đặt tỷ lệ khung hình khác nhau, nhưng cài đặt mặc định được gọi xMidYMid meet. Tôi đặt nó trên mỏ để nhắc nhở bản thân một cách rõ ràng. xMidYMid meetlàm cho nó có tỷ lệ cân xứng dựa trên điểm giữa X và Y. Điều này có nghĩa là nó nằm ở giữa trong khung nhìn.

CHIỀU RỘNG

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribution/ thong

Nhìn vào mã ví dụ của tôi ở trên. Chú ý cách tôi chỉ đặt chiều rộng, không có chiều cao. Tôi đặt nó thành 100% để nó lấp đầy thùng chứa. Đây là điều có lẽ đóng góp nhiều nhất để trả lời câu hỏi Stack Overflow này.

Bạn có thể thay đổi nó thành bất kỳ giá trị pixel nào bạn muốn, nhưng tôi khuyên bạn nên sử dụng 100% như tôi đã làm để thổi nó lên kích thước tối đa và sau đó kiểm soát nó bằng CSS thông qua bộ chứa chính. Tôi khuyên bạn nên làm điều này bởi vì bạn sẽ có được sự kiểm soát "thích hợp". Bạn có thể sử dụng truy vấn phương tiện và bạn có thể kiểm soát kích thước mà không cần JavaScript điên.

LẬP TRÌNH VỚI CSS

Nhìn vào mã ví dụ của tôi ở trên một lần nữa. Lưu ý cách tôi có các thuộc tính này:

resize: 'horizontal', // you can safely omit this
overflow: 'hidden',   // if you use resize, use this to fix weird scrollbar appearance
width: '1000px',
height: 'auto',

Đây là bổ sung, nhưng nó chỉ cho bạn cách cho phép người dùng thay đổi kích thước SVG trong khi duy trì tỷ lệ khung hình phù hợp. Vì SVG duy trì tỷ lệ khung hình của riêng nó, bạn chỉ cần thay đổi kích thước chiều rộng trên vùng chứa chính và nó sẽ thay đổi kích thước theo ý muốn.

Chúng tôi để chiều cao một mình và / hoặc đặt nó thành tự động và chúng tôi kiểm soát thay đổi kích thước theo chiều rộng. Tôi chọn chiều rộng vì nó thường có ý nghĩa hơn do thiết kế đáp ứng.

Dưới đây là hình ảnh của các cài đặt này đang được sử dụng:

nhập mô tả hình ảnh ở đây

Nếu bạn đọc mọi giải pháp trong câu hỏi này và vẫn còn bối rối hoặc không thấy rõ những gì bạn cần, hãy xem liên kết này tại đây. Tôi tìm nó rất có ích:

https://css-tricks.com/scale-svg/

Đây là một bài viết lớn, nhưng nó phá vỡ khá nhiều cách có thể để thao tác một SVG, có hoặc không có CSS. Tôi khuyên bạn nên đọc nó trong khi tình cờ uống cà phê hoặc lựa chọn chất lỏng của bạn.


Điều này dường như không hoạt động đối với bất kỳ SVG nào - Nếu bạn không có quyền kiểm soát nguồn SVG, thì phương pháp này sẽ thất bại khi SVG có chiều rộng cố định.
dùng48956

@ user48956 Bạn luôn có thể thao tác nó sau khi thực tế với JavaScript.
Andrew

Có - bạn luôn có thể chọc vào các bộ định dạng tệp khác nhau bằng một chương trình - nhưng bạn hy vọng sẽ có một phương pháp hoạt động cho tất cả các loại tài sản (ví dụ: PNG) và không yêu cầu lập trình JavaScript.
dùng48956

20

Bạn sẽ muốn thực hiện một chuyển đổi như vậy:

với JavaScript:

document.getElementById(yourtarget).setAttribute("transform", "scale(2.0)");

Với CSS:

#yourtarget {
  transform:scale(2.0);
  -webkit-transform:scale(2.0);
}

Gói Trang SVG của bạn trong thẻ Nhóm như vậy và nhắm mục tiêu trang đó để thao tác toàn bộ trang:

<svg>
  <g id="yourtarget">
    your svg page
  </g>
</svg>

Lưu ý : Tỷ lệ 1.0 là 100%


7
Đồng ý. Tôi không muốn JS trong việc này. Có cách nào để nó biến đổi để phù hợp với cha mẹ?
bjb568

@bj setAttribution giống như <tag
property

17

Loay hoay và tìm thấy CSS này dường như chứa SVG trong trình duyệt Chrome cho đến khi vùng chứa lớn hơn hình ảnh:

div.inserted-svg-logo svg { max-width:100%; }

Cũng có vẻ như đang làm việc trong FF + IE 11.


Điều này đã giải quyết vấn đề cho tôi. Tôi chỉ nhìn thấy tràn trong iOS mặc dù. Cảm ơn!
Evan Mattson

5
Sử dụng cả hai max-width: 100%max-height: 100%sẽ làm cho svg luôn mở rộng quy mô cho container mà không bao giờ tràn hoặc mất tỷ lệ khung hình của nó.
Gavin

2
@Gavin max-height: 100%không hoạt động với tôi, được giải quyết bằng cách sử dụng vhthay vì%
Pavel

2

thay đổi tệp SVG không phải là một giải pháp công bằng cho tôi vì vậy thay vào đó, tôi đã sử dụng các đơn vị CSS tương đối .

vh, vw, %Rất tiện dụng. Tôi đã sử dụng CSS như height: 2.4vh;để đặt kích thước động cho hình ảnh SVG của mình.



0

Điều chỉnh thuộc tính currentScale hoạt động trong IE (Tôi đã thử nghiệm với IE 11), nhưng không phải trong Chrome.

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.