Hộp giới hạn SVG: đo trong đúng hệ tọa độ
So sánh getBBox và getBoundingClientRect trên hình SVG đã biến đổi. Đặt lớp phủ đúng, thử giới hạn đường viền và căn viewBox với khoảng đệm được chỉ định cụ thể.
Trên trang này
Dùng getBBox() khi cần giới hạn của phần tử SVG trong tọa độ người dùng riêng của nó. Dùng getBoundingClientRect() khi cần hình chữ nhật tính bằng pixel CSS so với khung nhìn trình duyệt. Trước khi sao chép kết quả nào vào lớp phủ hoặc viewBox, kiểm tra hệ tọa độ nơi sử dụng.
Biểu trưng xoay có thể có hộp cục bộ nhỏ và hộp căn theo màn hình lớn hơn nhiều. Cả hai số đo đều có thể đúng. Không nên coi số đo nào là hình chữ nhật phổ quát bao quanh mọi pixel được vẽ, đặc biệt khi có đường viền, dấu đầu/cuối, cắt vùng hoặc bộ lọc.
Chọn phép đo theo nơi sử dụng
| Nơi sử dụng | Phép đo bắt đầu | Điều cần lưu ý |
|---|---|---|
| Hình chữ nhật bên trong cùng hệ tọa độ SVG | getBBox() | Đặt hình chữ nhật trong cùng ngữ cảnh biến đổi |
| Đường bao chọn HTML có vị trí fixed | getBoundingClientRect() | Giữ trong tọa độ khung nhìn và cập nhật khi bố cục đổi |
| viewBox SVG gốc quanh nhóm đã biến đổi | Hộp cục bộ cộng phép biến đổi tọa độ | Chuyển sang đơn vị người dùng của phần tử gốc trước khi căn |
| Vùng cắt gồm đường viền và hiệu ứng | Quy trình giới hạn được xác minh riêng | Đừng cho rằng hộp hình học cơ bản bao gồm mọi phần được vẽ |
Tài liệu getBBox() của MDN mô tả giới hạn hình học cục bộ và các điều khiển tùy chọn cho đường viền, dấu đầu/cuối và cắt vùng. Transform của chính phần tử được đo và các phần tử tổ tiên không nằm trong kết quả cục bộ đó. Các phần tử con của nhóm vẫn đóng góp vào hình học nhóm, bao gồm vị trí của chúng trong nhóm.
Tài liệu getBoundingClientRect() của MDN mô tả tọa độ tương đối với khung nhìn. Cuộn trang thay đổi quan hệ tọa độ đó. Các giá trị pixel CSS này không tự động là đơn vị người dùng SVG hoặc kích thước in vật lý.

Đo biểu trưng tự tạo đã biến đổi
Mẫu thử này chứa vòng xanh ngọc có khoảng trống chữ nhật và tam giác vàng riêng. Cả hai có đường viền dày với điểm nối tròn. Nhóm được dịch chuyển, xoay và thay đổi tỷ lệ.
<svg id="scene" width="600" height="300" viewBox="0 0 300 150"
xmlns="http://www.w3.org/2000/svg" style="overflow:visible">
<g id="art" transform="translate(100 35) rotate(25) scale(1.2)"
stroke="#17364c" stroke-width="10" stroke-linejoin="round">
<path fill="#147d78" fill-rule="evenodd"
d="M0 0H80V60H0Z M20 20H60V40H20Z" />
<path fill="#e5a340" d="M100 50L120 10L140 50Z" />
</g>
</svg>
<script>
const art = document.querySelector("#art");
const local = art.getBBox();
const screen = art.getBoundingClientRect();
</script>Tọa độ cục bộ chạy từ 0 đến 140 theo chiều ngang và 0 đến 60 theo chiều dọc. Lỗ tác động tới phần bên trong của hình nhưng không làm giảm phạm vi ngoài đó.
Chúng tôi mở hình học này trong Chrome và đo bằng một bộ mã kiểm tra nhỏ. Ở kích thước hiển thị 600 × 300 pixel CSS, getBBox() trả về x=0, y=0, width=140, height=60. Hình chữ nhật client xấp xỉ 365.376 × 272.508 pixel CSS. Vị trí màn hình của nó phụ thuộc SVG nằm ở đâu trên trang.
Sau khi đổi kích thước hiển thị thành 300 × 150, hộp cục bộ giữ nguyên 140 × 60. Hình chữ nhật client trở thành xấp xỉ 182.688 × 136.254, bằng một nửa kích thước trước. Hình học nguồn không thay đổi; ánh xạ của nó lên trang đã thay đổi.
Các con số này mô tả mẫu thử trong trình duyệt được kiểm tra. Chúng không phải so sánh các bộ máy trình duyệt hoặc đặc tả cho hộp chọn của mọi trình chỉnh sửa.
Vẽ mỗi đường bao trong hệ tọa độ riêng
Với đường bao cục bộ, dùng tọa độ trả về và cùng transform với nhóm được đo. Đặt nó làm phần tử cùng cấp để nó không trở thành một phần của lần đo tiếp theo:
const scene = document.querySelector("#scene");
const box = art.getBBox();
const outline = document.createElementNS("http://www.w3.org/2000/svg", "rect");
for (const key of ["x", "y", "width", "height"]) {
outline.setAttribute(key, box[key]);
}
outline.setAttribute("transform", art.getAttribute("transform"));
outline.setAttribute("fill", "none");
outline.setAttribute("stroke", "olive");
scene.append(outline);Sao chép trực tiếp transform phù hợp với mẫu này vì hình và đường bao cùng phần tử cha. Hình chữ nhật được chèn nơi khác cần ánh xạ ma trận giữa hai hệ tọa độ.
Với đường bao HTML, đặt div trực tiếp dưới body với vị trí fixed và không có phần tử tổ tiên chứa nó đã được biến đổi:
const box = art.getBoundingClientRect();
Object.assign(overlay.style, {
position: "fixed",
boxSizing: "border-box",
pointerEvents: "none",
border: "2px dashed coral",
left: `${box.x}px`,
top: `${box.y}px`,
width: `${box.width}px`,
height: `${box.height}px`,
});Ở đây overlay là phần tử đường bao có sẵn của bạn. Đo lại khi cuộn, đổi kích thước hoặc thay đổi bố cục hay transform của hình. Nếu dùng vị trí theo tài liệu, tính độ lệch cuộn; nếu dùng vùng chứa có định vị, tính hệ tọa độ của vùng chứa đó. Trộn lẫn các quy tắc bố trí này là nguyên nhân phổ biến khiến hình chữ nhật vốn đúng xuất hiện lệch vị trí.
Bộ kiểm tra của chúng tôi hiển thị cả hai đường bao. Hình chữ nhật cục bộ nghiêng theo vòng và tam giác, còn hình chữ nhật HTML nét đứt giữ ngang và dọc. Đường viền dày vượt ra ngoài một số phần của đường bao hình học.
Thử tùy chọn đường viền thay vì mặc định có hỗ trợ
Hộp cục bộ mặc định không bao gồm độ rộng đường viền. MDN mô tả getBBox({ stroke: true }), nhưng tham số options có các vấn đề tương thích riêng so với phương thức không đối số đã tồn tại lâu.
Trong mẫu Chrome của chúng tôi, truyền { stroke: true } trả về cùng hộp 140 × 60 như gọi không đối số. Xóa đường viền 10 đơn vị cũng để hình chữ nhật client giữ nguyên. Viền tối nhìn thấy rõ ràng đã đổi, nên không kết quả nào trong thử nghiệm đó biểu diễn toàn bộ phạm vi được vẽ.
Một lần gọi nhận đối tượng options mà không ném lỗi chưa đủ chứng minh nó tuân thủ tùy chọn. Thử hình có đường viền đã biết và kiểm tra kích thước trả về trong trình duyệt đích. Dùng các định nghĩa hộp giới hạn SVG để phân biệt giới hạn đối tượng, đường viền và phần trang trí.
Đừng khái quát quy tắc đệm nửa độ rộng đường viền cho mọi hình. Điểm nối miter, dấu đầu/cuối, đường viền không đổi tỷ lệ, bóng và bộ lọc có thể mở rộng khác nhau. Với mẫu điểm nối tròn đơn giản do bạn kiểm soát, khoảng đệm được chỉ định cụ thể cộng kiểm tra trực quan có thể đủ. Với công cụ tự động cắt vùng xuất, những trường hợp đó cần xử lý chủ động.
Chuyển hộp cục bộ trước khi căn viewBox gốc
Không bao giờ dán trực tiếp x, y, width và height của hình chữ nhật client vào viewBox SVG. Các giá trị đó gồm vị trí trên trang và dùng hệ đơn vị khác.
Với mẫu thử, ánh xạ bốn góc hộp cục bộ vào tọa độ người dùng của SVG gốc. Tài liệu getScreenCTM() của MDN mô tả ma trận dùng để ánh xạ tọa độ SVG về khung nhìn tài liệu. Kết hợp ma trận hình với ma trận gốc nghịch đảo loại bỏ ánh xạ màn hình chung đó:
const box = art.getBBox();
const rootMatrix = scene.getScreenCTM();
const artMatrix = art.getScreenCTM();
if (!rootMatrix || !artMatrix) throw new Error("SVG is not measurable");
const toRoot = rootMatrix.inverse().multiply(artMatrix);
const corners = [
[box.x, box.y],
[box.x + box.width, box.y],
[box.x + box.width, box.y + box.height],
[box.x, box.y + box.height],
].map(([x, y]) => new DOMPoint(x, y).matrixTransform(toRoot));
const xs = corners.map(p => p.x);
const ys = corners.map(p => p.y);
const x = Math.min(...xs);
const y = Math.min(...ys);
const width = Math.max(...xs) - x;
const height = Math.max(...ys) - y;
const padding = 12; // Chosen for this simple fixture, in root user units.
scene.setAttribute("viewBox", [
x - padding, y - padding,
width + 2 * padding, height + 2 * padding,
].join(" "));Cách này giả định SVG đã hiển thị có transform hai chiều khả nghịch. Ánh xạ các góc hình chữ nhật cục bộ tạo một vùng bao căn theo trục có thể rộng hơn mức cần thiết, chưa chắc là hộp khít nhất có thể quanh mọi đường cong đã biến đổi.
Bộ kiểm tra tạo viewBox xấp xỉ 57.571 23 206.688 160.254 với khoảng đệm đó. Chúng tôi kiểm tra kết quả và đường viền tròn của mẫu vẫn nằm trong vùng hiển thị. Khung hiển thị rộng vẫn có khoảng trống hai bên vì viewBox đã căn có tỷ lệ khác; căn khung không có nghĩa kéo giãn.
Nếu cần tâm xoay thay vì vùng cắt, hướng dẫn transform-origin giải thích hộp tham chiếu ảnh hưởng đến xoay thế nào. Với kích thước nhập vật lý, dùng quy trình xử lý kích thước SVG.
Đo hình học bạn định chỉnh sửa
Nếu nguồn chỉ tồn tại dưới dạng PNG hoặc JPG và bạn cần hình chỉnh sửa được, PerfectVector có thể khôi phục SVG trước khi đo. Kiểm tra đường dẫn, khoảng trống, đường viền và mọi nội dung raster giữ lại. Hộp giới hạn cho biết hình học trải tới đâu; nó không chứng minh đồ lại chính xác hoặc mọi chi tiết nhìn thấy đều chỉnh sửa được.
SVG có sẵn có thể được đo trực tiếp. Hướng dẫn chỉnh sửa SVG giúp nhận diện thứ bạn thực sự có, còn tổng quan vector hóa ảnh giải thích bước chuyển đổi trước đó.
Với hình chỉ có raster, thử nguồn của bạn trong PerfectVector, kiểm tra đường bao được khôi phục, rồi đo nhóm bạn sẽ bố trí hoặc xuất. Giữ khoảng đệm và kiểm tra các mép nhìn thấy cuối cùng trước khi coi kết quả là vùng cắt bàn giao.
Câu hỏi thường gặp
Vì sao hai phương thức trả về chiều rộng khác nhau? Chúng dùng hệ tọa độ khác nhau. Hộp SVG cục bộ mô tả hình học bằng đơn vị người dùng, còn hình chữ nhật client mô tả giới hạn tương đối với khung nhìn bằng pixel CSS sau ánh xạ trang. Thay đổi tỷ lệ và xoay có thể làm thay đổi những kích thước đó.
Hộp giới hạn có cho biết hình có lỗ không? Không. Hình chữ nhật ghi lại phạm vi ngoài, không ghi cấu trúc bên trong. Hình chữ nhật đặc và vòng có cùng mép ngoài có thể có cùng hộp giới hạn. Kiểm tra đường dẫn và quy tắc tô để kiểm tra khoảng trống.
Tôi có thể dùng hình chữ nhật client làm viewBox không? Không thể trực tiếp. Chuyển hình học liên quan vào tọa độ người dùng của SVG gốc trước. Không nên sao chép vị trí màn hình và kích thước pixel CSS vào hình chữ nhật tọa độ nguồn.
Nguồn tham khảo
- MDN getBBox — Xác định giới hạn SVG cục bộ và các điều khiển đo tùy chọn.
- MDN getBoundingClientRect — Giải thích hình chữ nhật tương đối với khung nhìn và việc cuộn.
- Các định nghĩa hộp giới hạn SVG — Phân biệt giới hạn hình học của đối tượng, đường viền và phần trang trí.
- MDN getScreenCTM — Mô tả ma trận dùng để nối tọa độ SVG và khung nhìn.
Thêm từ blog

Thứ tự transform SVG: đổi tỷ lệ và đặt vị trí hình
So sánh thứ tự translate và scale trong SVG qua logo có số đo. Dùng nhóm lồng nhau, theo dõi một điểm và bố trí hình mà không thay đổi đường dẫn nguồn.

Ảnh SVG trong Graphviz: Giúp hình của nút dễ bàn giao
Thêm hình SVG vào nút Graphviz, kiểm tra tham chiếu ảnh và thử gói tài nguyên đầy đủ với sơ đồ được di chuyển cùng bản bàn giao tự chứa.