Use the percentage value of margin/padding to achieve high self-adaptation (mostly used for placeholder, to avoid flickering), marginpadding
A basic but confusing css knowledge point
This article relies on a basic but confusing css knowledge point: when margin/padding is taken as a percentage value, whether it is left/right or top/bottom, all are based on the width of the parent element!
Maybe you will say that left/right is easy to understand with the width of the parent element as the reference object, but why does top/bottom take the width of the parent element as the reference object?
1. highly adaptive placeholder
Suppose there is a scenario:
As shown in, there is a container for storing images. The images are square (for the convenience of using square for example, you only need to fix the ratio of length to width ).
On the PC side, the width and height of the container are all written to the px, so that even if the image cannot be loaded, the container will not change. However, on the Mobile End, since the resolution difference between different models is too large, it is absolutely impossible to write the dead px. After all, it is necessary to achieve self-adaptation by percentage:
Set the container width to 50%, so that two containers are placed in one row, each accounting for half of the screen width. No problem.
Set the image width to 100% to get the container width. No problem.
The container height cannot be set. Because the reference object with the container width height is different and the requirement is that the height is the same as the width, you cannot set the percentage for the container height, then we can only rely on the content.
The content height of the container is the image height. If the image is square, the image height is the same as the image width, that is, the image width is the same. It seems OK, right? In fact, before the browser loads the image, the image height is zero, so there is no way to open the container. In this way, even if the image loading speed is fast, the container has a variant process before and after image loading, which is also known as "flashing". If the image cannot be loaded, the overall layout will be even more difficult.
Now the problem has come out, that is, how to expand the height of the container without relying on the image itself.
Set the container padding-bottom/top
The key to solving the adaptive height using the percentage value of margin/padding is that the percentage of the container margin/padding is the width of the parent element, the percentage of width in the container is also the width of the parent element. If the two attributes are the same, it is easy to unify the values of these two attributes.
The optimization scheme is as follows: set the value (percentage) of padding-top/padding-bottom consistent with width for the container ).
1 <div id="container" class="placeholder"></div>
1 # container {2 width: 50%; // half of the width of the parent element 3 background-color: red; // for convenience only} 4. placeholder {5 padding-top: 50%; // consistent with width: 50%;, that is, half of the width of the parent element. 6}
Result: The visual effect of the container is as follows:
The container box model is as follows:
As can be seen from the box model, although the content height of the container is 0, the overall visual effect is stretched out due to the padding with the same content width. The browser compatibility of this solution is very good. The only defect is that the max-height attribute cannot be set for the container, because max-height can only limit the content height, the padding cannot be restricted (I thought setting box-sizing: border-box; max-height can be used to limit the padding, but it is not valid in the test)
Set margin/padding for sub-element/pseudo-element to open the container
From the above solution, we can see that the reason for max-height failure is that the height of the container is originally supported by padding, while the content height is 0, and max-height cannot work. To optimize this point, the only method is to use the content height to expand rather than padding. This solution is very similar to the solution used to eliminate floating: add a sub-element/pseudo element to the container, set the sub-element/pseudo-element margin/padding to 100%, so that the actual height is equivalent to the container width, so that the container height can be consistent with the width. Since adding sub-elements is different from HTML semantics, we recommend that you use pseudo elements (: after) to implement this solution.
1 <div id="container" class="placeholder"></div>
# Container {width: 50%; position: relative; background-color: red; overflow: hidden; // The problem that BFC needs to be triggered to remove margin folding }. placeholder: after {content: ''; display: block; margin-top: 100%; // The percentage of margin relative to the width of the parent element}
At this time, the visual effect is similar to the previous solution. Let's take a look at the container's box model:
As you can see, the height of the container content is the same as the width of the content. Mom no longer needs to worry that I cannot use max-height to limit the height of the container.
In addition, if you use margin, you need to consider the margin folding issue (refer to). padding does not have to worry about this.
How to add content inside the container
The above solution only mentions how to open a container without relying on the container content. How to add content (images, text, etc.) to the container after the container is opened?
The answer is simple: Use position: absolute;
1 <div id="container" class="placeholder">2 3 </div>
1 # container {2 width: 50%; 3 position: relative; 4 background-color: red; 5 overflow: hidden; // The problem that BFC needs to be triggered to eliminate margin folding 6} 7. placeholder: after {8 content: ''; 9 display: block; 10 margin-top: 100%; // The percentage of margin relative to the width of the parent element is calculated as 11} 12 img {13 position: absolute; 14 top: 0; 15 width: 100%; 16}
Post-completion
How does one implement auto-adaptation with inconsistent width and height?
Some may ask, the width and height mentioned above are the same. What if they are different? In fact, the focus of self-adaptation is that the width and height of elements must maintain a fixed proportion. For example, the consistent ratio of width and height is, and the ratio of width to height is, as long as the ratio is clear and fixed, you only need to modify the percentage value of margin/padding to adapt to different width ratios.
Are there other wide and high adaptive solutions?
Of course, for example, the length unit vw introduced by css3 is to take the screen width as the reference object, as long as the width and height of the element are used with the vw unit, then width and height can be easily set to the same, but since it is css3, browser compatibility is certainly a problem:
Summary
The essence of adaptive is width. The percentage of margin/padding makes up for the defect that the element height cannot be adaptive to the element width.