我們在「為縮放魔法設置疆界」中展示了等比縮放產生的畫面過大問題,並學會如何限制 vw
的數值成長。
如果想避免 vw
數值無限制的放大或縮小,可以使用 max()
與 min()
來限制:
min( 設計稿上的值px, calc( 設計稿上的值 / 設計稿寬度 * 100vw ))
公式來限制數值放大。max( 設計稿上的值px, calc( 設計稿上的值 / 設計稿寬度 * 100vw ))
公式來限制數值縮小。有了這兩個公式,我們就能修改「實戰1」的程式碼來解決無限制縮放畫面的問題了~
只要把「實戰1」那一堆 calc( 設計稿上的值 / 設計稿寬度 * 100vw )
公式全部改成上面兩個公式即可。
修改範例
.square {
- left: calc(-10 / 375 * 100vw);
- width: calc(10 / 375 * 100vw);
- height: calc(10 / 375 * 100vw);
+ left: max(-10px, calc(-10 / 375 * 100vw));
+ width: min(10px, calc(10 / 375 * 100vw));
+ height: min(10px, calc(10 / 375 * 100vw));
}
為了版面乾淨,這邊就不全列了,可以到最下面看完整的程式碼。
結果
結果已經相當接近我們在「用等比縮放達到我心中的 pixel perfect」中所預期的目標效果了!
當視窗寬度大於設計稿寬度時,利用 min()
和 max()
讓畫面停止放大或縮小,當使用者的視窗畫面太大時,就不會感覺網站怎麼超爆大,使用體驗應該會比較舒服些。
細看第一天的展示效果可能會發現,左邊的圓圈在視窗超過 1440px
跟 375px
時,會直接固定在原地,但是右邊不會,這其實是為了呈現兩者不同而故意設計的。
absolute
盒子。100%
。top:0
與置中。index.html
圓圈外加一層盒子。
- <div class="circle1"></div>
+ <div class="lock-box">
+ <div class="circle1"></div>
+ </div>
src/normal.css
盒子最大只能與設計稿同寬,也就是 width: min(1440px, 100vw);
與 width: min(375px, 100vw);
,並且依上述方式實現即可。
.lock-box {
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, 0);
width: min(1440px, 100vw);
height: 100%;
}
@media (width < 768px) {
.lock-box {
width: min(375px, 100vw);
}
}
效果
現在我們就完全實現了「用等比縮放達到我心中的 pixel perfect」的目標效果,注意左邊圓圈的位置,當超出 1440px
與 375px
時,左邊圓圈就定在原地,相對於右邊圓圈的處理有明顯的不同。
下篇我們將介紹另一種更簡潔的延伸固定作法~那我們下篇見囉!
css/reset.css
與 index.html
可以去「實戰1」中複製,都沒變。src/normal.css
:root {
--color-red: #C22A29;
}
html, body {
overflow-x: hidden;
}
body {
background-color: black;
min-height: 100vh;
min-height: 100dvh;
color: white;
font-family: "Noto Sans TC", sans-serif;
}
/* layout */
#app {
position: relative;
left: 50%;
transform: translateX(-50%);
width: 100vw;
overflow: hidden;
padding: min(50px, calc(50 / 1440 * 100vw)) 0;
}
.container {
width: min(1340px, calc(1340 / 1440 * 100vw));
margin: auto;
display: flex;
}
.box1 {
margin-right: min(50px, calc(50 / 1440 * 100vw));
}
.box2 {
flex: 1;
}
@media (width < 768px) {
#app {
padding: min(30px, calc(30 / 375 * 100vw)) 0;
}
.container {
width: min(335px, calc(335 / 375 * 100vw));
flex-direction: column;
align-items: center;
}
.box1 {
margin-right: 0;
margin-bottom: min(20px, calc(20 / 375 * 100vw));
}
}
/* album */
.album {
width: max-content;
background: var(--color-red);
padding: min(50px, calc(50 / 1440 * 100vw));
margin-bottom: min(50px, calc(50 / 1440 * 100vw));
}
.album-inner {
position: relative;
width: min(500px, calc(500 / 1440 * 100vw));
}
.album-inner::after {
content: '';
display: block;
padding-top: 100%;
}
.album img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: contain;
}
@media (width < 768px) {
.album {
padding: min(20px, calc(20 / 375 * 100vw));
margin-bottom: min(20px, calc(20 / 375 * 100vw));
}
.album-inner {
width: min(260px, calc(260 / 375 * 100vw));
}
}
/* info */
.info-box {
padding-left: min(30px, calc(30 / 1440 * 100vw));
}
.square {
position: absolute;
top: 50%;
left: max(-10px, calc(-10 / 1440 * 100vw));
transform: translate3d(-100%,-50%,0);
width: min(20px, calc(20 / 1440 * 100vw));
height: min(20px, calc(20 / 1440 * 100vw));
background-color: var(--color-red);
}
.song {
position: relative;
font-size: min(40px, calc(40 / 1440 * 100vw));
font-weight: 700;
}
.singer {
font-size: min(32px, calc(32 / 1440 * 100vw));
}
@media (width < 768px) {
.info-box {
padding-left: min(20px, calc(20 / 375 * 100vw));
}
.square {
left: max(-10px, calc(-10 / 375 * 100vw));
width: min(10px, calc(10 / 375 * 100vw));
height: min(10px, calc(10 / 375 * 100vw));
}
.song {
font-size: min(25px, calc(25 / 375 * 100vw));
}
.singer {
font-size: min(18px, calc(18 / 375 * 100vw));
}
}
/* lyrics */
.lyrics {
font-size: min(28px, calc(28 / 1440 * 100vw));
}
@media (width < 768px) {
.lyrics {
font-size: min(14px, calc(14 / 375 * 100vw));
}
}
/* circle */
.circle1 {
position: absolute;
top: min(862px, calc(862 / 1440 * 100vw));
left: max(-100px, calc(-100 / 1440 * 100vw));
width: min(200px, calc(200 / 1440 * 100vw));
height: min(200px, calc(200 / 1440 * 100vw));
border-radius: 50%;
background-color: var(--color-red);
}
.circle2 {
position: absolute;
top: min(50px, calc(50 / 1440 * 100vw));
right: max(-50px, calc(-50 / 1440 * 100vw));
width: min(100px, calc(100 / 1440 * 100vw));
height: min(100px, calc(100 / 1440 * 100vw));
background: var(--color-red);
border-radius: 50%;
}
@media (width < 768px) {
.circle1 {
top: max(-25px, calc(-25 / 375 * 100vw));
left: max(-25px, calc(-25 / 375 * 100vw));
width: min(50px, calc(50 / 375 * 100vw));
height: min(50px, calc(50 / 375 * 100vw));
}
.circle2 {
top: min(362px, calc(362 / 375 * 100vw));
right: max(-50px, calc(-50 / 375 * 100vw));
width: min(100px, calc(100 / 375 * 100vw));
height: min(100px, calc(100 / 375 * 100vw));
}
}