PerfectVector
Bởi Irene Kim11 phút đọc

Văn bản SVG foreignObject: Sửa nhãn mất khi xuất

Sửa nhãn SVG hiện trong trình duyệt nhưng mất khi xuất. Đối chiếu foreignObject với văn bản thuần SVG, kiểm tra namespace và giữ nguyên phần hình sẵn có.

Trên trang này

Nếu các hình trong SVG vẫn còn sau khi xuất nhưng nhãn biến mất, hãy kiểm tra nhãn bị thiếu có dùng <foreignObject> không. Nó có thể chứa HTML mà trình duyệt bố trí thành công nhưng bộ kết xuất đích không hỗ trợ. Thay nhãn bị ảnh hưởng bằng các phần tử SVG <text> và <tspan>, hoặc chọn cách xuất giữ được diện mạo của nhãn.

Trước tiên mở đúng tệp đã xuất trong trình duyệt. Nếu nhãn cũng không có ở đó, hãy kiểm tra namespace, giới hạn và kiểu hiển thị trước khi quy lỗi cho công cụ nhập. Giữ hình gốc: không cần dò nét toàn bộ ảnh khi chỉ vùng chứa văn bản bị lỗi.

Vì sao hình còn nhưng nhãn biến mất

SVG có thể kết hợp các hình thông thường với nội dung từ một namespace XML khác. Ngọn núi vẽ bằng <path> và mặt trời vẽ bằng <circle> là SVG gốc. Đoạn văn trong <foreignObject> có thể là HTML, với quy tắc xuống dòng và bố trí riêng. Tài liệu foreignObject của MDN mô tả sự khác biệt đó.

Vì vậy, phần mở rộng .svg không đảm bảo mọi phần đều dùng cùng những tính năng kết xuất. Đích tiếp nhận có thể vẽ ngọn núi và mặt trời nhưng bỏ qua đoạn văn HTML. Đổi màu chữ hoặc tăng độ phân giải xuất không bổ sung khả năng hỗ trợ HTML cho bộ kết xuất đó.

Hiện tượngKiểm tra tiếpCách sửa có thể phù hợp
Hình hiện ở cả hai nơi; nhãn chỉ hiện trong trình duyệtNhãn bị thiếu có dùng foreignObject không?Thay nhãn đó hoặc đổi cách xuất
Nhãn HTML cũng mất trong trình duyệtNamespace XHTML, giới hạn được chỉ định rõ, trạng thái hiển thị và kiểu hiển thịSửa vùng chứa HTML trước
Văn bản thuần SVG hiện với kiểu chữ hoặc độ dài dòng khácPhông chữ có sẵn và vị trí dòng đã chọnGiải quyết phông chữ hoặc chuyển chữ cuối cùng thành đường bao
Phần lớn hình bị mấtKhung nhìn, cắt vùng và cấu trúc tài liệuDùng các bước kiểm tra SVG trống rộng hơn

Thử nghiệm nhỏ: chỉ thay nhãn

Chúng tôi tạo một thẻ SVG 480 × 240 gồm một đường dẫn, một hình tròn và dòng chữ ‘Keep artwork and labels separate.’ Tệp đầu dùng nhãn HTML. Tệp thứ hai giữ nguyên các hình và chỉ thay nhãn bằng văn bản thuần SVG với ba dòng được chỉ định rõ.

Trong bản xem trước trên trình duyệt, cả hai nhãn đều hiện. Kết xuất chính những tệp này thành PNG bằng sharp 0.34.4, dùng librsvg 2.61.1 đi kèm, cho kết quả bên dưới: nhãn HTML biến mất còn nhãn SVG gốc vẫn còn. Đầu ra có nhãn HTML cũng giống từng pixel với tệp đối chứng đã bỏ nhãn. Đây là phép thử cho các tệp này và phiên bản bộ kết xuất này, không phải kết luận tương thích cho mọi trình chỉnh sửa.

Bốn bản kết xuất của cùng một thẻ minh họa: cả hai nhãn hiện trong trình duyệt, còn librsvg bỏ nhãn HTML và giữ văn bản thuần SVG
Phần hình giữ nguyên trong cả bốn trường hợp. Chỉ nhãn HTML biến mất trong đầu ra librsvg; văn bản thuần SVG dùng các ngắt dòng được chỉ định rõ.

Tệp gốc đủ nhỏ để bạn tái tạo. Lưu đoạn này thành html-label.svg và mở trong trình duyệt:

<svg xmlns="http://www.w3.org/2000/svg"
  width="480" height="240" viewBox="0 0 480 240">
  <rect width="480" height="240" rx="20" fill="#f5f1e7"/>
  <path d="M40 135Q90 15 140 135Z" fill="#087f75"/>
  <circle cx="90" cy="95" r="18" fill="#f4bc45"/>
  <foreignObject x="180" y="70" width="230" height="110">
    <div xmlns="http://www.w3.org/1999/xhtml"
      style="font: 28px/1.25 Arial, sans-serif; color: #172b34;">
      Keep artwork and labels separate
    </div>
  </foreignObject>
</svg>

Với tệp thứ hai, thay toàn bộ phần tử foreignObject bằng nhãn này rồi lưu thành native-label.svg:

<text x="180" y="96" font-family="Arial, sans-serif"
  font-size="28" fill="#172b34">
  <tspan x="180" dy="0">Keep artwork</tspan>
  <tspan x="180" dy="35">and labels</tspan>
  <tspan x="180" dy="35">separate</tspan>
</text>

Giá trị x đặt đầu mỗi dòng ở cùng vị trí ngang. Các giá trị dy đưa những dòng tiếp theo xuống dưới. Cách này chủ động bỏ tính năng xuống dòng tự động của HTML: người tạo chọn vị trí ngắt dòng và kiểm tra xem chúng có vừa không. MDN mô tả cách đặt vị trí tspan, còn librsvg liệt kê các phần tử SVG được hỗ trợ, gồm text và tspan.

Mở cả hai tệp qua đúng quy trình bàn giao, chẳng hạn công cụ chuyển đổi ảnh hoặc trình tạo PDF của bạn. Đối chiếu kết quả đã lưu, không chỉ bản xem trước nguồn. Dùng cùng kích thước với ví dụ không đảm bảo phông chữ trên máy khác sẽ giống nhau.

Nếu nhãn cũng mất trong trình duyệt

Kiểm tra tệp .svg đã tuần tự hóa, thay vì chỉ xem trang tạo ra nó. SVG nội tuyến trong HTML và tài liệu SVG độc lập là hai ngữ cảnh phân tích cú pháp khác nhau.

Ví dụ đặt rõ div trong http://www.w3.org/1999/xhtml. MDN lưu ý khai báo namespace này là bắt buộc cho nội dung HTML trong tài liệu SVG độc lập, dù một ví dụ HTML nội tuyến có thể bỏ nó. Nếu tạo phần tử bằng JavaScript, hãy dùng namespace phù hợp cho phần tử HTML con; div tạo trong namespace SVG không phải vùng chứa đoạn văn HTML.

Sau đó kiểm tra các phần này của nhãn:

  • Đặt các giá trị width và height rõ ràng, dương cho foreignObject, phù hợp với vùng nhãn dự định.
  • Giữ tọa độ x và y trong phần hình nhìn thấy, chừa chỗ cho mọi dòng.
  • Kiểm tra display, visibility, độ đục (opacity) và màu chữ của vùng chứa cùng các phần tử con.
  • Xác nhận tệp xuất có đủ kiểu hiển thị cần thiết, thay vì phụ thuộc vào stylesheet của trang web bao quanh.

Trong ví dụ, toàn bộ kiểu hiển thị nhãn đều đặt nội tuyến và hộp rộng 230 đơn vị, cao 110 đơn vị. Điều đó loại CSS bên ngoài khỏi các biến số. Nó không khiến foreignObject tương thích với bộ kết xuất thiếu tính năng này.

Với bản xuất draw.io, chuyển nhãn ngay trong nguồn

Nếu còn sơ đồ chỉnh sửa được, hãy sửa cách xuất nhãn ở đó trước khi chỉnh XML thủ công. Tài liệu xuất draw.io hiện cung cấp Convert Labels to SVG cho các nhãn có định dạng được hỗ trợ: chọn hình hoặc đường nối, mở phần Advanced của tab Text rồi bật hộp kiểm.

Tùy chọn đó có giới hạn. Tài liệu loại trừ khỏi phép chuyển đổi các nhãn chứa cấu trúc như bảng, danh sách, liên kết hoặc màu nền. Nếu không có tùy chọn này, tắt Formatted Text và Word Wrap là một cách khác được tài liệu mô tả; bạn có thể cần chèn ngắt dòng thủ công rồi kiểm tra bố cục lại.

Xuất bản sao mới và mở lại trong ứng dụng tiếp nhận. Ẩn cảnh báo ‘Text is not SVG’ không chuyển đổi nhãn. Nhúng phông chữ giải quyết sự phụ thuộc vào phông chữ, không giải quyết việc thiếu hỗ trợ bố trí HTML.

Với sơ đồ có hình minh họa, hãy giữ phần hình nhập riêng với nhãn. Hướng dẫn hình SVG tùy chỉnh trong draw.io trình bày phần hình của quy trình đó.

Chọn định dạng văn bản cho người tiếp nhận

Văn bản thuần SVG là cách sửa hữu ích khi người nhận cần sửa nội dung, nhưng vẫn phụ thuộc vào phông chữ dùng được. Nếu nhãn hiện sai kiểu chữ, hãy làm theo các bước kiểm tra phông chữ SVG thay vì xem đó là cùng lỗi mất vùng chứa.

Nhu cầu bàn giaoLựa chọn thực tếĐiều cần kiểm tra
Nội dung chữ chỉnh sửa đượctext thuần SVG với vị trí dòng được chọn có chủ đíchPhông chữ, độ dài dòng và trình chỉnh sửa tiếp nhận
Hình chữ cố địnhChuyển chữ cuối cùng thành đường bao trong trình chỉnh sửa nguồnDiện mạo đúng; giữ bản gốc chỉnh sửa được
Bố cục phong phú chỉ dùng trong trình duyệtGiữ foreignObject khi cách dùng trình duyệt đó đáp ứng yêu cầuTệp nhúng hoặc độc lập thực tế
Chỉ cần diện mạoXuất PNG từ bộ kết xuất hiển thị đầy đủ thiết kếKích thước pixel và chữ nhỏ nhất ở kích thước bàn giao

Chuyển chữ thành đường bao chỉ hoạt động khi công cụ nguồn thấy và chuyển đổi được chữ. Mở một bản xuất đã thiếu nội dung rồi chuyển đổi những đối tượng còn lại không thể khôi phục các từ vắng mặt trong tài liệu đã nhập đó. PNG giữ pixel, nên không phù hợp khi người nhận cần chữ chỉnh sửa được hoặc đường cắt vector.

PerfectVector phù hợp ở đâu trong một thẻ minh họa

Nếu hình minh họa trên thẻ chỉ có dạng PNG hoặc JPG, quy trình clipart thành SVG của PerfectVector có thể chuẩn bị một bản vector ứng viên cho phần hình đó. Giữ nội dung chữ thành một phần tử văn bản riêng trong trình chỉnh sửa thiết kế. Kiểm tra mép và khoảng trống bên trong hình, thêm nhãn rồi kiểm tra tệp đã ghép trong bộ kết xuất đích.

Hướng dẫn vector hóa ảnh giải thích cách pixel trở thành đường dẫn. PerfectVector không sửa nhãn HTML trong SVG. Khi hình minh họa đã có đường dẫn tốt, hãy giữ chúng và chỉ thay nhãn bị lỗi. Ảnh chụp màn hình của nhãn đã mất không có chữ để khôi phục, còn dò nét chữ nhìn thấy sẽ tạo ra các hình thay vì nội dung chữ chỉnh sửa được.

Trước khi gửi SVG đã sửa

  1. Mở lại bản xuất trong trình duyệt và đích tiếp nhận dự định.
  2. Xác nhận mọi nhãn, kể cả dòng cuối, đều nhìn thấy.
  3. Kiểm tra phần hình không di chuyển hay đổi kích thước.
  4. Xác minh phông chữ, hoặc kiểm tra chữ đã chuyển thành đường bao ở kích thước dự định.
  5. Giữ nguồn chỉnh sửa được cùng với bản bàn giao.

Câu hỏi thường gặp

Tại sao chữ SVG hiện trong Chrome nhưng mất khi xuất PNG? Nhãn có thể là HTML bên trong foreignObject, trong khi bộ kết xuất PNG chỉ hỗ trợ một tập tính năng SVG khác. Kiểm tra mã của nhãn bị thiếu và kết xuất bản văn bản thuần SVG qua cùng cách xuất.

Thêm namespace XHTML có sửa mọi bản xuất foreignObject không? Không. Nó sửa namespace của nội dung HTML trong SVG độc lập. Đích tiếp nhận vẫn cần hỗ trợ nội dung đó, và nhãn vẫn cần kích thước phù hợp cùng kiểu hiển thị nhìn thấy được.

tspan có thể tự xuống dòng như đoạn văn HTML không? Ví dụ dùng các dòng được chỉ định rõ cùng độ lệch dọc. Nó không tái tạo bố cục đoạn văn HTML. Chọn vị trí ngắt dòng theo khoảng trống có sẵn và kiểm tra với phông chữ ở đích tiếp nhận.

Tôi có nên vector hóa cả thẻ để khôi phục nhãn không? Giữ các đường dẫn sẵn có và tạo lại nhãn từ nội dung chữ gốc. Chỉ vector hóa phần hình ở dạng pixel. Chữ được dò nét là hình học, nên không giữ nội dung chữ chỉnh sửa được.

Nguồn tham khảo

  1. MDN — foreignObject — Định nghĩa nội dung ngoại lai, thuộc tính hình học và namespace XHTML trong SVG độc lập.
  2. MDN — tspan — Giải thích cách đặt vị trí cho từng phần của văn bản thuần SVG.
  3. draw.io — Vấn đề văn bản SVG đã xuất — Mô tả chuyển nhãn thành văn bản thuần SVG, giới hạn định dạng và thiết lập xuất thay thế.
  4. GNOME — Các tính năng SVG và CSS được Librsvg hỗ trợ — Liệt kê các phần tử và thuộc tính được bộ kết xuất hỗ trợ.

Nếu hình minh họa vẫn là bitmap, hãy chuẩn bị clipart thành SVG, kiểm tra hình dạng rồi thêm văn bản riêng. Xác minh cả hai trong tệp đã xuất trước khi bàn giao.

Thêm từ blog

Bắt đầu với SVG gọn sạch hơn
và dễ chỉnh sửa hơn