Vòng tròn SVG phải thích ứng với chiều cao lưới CSS mà không bị chồng chéo


8

Trong ví dụ sau, vòng tròn thích ứng với chiều rộng lưới và giữ tỷ lệ khung hình của nó. Khi chiều rộng của container co lại, các vòng tròn co lại với nó ...

Tuy nhiên, khi chiều cao nhỏ hơn chiều rộng (hộp thứ hai), vòng tròn không co lại chồng chéo bên ngoài lưới thay vào đó Có cách nào để nó thích ứng với chiều cao quá trong khi vẫn giữ tỷ lệ khung hình không?

.container {
	display: grid;
	background-color: greenyellow;
	margin: 5px;
	min-height: 10px;
	min-width: 10px;
}

.portrait {
		max-height: 100px;
		max-width: 200px;
}

.landscape {
		max-height: 200px;
		max-width: 100px;
}

.aspect-ratio {
	grid-column: 1;
	grid-row: 1;
	background-color: deeppink;
	border-radius: 50%;
 align-self: center;
	justify-self: center;
}
<div class="container landscape">
  <svg class="aspect-ratio" viewBox="0 0 1 1"></svg>
</div>

<div class="container portrait">
  <svg class="aspect-ratio" viewBox="0 0 1 1"></svg>
</div>

Kết quả sẽ như thế này: nhập mô tả hình ảnh ở đây


Bạn có khả năng chỉnh sửa mã svg không?
thetont

Câu trả lời:


8

Sau khi loay hoay một thời gian với vấn đề này, tôi nghĩ rằng đây không phải là vấn đề với bố cục lưới.

Vì bạn không bao giờ xác định chiều cao / chiều cao tối đa hoặc chiều rộng / chiều rộng tối đa cho SVG của mình, những gì đang được tính toán là width:autoheight:auto

Lưu ý: Tôi hiển thị chiều cao tối đa / chiều rộng tối đa vì các giá trị này sẽ được ưu tiên hơn các giá trị chiều rộng / chiều cao .


Bây giờ, tại sao bố cục phong cảnh của bạn hoạt động và bố cục chân dung của bạn không hoạt động? Bởi vì chiều rộng là "ưu tiên" so với chiều cao của bạn.

Và đó là lý do tại sao, trong bố cục khối, chiều cao tự động dựa trên tổng chiều cao của con cháu và chiều rộng tự động dựa trên chiều rộng khối chứa.

Nguồn - Tại sao width: auto hoạt động khác với height: auto?

Điều này có nghĩa là SVG của bạn đang lấy widthtừ thùng chứa của nó và heighttừ hậu duệ của nó.

Trong ví dụ của bạn, SVG của bạn không có con cháu, nhưng có cha mẹ với chiều rộng tối đa được xác định . Nhưng điều này có ý nghĩa gì đối với chiều cao của SVG ?

SVG đang tính toán chiều cao của nó thông qua tỷ lệ intrisic:

Nếu phần tử 'viewBox' trên phần tử 'svg' được chỉ định chính xác:

  1. đặt viewbox là viewbox được xác định bởi thuộc tính 'viewBox' trên phần tử 'svg'
  2. trả về viewbox. thong / viewbox.height

Nguồn

Và tỷ lệ intrisic của bạn là 1/1 = 1

Vì vậy, bạn đang ép buộc height=width


Bản đồ đường viền)

Giải pháp là đặt a widthhoặc a margincho SVG của bạn tùy thuộc vào tỷ lệ div gốc của bạn.

Trong ví dụ bạn đã đưa ra, bạn có tỷ lệ 2: 1 vì vậy SVG của bạn nên có width:50%hoặc margin: 0 25%.

Điều này có nghĩa là nếu bạn muốn đặt một tỷ lệ khác, bạn phải điều chỉnh cho phù hợp (xem chân dung-1-3 trong mã dưới đây).

Có thể tránh đặt quy tắc CSS cho từng tỷ lệ nếu heightkhông phải là một ràng buộc, vì bạn có thể xác định một widthcho SVG và vùng chứa của mình, để các thành phần điều chỉnh heightđể giữ tỷ lệ khung hình của bạn.

Tôi cũng đã thêm một ví dụ cuối cùng nếu ai đó không quan tâm đến việc giữ tỷ lệ khung hình nhưng cần chứa SVG trong một bộ heightwidththùng chứa.

.container {
  display: grid;
  background-color: greenyellow;
  margin: 5px;
  min-height: 10px;
  min-width: 10px;
}

.portrait {
  max-height: 100px;
  max-width: 200px;
}


/* Add 25% margin left and right to center the image  OR set the image width to 50% */

.portrait>.aspect-ratio {
  margin: 0 25%;
  /*
    or 
    
    width:50%;
  */
}

.landscape {
  max-height: 200px;
  max-width: 100px;
}

.aspect-ratio {
  grid-column: 1;
  grid-row: 1;
  background-color: deeppink;
  border-radius: 50%;
  align-self: center;
  justify-self: center;
}


/* Set fixed max-height and max-width rule (33% proportion)  */

.portrait-1-3 {
  max-height: 100px;
  max-width: 300px;
}


/* Align image with the new proportion */

.portrait-1-3>.aspect-ratio {
  margin: 0 33.33%;
  /*
    or 
    
    width:33.3%;
  */
}


/* Removed max-height and let the container adjust the height according to the max-width rule and the proportion set  */

.portrait-any-height {
  max-width: 400px;
}


/* Height will be adjusted through the width/margin defined here, so 10% width will correspond to 40px of height (10%*400px)*(aspect ratio=1)*/

.portrait-any-height>.aspect-ratio {
   width:10%;
}


/* Set fixed max-height and max-width rule (proportion doesn't matter)  */

.portrait-squeezed {
  max-height: 100px;
  max-width: 300px;
}


/* Make sure SVG complies with the the given max with and height (squeezing your svg)  */

.portrait-squeezed>.aspect-ratio {
  max-height: inherit;
  max-width: inherit;
}
<div class="container landscape">
  <svg class="aspect-ratio" viewBox="0 0 1 1"></svg>
</div>

<div class="container portrait">
  <svg class="aspect-ratio" viewBox="0 0 1 1"></svg>
</div>

<div class="container portrait-1-3">
  <svg class="aspect-ratio" viewBox="0 0 1 1"></svg>
</div>

<div class="container portrait-any-height">
  <svg class="aspect-ratio" viewBox="0 0 1 1"></svg>
</div>

<div class="container portrait-squeezed">
  <svg class="aspect-ratio" viewBox="0 0 1 1"></svg>
</div>

Xin lưu ý rằng tôi không thành thạo khi làm việc với SVG và phản hồi này là kết quả của nghiên cứu và rất nhiều thử nghiệm! Tôi rất vui khi nhận được bất kỳ điều chỉnh và / hoặc sửa chữa cho phản hồi của tôi.


Cảm ơn đã giải thích chi tiết ... Tôi phải lưu ý rằng nghiên cứu của bạn không may trả lại kết quả giống như của tôi. Dường như không có giải pháp nào cho yêu cầu của tôi: 1. Tỷ lệ khung hình SVG là cố định. 2. tỷ lệ khung hình của thùng chứa là biến / không xác định 3. kích thước vùng chứa bị giới hạn bởi cả chiều cao và chiều rộng tùy thuộc vào môi trường (ví dụ: kích thước cửa sổ trình duyệt) Giải pháp được đề xuất bằng cách đặt chiều rộng SVG thành một tỷ lệ phần trăm nhất định của container, sẽ hoạt động nếu vùng chứa có tỷ lệ khung hình cố định, nhưng nó không.
Th3S4mur41

Tăng chiều cao tối đa cũng không hiệu quả, điều đó chỉ có nghĩa là chuyển vấn đề tràn sang phụ huynh
Th3S4mur41

Với 3 yêu cầu đó, dường như không có giải pháp nào, đó là chỉ sử dụng CSS. Có phải đang sử dụng Javascript để tính chiều rộng SVG phù hợp không?
H. Figueiredo

Đó là những gì giải pháp hiện tại của tôi đang làm mà tôi muốn tránh;)
Th3S4mur41

Tôi hy vọng rằng tỷ lệ khung hình sẽ giúp giải quyết điều này, nhưng tôi thậm chí không chắc chắn về điều đó. dự thảo.csswg.org/css
Th3S4mur41

0

Thêm vào chiều cao và chiều rộng cụ thể của container bên cạnh chiều cao tối đa và chiều rộng tối đa.

đơn vị vw & vh có thể được sử dụng để làm cho bố cục này linh hoạt hơn.

  max-height: 100px;
  max-width: 200px;
  width: 100vw;
  height: 100vh;

Bằng cách này, nó có thể được đặt thành max-width: 100%; max-height: 100%;svg và nó sẽ không trùng nhau.


-BIÊN TẬP-

Vì khung nhìn của Svg đã được hiển thị với tỷ lệ khung hình chính xác, nên việc di chuyển nền svg bên trong chính Svg để có kết quả như mong đợi là an toàn: thẻ cicle sẽ thực hiện thủ thuật.

Có thể bắt chước bán kính đường viền bằng thẻ vòng tròn khác trong mặt nạ không

Tất cả các yếu tố khác của svg sau đó nên được đặt trong một nhóm đeo mặt nạ. I E:<g mask="url(#mask)">

.container {
  display: grid;
  background-color: greenyellow;
  margin: 5px;
  min-height: 10px;
  min-width: 10px;
}

.portrait {
  max-height: 100px;
  max-width: 200px;
  width: 100vw;
  height: 100vh;
}

.landscape {
  max-height: 200px;
  max-width: 100px;
  width: 100vw;
  height: 100vh;
}

.aspect-ratio {
  grid-column: 1;
  grid-row: 1;
  align-self: center;
  justify-self: center;
  max-width: 100%;
  max-height: 100%;
}

.aspect-ratio .bkg{
  fill: deeppink;
}
<div class="container landscape">
  <svg class="aspect-ratio" viewBox="0 0 1 1">
    <mask id="mask">
      <circle cx=".5" cy=".5" r=".5" fill="#fff"/>
    </mask>
    <circle cx=".5" cy=".5" r=".5" class="bkg"/>
    <g  mask="url(#mask)">

    </g>
  </svg>
</div>

<div class="container portrait">
  <svg class="aspect-ratio"viewBox="0 0 1 1">
    <mask id="mask">
      <circle cx=".5" cy=".5" r=".5" fill="#fff"/>
    </mask>
    <circle cx=".5" cy=".5" r=".5" class="bkg"/>
    <g  mask="url(#mask)">

    </g>
  </svg>
</div>


1
Câu hỏi được chỉ định "Có cách nào để nó thích ứng với chiều cao không trong khi vẫn giữ tỷ lệ khung hình" mà ví dụ của bạn không có. Đó là một cách để buộc SVG bên trong container nhưng nó sẽ không tạo ra kết quả như mong muốn. Nó giống như ví dụ cuối cùng về phản ứng của tôi trong đó Svg được vắt để phù hợp với container
H. Figueiredo

Lời giải thích có thể hơi bối rối nhưng với giải pháp cho thấy chiều cao của Svg thích ứng với chiều cao của container.
thetont

Nhưng nó không giữ tỷ lệ khung hình SVG ! Bạn đã thấy kết quả mong muốn mà OP đăng tải chưa?
H. Figueiredo

Ồ, wow ... Tôi vừa kiểm tra nó bằng Chrome và bây giờ tôi hiểu bạn đang nói gì. Tôi đã mã hóa nó trên Firefox và với trình duyệt đó, nó hoạt động như dự định, tôi không mong đợi kết quả quá khác biệt. Xấu của tôi
thetont

Đó thực sự là một hành vi khá thú vị, tôi đoán Firefox và Chrome tính toán khác nhau 100%? Dù sao, tất cả chúng ta đều phạm sai lầm, nếu không thì SO sẽ không tồn tại: D
H. Figueiredo
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.