切版實戰

demo

素材下載

前置作業

參考 SCSS 建立專案

flowchart LR
    A[fa:fa-folder project root]
    A-->dist[fa:fa-folder dist]
    dist-->css[fa:fa-folder css]
    dist-->js[fa:fa-folder js]
    dist-->images[fa:fa-folder images]
    dist-->index[fa:fa-file index.html]
    css-->|fa:fa-ban 禁止異動| cssfile[fa:fa-file some.css]
    A-->src[fa:fa-folder src]
    src-->scss[fa:fa-folder scss]
    scss-->scssfile[fa:fa-file some.scss]
    scssfile-->|fa:fa-bolt 編譯產生| cssfile

建立 src/scss/_reset.scss

*,
*::after,
*::before {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

建立 src/scss/index.scss

@import 'reset';

使用 Watch Sass 編譯,看到 dist/css/index.css 表示前置作業完成

Step 1

建置 header 架構

dist/index.html

<div id="header">
    <div>Logo</div>
    <div>Menu</div>
</div>

demo

Step 2

編輯 header 樣式

看起來內容有局限在一定範圍內,所以先將 header 套入 .container

dist/index.html

<div id="header">
    <div class="container">
        <div class="header-content">
            <div>Logo</div>
            <div>Menu</div>
        </div>
    </div>
</div>

增加 .container 樣式

src/scss/_reset.scss

.container {
    max-width: 1000px;
    height: 100%;
    padding: 0 30px;
    position: relative;
    margin: auto;
}

加入 .header-content 樣式

src/scss/index.scss

#header {
    height: 80px;
    .header-content {
        height: 100%;
        display: flex;
        justify-content: space-between;
        align-items: center;
        background: rgb(240, 240, 240);
        padding: 0 15px;
        border-bottom-right-radius: 8px;
        border-bottom-left-radius: 8px;
    }
}

demo

Step 3

編輯 logomenu

dist/index.html

<div>
    <a href=""><img src="images/logo.svg" alt="appedu" /></a>
</div>
<div class="header-menu">
    <ul>
        <li>
            <a href="#">
                <div class="en">About Us</div>
                <div>關於赫綵</div>
            </a>
        </li>
        <li>
            <a href="#">
                <div class="en">Join Us</div>
                <div>加入赫綵</div>
            </a>
        </li>
        <li>
            <a href="#">
                <div class="en">Courses</div>
                <div>課程總覽</div>
            </a>
        </li>
    </ul>
</div>

加入 ula 的初始化

src/scss/_reset.scss

ul {
    list-style-type: none;
}

a {
    color: inherit;
    text-decoration: none;
}

加入 header-menu 樣式

src/scss/index.scss

#header {
    // ...

    .header-menu {
        ul {
            display: flex;

            li {
                font-weight: 700;
                text-align: center;
                margin-right: 30px;

                &:last-child {
                    margin-right: 0;
                }

                .en {
                    text-transform: uppercase;
                    font-size: 10px;
                }
            }
        }
    }
}

demo

Step 4

建立一頁式表單區塊

dist/index.html

<div id="join-form">
    <div class="container">
        <div>LEFT</div>
        <div>RIGHT</div>
    </div>
</div>

加入 #join-form 樣式

src/scss/index.scss

#join-form {
    min-height: 100vh;
    background-color: #000;
    background-image: url(../images/banner.jpeg);
    background-size: cover;
    color: #fff;
}

#header 設定為 fixed

src/scss/index.scss

#header {
    position: fixed;
}

此時發現區塊沒有滿版,調整一下

src/scss/index.scss

#header {
    position: fixed;
    width: 100%;
}

滿版了,但是點不到選單

src/scss/index.scss

#header {
    position: fixed;
    width: 100%;
    z-index: 9;
}

demo

Step 5

編輯表單內容區塊

dist/index.html

<div id="join-form">
    <div class="container">
        <div class="join-content">
            <div>LEFT</div>
            <div>RIGHT</div>
        </div>
    </div>
</div>

加入 .join-content 樣式

src/scss/index.scss

#join-form {
    // ...

    .join-content {
        width: 100%;
        height: 500px;
        background: rgba(10, 70, 161, 0.879);
    }
}

因為要讓區塊在畫面中間,使用 flex 水平垂直置中

增加 #join-form 樣式

src/scss/index.scss

#join-form {
    // ...

    display: flex;
    align-content: center;
    justify-content: center;

    // ...
}

此時發現 .join-content 沒有如預期的寬度滿版

發現是 .container 受到 flex 影響沒有滿版

增加 .container 樣式

src/scss/_reset.scss

.container {
    // ...
    flex: 1;
}

demo

Step 6

設計表單內容

dist/index.html

<div id="join-form">
    <div class="container">
        <div class="join-content">
            <div class="join-content-left">
                <h3 class="slogan">加入赫綵,人生精彩</h3>
                <div class="join-text">
                    就我個人來說,加入赫綵對我的意義,不能不說非常重大。一般來說,儘管如此,我們仍然需要對加入赫綵保持懷疑的態度。加入赫綵可以說是有著成為常識的趨勢。這必定是個前衛大膽的想法。培根說過一句很有意思的話,知識貧乏最能讓人生出許多懷疑。請諸位將這段話在心中默念三遍。儘管如此,別人往往卻不這麼想。
                </div>
            </div>
            <div class="join-content-right">
                <h3 class="slogan">加入赫綵,就是現在</h3>
                <div>
                    <input type="text" placeholder="姓名" class="form-control" />
                </div>
                <div>
                    <input type="text" placeholder="信箱" class="form-control" />
                </div>
                <div class="text-end">
                    <button class="btn">立即加入</button>
                </div>
            </div>
        </div>
    </div>
</div>

增加樣式

src/scss/index.scss

#join-form {
    // ..,
    .join-content {
        // ...

        display: flex;
        padding: 20px;

        > div {
            width: 50%;
        }

        .join-content-left {
            border-right: 2px dashed #fff;
            padding-right: 20px;
        }

        .join-content-right {
            padding-left: 20px;
        }
    }
}

加入 .slogan 通用樣式

src/scss/_reset.scss

.slogan {
    text-align: center;
    font-size: 26px;
    padding-top: 30px;
    padding-bottom: 10px;
    margin-bottom: 20px;
    position: relative;

    &::after {
        content: '';
        position: absolute;
        bottom: 0;
        left: calc(50% - 140px);
        width: 0;
        height: 3px;
        border-left: solid 100px #1072c2;
        border-right: solid 180px #fff;
    }
}

加入 .join-text 樣式

src/scss/index.scss

#join-form {
    // ..,

    .join-content {
        // ...

        .join-text {
            line-height: 30px;
            text-align: justify;
        }
    }
}

加入 .form-control.btn 樣式

src/scss/index.scss

#join-form {
    // ..,

    .join-content {
        // ...

        .form-control {
            width: 100%;
            height: 40px;
            margin-bottom: 20px;
            padding: 0 15px;
            font-size: 16px;
            border-radius: 3px;
            border: 0;
            outline: 0;
        }

        .btn {
            padding: 10px 15px;
            border: 0;
            outline: 0;
            background: rgb(64, 5, 165);
            color: #fff;
            font-size: 14px;
            font-weight: 700;
            letter-spacing: 1px;
            border-radius: 3px;
            cursor: pointer;

            &:hover {
                background: rgb(84, 31, 175);
            }
        }
    }
}

加入 .text-end 通用樣式

src/scss/_reset.scss

.text-end {
    text-align: right;
}

#join-content 高度改為為最小高度,讓內容自動擴增

src/scss/index.scss

#join-form {
    // ...

    .join-content { 
        // ...

        // height: 500px;
        min-height: 200px;

        // ...
    }
}

demo

Step 7

建立課程顧問頁面

dist/index.html

<div id="courses">
    <h3 class="slogan">課程顧問</h3>
</div>

加入 #courses 樣式

src/scss/index.scss

#courses {
    height: 50vh;
    background-image: url(../images/process.jpeg);
    background-size: cover;
    padding-top: 30px;
    padding-bottom: 30px;
    color: #fff;
}

demo

此時發現背景圖片白色與字體白色色調太近,文字可讀性低

Step 8

加入 .mask 樣式

src/scss/_reset.scss

.mask {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.438);
}

#courses 區塊調整

dist/index.html

<div id="courses">
    <div class="courses-content">
        <h3 class="slogan">課程顧問</h3>
    </div>
    <div class="mask"></div>
</div>

增加對應樣式

src/scss/index.scss

#courses {
    // ...

    position: relative;

    .courses-content {
        position: relative;
        z-index: 2;
    }
}

demo

Step 9

製作 timeline

dist/index.html

<div class="timeline">
    <div class="item">
        <div class="circle"></div>
        <div class="text">
            <h3>需求訪談</h3>
            <div>深度了解需求,給予最適合的建議</div>
        </div>
    </div>
</div>

增加 .timeline 樣式

src/scss/_reset.scss

.timeline {
    position: relative;
    width: 100%;
}

增加 .item 樣式

src/scss/_reset.scss

.timeline {
    // ...

    .item {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100%;
        position: relative;
        padding-top: 20px;
        padding-bottom: 20px;
        word-break: break-all;
    }
}

增加 .circle 樣式

src/scss/_reset.scss

.timeline {
    // ...

    .item {
        // ...

        .circle {
            width: 24px;
            height: 24px;
            border-radius: 24px;
            background: red;
        }
    }
}

此時 .circle 並沒有在中間,因為他與 .text 一同分享 .itemflex 空間

增加 .text 樣式

scr/scss/_reset.scss

.timeline {
    // ...

    .item {
        // ...

        .text {
            position: absolute;
            padding: 20px;
            background: red;
            border-radius: 8px;
        }
    }
}

透過 padding 產生內距,由內容稱出寬高,避免固定寬高破版

此時 .text 蓋在 .circle 上面,須將 .text 推到旁邊

.timeline {
    // ...

    .item {
        // ...

        .text {
            // ...

            left: calc(50% + 50px);
        }
    }
}

此時 .circle 因為 .text 設定為 position: absolute; 已經不佔據寬高,所以獨享 .item

calc+ 符號兩邊要留空白,不然編譯會出問題

增加白色虛線

src/scss/_reset.scss

.timeline {
    // ...

    &::after {
        content: '';
        position: absolute;
        border-left: 4px dashed #fff;
        height: 100%;
        left: calc(50% - 2px);
        top: 0;
    }

    // ...
}

此時 .circle 被白色虛線壓住了,調整一下

src/scss/_reset.scss

.timeline {
    // ...

    .item {
        // ...

        z-index: 2;
    }
}

增加第二個 .item

dist/index.html

<div class="timeline">
    <!-- ... -->

    <div class="item">
        <div class="circle"></div>
        <div class="text">
            <h3>課程搭配</h3>
            <div>提供專業課程配套方案</div>
        </div>
    </div>
</div>

將偶數 .item 內的 .text 往另一邊推

src/scss/_reset.scss

.timeline {
    // ..

    .item {
        // ...

        &:nth-child(even) {
            .text {
                right: calc(50% + 50px);
                text-align: right;
            }
        }
    }
}

看起來怪怪的,這是因為原先的 .text 已經有 left 屬性,在 CSS 覆寫疊加機制下,最終偶數 .item.text 會變成

.text {
    // ...

    left: calc(50% + 50px);
    right: calc(50% + 50px);
}

一下子要左邊一下子要右邊,搞得我好亂啊!

使用 unsetleft 取消設定

src/scss/_reset.scss

.timeline {
    // ..

    .item {
        // ...

        &:nth-child(even) {
            .text {
                // ...

                left: unset;
            }
        }
    }
}

將剩下的區塊補完

dist/index.html

<div class="timeline">
    <div class="item">
        <div class="circle" data-color="yellow"></div>
        <div class="text">
            <h3>需求訪談</h3>
            <div>深度了解需求,給予最適合的建議</div>
        </div>
    </div>
    <div class="item">
        <div class="circle"></div>
        <div class="text">
            <h3>課程搭配</h3>
            <div>提供專業課程配套方案</div>
        </div>
    </div>
    <div class="item">
        <div class="circle"></div>
        <div class="text">
            <h3>免費試聽</h3>
            <div>實際體驗課程狀況</div>
        </div>
    </div>
    <div class="item">
        <div class="circle"></div>
        <div class="text">
            <h3>分期付款</h3>
            <div>提供無壓力的付款方式</div>
        </div>
    </div>
    <div class="item">
        <div class="circle"></div>
        <div class="text">
            <h3>課後關懷</h3>
            <div>關心上課情況,給予適度調整</div>
        </div>
    </div>
    <div class="item">
        <div class="circle"></div>
        <div class="text">
            <h3>就業輔導</h3>
            <div>結訓後,提供就業媒合</div>
        </div>
    </div>
</div>

補完發現,內容跑去外面了(破版),這是因為 #courses 設定固定高度 height: 50vh;

src/scss/index.scss

#courses {
    // height: 50vh;
    min-height: 50vh;
}

.timeline 內的第一個 .item 與最後一個 .item 調整一下,讓線條可以突出

src/scss/_reset.scss

.timeline {
    // ...
    
    .item {
        // ...

        &:first-child {
            padding-top: 50px;
        }

        &:last-child {
            padding-bottom: 50px;
        }
    }
}

設定交錯顏色

src/scss/_reset.scss

.flow {
    // ...

    .item {
        // ...

        .circle {
            // ...

            background: rgb(10, 149, 151);
        }

        .text {
            // ...

            background: rgb(10, 149, 151);
        }

        &:nth-child(even) {
            .circle {
                background: blue;
            }
            .text {
                // ...

                background: blue;
            }
        }

        &:nth-child(3n) {
            .circle {
                background: red;
            }
            .text {
                background: red;
            }
        }

        &:nth-child(4n) {
            .circle {
                background: rgb(10, 149, 151);
            }
            .text {
                background: rgb(10, 149, 151);
            }
        }

        &:nth-child(5n) {
            .circle {
                background: blue;
            }
            .text {
                background: blue;
            }
        }
    }
}

demo

Step 10

製作頁尾 #footer

dist/index.html

 <div id="footer">
    <div class="container">
        <div class="footer-content">
            <div>
                <img src="images/logo.svg" alt="" />
            </div>
            <div>&copy; appedu 2022.</div>
        </div>
    </div>
</div>

增加 #footer 樣式

src/scss/index.scss

#footer {
    height: 100px;

    .footer-content {
        height: 100%;
        padding: 0 15px;
        display: flex;
        align-items: center;
        justify-content: space-between;
    }
}

demo