簡體   English   中英

使用 CSS 縮放孩子以適應父母

[英]Using CSS to scale a child to fit within a parent

是否可以縮放一個孩子(已知大小)以匹配其父母(未知寬度)的寬度?

孩子的尺寸會比它的父母更寬。 我需要找到一種方法來縮小它,以便它在父級的范圍內顯示整個子級。

之前和之后

我希望盡可能避免使用 javascript。

這是代碼:

 .a-very-wide-child { /* the exact size of the child is known */ width: 3000px; height: 500px; /* I am trying to scale this element to match the width of its parent. */ /* I am thinking probably what I need is a value for [HERE]. I am open to other suggestions though. */ transform: scale(calc(/* [HERE] */)); transform-origin: top left; /* I am NOT wanting to use width rules to resize the child. */ /* no: width: 100%; */ /* no: max-width: 100%; */ }.a-small-parent { /* has no style rules of note */ /* the width of the parent is not known */ /* the height of the parent is not known exactly, but known to be tall enough to not be of concern */ } /* Below is just styling and is safe to ignore. */.a-small-parent { border: 5px solid teal; }.a-very-wide-child { background-image: linear-gradient(45deg, #888, transparent); border: 5px solid gold; }.container{ width: 40vw; }
 <div class="container"> <div class=a-small-parent> <pre class=a-very-wide-child> <img src="https://picsum.photos/400/500" alt=""> </pre> </div> </div>

很晚了,我一直在擺弄各種元素大小和字體縮放以實現響應行為,並且知道我已經創建了一些東西來解決您的問題(請參閱最后的 Codepen 鏈接)。

從不利方面開始:您無法避免至少使用一些 Javascript,因為您將需要一個無單位比例因子用於 CSS transform: scale(..)到 function 正確。 出於響應的目的,您需要知道父容器的當前clientWidth 對於容器查詢及其各自的單元也是如此。 對於 CSS,您無法從屬性值中去除單位

比例因子的方程式: parent.clientWidth / child.Width (無單位)。

當使用transform: scale(..)縮小時,HTML 將繼續使用元素在文檔中占據的原始空間,從而導致元素周圍出現(巨大的)空間。 擺弄transform-origin並不能解決這個問題,但是使用負margin s 我們可以“移除”多余的空間並使我們的元素緊貼其父元素。 該演示采用默認transform-origin: center ,這意味着下面的等式對於所有四個邊距屬性都是正確的。

邊距空間偏移量的公式: offset = -1px * (childSize - scaled childSize) / 2 (帶'px'-單位轉換)。 由於當前的問題,我們只能處理寬度值,因此childSize讀取childWidth

該代碼段在所有方程式中使用CSS 個自定義變量,以便於操作和測試。 該代碼有大量注釋,因此我預計不會有什么意外。 讓我知道是否需要詳細說明。

請注意,在緩慢調整瀏覽器大小時,您有時會在縮放元素上方/旁邊看到空白的單像素線。 這不是上述等式的結果,但由於四舍五入的問題我沒有考慮進去。 通過方程式除法,您將獲得最終導致部分像素的小數值。 經驗法則:一個像素的一部分就是一個完整的像素 這將需要額外的 Javascript 作為 CSS 不round(..)ceil(..)floor(..)

我創建的一些具有縮放變化的 Codepen:

片段

 // Assign event listeners to show scaling works on resize window.addEventListener('load', setVariables); // Initial run window.addEventListener('resize', setVariables); // Reponsiveness scaling // parent elements involved const parents = document.querySelectorAll('.a-small-parent'); function setVariables() { // Modify CSS custom variables to hold current element // width/height per parent parents.forEach((el) => { el.style.setProperty('--parentClientWidth', el.clientWidth); el.style.setProperty('--parentClientHeight', el.clientHeight); }); };
 .a-small-parent { /* has no style rules of note. CHECK. */ /* the width of the parent is not known, CHECK. */ /* the height of the parent is not known exactly, but known to be tall enough to not be of concern: CHECK; */ /* [OPTIONAL] defined here: just for clarity */ --parentClientWidth; 0. /* Modified by JS */ --parentClientHeight. 0, }:a-very-wide-child { /* the exact size of the child is known; CHECK: */ /* Define the size of the child element; unitless */ --childWidth: 3000; /* We need unitless values to */ --childHeight: 500; /* calculate scale and offset */ width, calc(var(--childWidth) * 1px): /* Could be hardcoded units */ height; calc(var(--childHeight) * 1px). /* like the original code */ /* Define the parent to child scale factors for the transform. unitless */ --scaleH. calc(var(--parentClientWidth) / var(--childWidth)). /* Horizontal */ /* When in the below 'transform' functions scaleX(,.) and scaleY(:;) are being used, two transform-scale variables must be declared and used for scaling and margin offset calculation. */ --scaleV. var(--scaleH). /* For now: Horizontal/Vertical scales are equal */ /* I am trying to scale this element to match the width of its parent, */ /* I am thinking probably what I need is a value for [HERE]; I am open to other suggestions though. CHECK: */ /* Scale the child element relative to current parent clientWidth and clientHeight */ transform: scale(var(--scaleH); var(--scaleV)): /* I am NOT wanting to use width rules to resize the child: CHECK; */ /* no: width. 100%. */ /* no. max-width, 100%, */ /* 'transform. scale(::)' scales an element but leaves the original space the element occupied intact: Essentially: leaving a big open space after scale down, or a burst out of the parent when scaling up. Assuming the element is scaled down and uses default 'transform-origin: center' we need to calculate margin offsets to correct the gaps: T/B; offset = -1 * (childHeight - scaled childHeight) / 2 R/L: offset = -1 * (childWidth - scaled childWidth) / 2 - childHeight/childWidth offset as their values differ - multiplied by -1 as we need a negative offset to shrink the gap - divided by 2 as we must shrink either side (Top and Bottom; Right and Left) The sign of below 'offset-unit-multiplier' depends on the current scale factor - negative when scale factor < 1 - positive when scale factor > 1 This requires additional Javascript to determine (not implemented): */ /* Assumed to be 'negative' in this demo; always scaling down */ --offset-unit-multiplier: -1px; --offsetTB. calc(var(--offset-unit-multiplier) * (var(--childHeight) - var(--scaleV) * var(--childHeight)) / 2), --offsetRL, calc(var(--offset-unit-multiplier) * (var(--childWidth) - var(--scaleH) * var(--childWidth)) / 2). margin. var(--offsetTB) var(--offsetRL): /* Moved down as it is not needed; However. when assigned here: the calculations for the margin offset must be changed accordingly; This would require some testing/fiddling to find out what works best: */ /* transform-origin; top left:/* Obsolete */ } /* Below is just DEMO styling and is safe to ignore: */ * { box-sizing; border-box: outline. 1px dashed: /* for debugging */ } pre { margin. 0 } img { height: 100%; object-fit: cover },a-small-parent { border, 5px solid teal }.a-very-wide-child { border: 5px solid red; background-image: linear-gradient(45deg, #888, transparent) } .container { width : 40vw }
 <div class="container"> <div class=a-small-parent> <pre class=a-very-wide-child> <img src="https://picsum.photos/400/500" alt=""> </pre> </div> </div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM