從原型圖到成品:步步深入CSS布局

2024-04-05    分類: 網(wǎng)站建設(shè)

點擊上方 "程序員小樂"關(guān)注, 星標(biāo)或置頂一起成長

每天凌晨00點00分, 第一時間與你相約

每日英文

Sometimes being too nice is dangerous, you have to show your mean side once in a while to avoid getting hurt.

有時候,太善良也是種危險。偶爾你也得厲害一點,才能免受傷害。

每日掏心話

做人不要太玻璃心,不要別人一條信息沒回,就覺得自己做錯了什么,不要被人一句呵呵,就覺得對方是討厭自己。玻璃心,想太多,什么事都對號入座,何必那么累。

來自:Badd | 責(zé)編:樂樂

鏈接:juejin.im/post/5cebb52651882530be7b16a4

程序員小樂(ID:study_tech)第 789 次推文 圖片來自百度

往日回顧:30 張圖帶你徹底理解紅黑樹

正文

對很多人來說,創(chuàng)建布局是前端開發(fā)領(lǐng)域中最難啃的骨頭之一。

你肯定經(jīng)歷過耗費數(shù)個小時,換著花樣地嘗試所有可能起作用的 CSS 屬性、一遍遍地從 Stack Overflow 上復(fù)制粘貼代碼,寄希望于誤打誤撞地賭中那個能實現(xiàn)預(yù)期效果的魔幻組合。

如果你的慣用策略就是按部就班地組合布局 —— 先把 A 元素放在這兒,好了,A 元素就位了,我再看怎么把 B 放在那兒 …… 那你沒有挫敗感才怪呢。CSS 的玩法可與 SKetch 或者 Photoshop 的玩法不一樣。

在本文中,我將向你展示如何以統(tǒng)籌全局的思維實現(xiàn) CSS 布局,根治布局難產(chǎn)的頑疾。

我們將用一個小案例貫穿全文,我會把所有的 CSS 代碼都解釋給你聽,因此即使你不知道或者忘記了 position 和 display 的用法,即使你分不清 align-items 和 justify-content 的區(qū)別,你仍會有所斬獲。

聽起來很棒吧?那就開始吧。

布局小例子

在本文中,我們要比照 Twitter 的推文組件自己仿寫一個:

不論是一個像這樣的草圖,還是一個細節(jié)精美的原型圖,有章可循 總是個好主意。

要避免一邊在腦海里設(shè)計,一邊在瀏覽器中七拼八湊地攢布局,這樣的開發(fā)過程才會更順暢。你當(dāng)然可以達到那種手腦合一的境界!但鑒于你還在乖乖地讀這篇文章,我可以假設(shè)你還沒有那么神通廣大。:)

第一步:分而治之

在動手敲代碼之前,我們先把布局的各個單元區(qū)分開來:

在用 CSS 鋪排布局時,用行和列的形式去構(gòu)思大有裨益。因此,要么你把元素從上到下排列,要么從左到右排列。這種行和列的思路完美對應(yīng)了 CSS 中兩種布局技術(shù):Flexbox 和 Grid。

當(dāng)然了,我們的示例布局并不是中規(guī)中矩的行列。它有一張圖片鑲嵌在左側(cè),其他元素排列在右側(cè)。

第二步:沿著各個單元畫方框

畫一些方框把這些元素框起來,看看行和列是否初具規(guī)模。我們把方向一致的單元歸到同一個方框中。

按目前的規(guī)劃,把布局用 HTML 代碼實現(xiàn)出來大概如下所示:

展示出的效果是這樣的(可以點擊這里調(diào)試代碼):

這離我們想要的效果還遠呢。但是!所有所需的內(nèi)容都齊全了。有些元素還以從左到右的順序排列。

我們可以認(rèn)為,即使不用進一步設(shè)置樣式,目前的布局效果也能達到網(wǎng)頁想表達的要點,這也是一個優(yōu)秀的 HTML 應(yīng)該達到檢查標(biāo)準(zhǔn)。

關(guān)于語義化 HTML 的說明

你可能會好奇,為何我選的是那些元素 —— article、p 等等。為何不都用 div 呢?

為何要這樣寫:

...

...

而不這樣寫?

... ...

其實,每個 HTML 元素的名稱都有其特定含義,在不同場景中恰如其分地使用語義上與它們所表示的內(nèi)容匹配的元素,是很好的語義化實踐。

這種寫法,首先,有助于開發(fā)者理解代碼;其次,對使用屏幕閱讀器等輔助設(shè)備的用戶比較友好。同時這樣用標(biāo)簽也有利于 SEO —— 搜索引擎會試著理解這個頁面的含義,以便于顯示相關(guān)廣告來盈利、幫助搜索者找到滿意結(jié)果。

article 標(biāo)簽代表文章類內(nèi)容,而你可以認(rèn)為推文這種東西有點類似于一篇文章。

p 標(biāo)簽代表段落,而推文的內(nèi)容文本有點類似于一個段落。

ul 標(biāo)簽代表無序列表(與有序列表或數(shù)字序號列表相對應(yīng)),在本示例中,你可以用它來存放列表信息。

我們無法用只言片語就說清楚 HTML 元素的語義,以及何種情況用何種標(biāo)簽。但大多數(shù)情況下,一個語義化元素即使其語義再不貼切,也比用 div 強,div 標(biāo)簽只代表 一塊區(qū)域。

元素的默認(rèn)樣式

是什么決定了元素的樣式?為什么有的元素獨占一行,而有的元素能共處一行?

這要歸因于元素的默認(rèn)樣式,這其中就有我們要探討的第一個 CSS 知識點:行內(nèi)元素和塊級元素。

行內(nèi)元素們肩并肩擠在一行里(就像句子中的詞一樣,必要時會折行)。根據(jù)再瀏覽器中的默認(rèn)樣式劃分,span、button 以及 img 都是行內(nèi)元素。

而塊級元素,總是踽踽獨行。以控制臺輸出的方式去理解,你可以認(rèn)為塊級元素前后各有一個換行符 \n。就好像console.log(\ndiv\n)。article、div、li、ul 以及 p 標(biāo)簽都是塊級元素。

注意,在上面的例子中,為什么即使 img 標(biāo)簽是行內(nèi)元素,頭像圖片依然獨占一行?因為它下方的 div 是塊級元素。

然后要注意,為什么 @handle、用戶名和時間都在同一行?原因是它們都在 span 標(biāo)簽中,而 span 是行內(nèi)元素。

這三個 span 和 文字 insightful message 處于不同行,因為(a)它們被包在一個 div 中,div 后面自然要另起一行;(b)p 標(biāo)簽同樣是塊級元素,它自然從新行開始排列。(之所有沒有出現(xiàn)兩個空行,是因為 HTML 合并了相鄰的空行,與相鄰空格同理。)

如果你再看得仔細點,你會發(fā)現(xiàn) insightful message 的上下方空間,要比頭像圖片以及 handle、用戶名、時間的上下方空間要大。此空間的大小也由默認(rèn)樣式控制:p 標(biāo)簽的頂部和底部都有 margin。

你也會注意到按鈕列表的圓點,以及列表的縮進行為。這些也都是默認(rèn)樣式。我們馬上就要修改這些默認(rèn)樣式了。

第三步:再畫一些方框

我們想把頭像圖片放在左側(cè),其余元素放在右側(cè)。你可能會根據(jù)剛剛探討的行內(nèi)和塊級知識來推斷,認(rèn)為只要把右側(cè)的元素都包裹到一個如 span 標(biāo)簽般的行內(nèi)元素中,就完事大吉了。

但這是行不通的。行內(nèi)元素并不能阻止其內(nèi)部的塊級元素另起一行。

為了把這些元素收拾得服服帖帖,我們需要用一些更強大的技術(shù),比如 Flexbox 或者 Grid 布局。這次我們選用 Flexbox 來解決。

Flexbox 的原理

CSS 的 Flex 布局能夠把元素以行或者列的形式排布。這是一種單向的布局系統(tǒng)。為了實現(xiàn)交叉的行和列(正如推文組件的設(shè)計那樣),我們需要添加一些容器元素來扭轉(zhuǎn)方向。

你可以在容器上設(shè)置 display: flex; 來啟用 Flex 布局。容器本身是塊級元素(得以獨占一行),其內(nèi)部元素會成為 Flex 子項 —— 即它們不再是行內(nèi)或塊級元素了;它們都受 Flex 容器控制。

在本例中,我們會設(shè)置一些嵌套的 Flex 容器,讓該成行的成行,該成列的成列。

我們把外層容器(綠色方框)設(shè)置為列,藍色方框設(shè)置為行,而紅色方框中的元素排布在列中。

為何選 Flexbox 布局,不選 Grid 布局?

由于一些原因,我決定用 Flexbox 布局而不用 Grid 布局。我覺得 Flexbox 布局更易于學(xué)習(xí),也更適用于輕量級的布局。當(dāng)布局中主要是行或者主要是列時,F(xiàn)lexbox 布局的表現(xiàn)更出色。

另一個重點就是,即使 Grid 布局比 Flexbox 布局年輕,前者也撼動不了后者的地位。它們各自適用于不同的場景,對于二者,我們都要學(xué)習(xí),技不壓身。有些情況你甚至?xí)瑫r使用二者 —— 例如 Grid 布局排布整體頁面,而 Flexbox 布局調(diào)控頁面中的一個表單。

沒錯沒錯,在 Web 開發(fā)的世界,普遍的更替法則是后浪推前浪,但 CSS 并不如此。Flexbox 和 Grid 能夠和諧共存。

用 CSS 解決問題,條條大路通羅馬!

第四步:應(yīng)用 Flexbox

好了,既然我們已經(jīng)打定主意,那就開動吧。我把左側(cè)元素包進一個 div,并給元素們設(shè)置類名,便于應(yīng)用 CSS 選擇器。

看著好像沒有變化。

這是因為 div 作為塊級元素(如果沒有空行就引入一個)是看不見的。當(dāng)你需要一個包裹其他元素的容器,除了 div 之外沒有更貼合語義的選擇了。

下面咱們的第一段 CSS 代碼,我們會把它放在 HTML 文檔中 head 標(biāo)簽的 style 里:

.tweet {display: flex;}

干得漂亮!我們用類選擇器鎖定了所有類名為 tweet 的元素。當(dāng)然目前只有一個這樣的元素,但如果有十個,那它們將都會是 Flex 容器了。

CSS 中以 . 開頭的選擇器代表類選擇器。為什么是 .?我可不知道。你只要記住這條規(guī)則就行了。

現(xiàn)在文字內(nèi)容都到頭像右側(cè)去了。問題是頭像圖片都扭曲變形了。

因為 Flex 容器會默認(rèn):

把子項排成一行;

讓子項與其內(nèi)容等寬,并 ——

把所有子項的高度拉平為最高子項的高度。

我們可以用 align-items 屬性來控制垂直方向的對齊方式。

.tweet {display: flex;align-items: flex-start;}

align-items 的默認(rèn)值是 stretch,而將其設(shè)為 flex-start 后,會讓子項沿著容器頂部對齊,并且讓子項保持各自的高度。

方向的辯證:行還是列?

另外,F(xiàn)lex 容器的默認(rèn)排列方向是 flex-direction: row;。是的,這個方向是 行,即使我們可能感覺那更像是兩列。要把它想成是子項們排成一行,這樣理解就舒服多了。

有點像這張花瓶的圖片,或者說兩張臉的圖片。橫看成嶺側(cè)成峰。

給文字內(nèi)容更多的空間

Flex 布局的子項僅取其所需寬度,但我們需要 content 區(qū)域盡量寬敞一些。

因此,我們要給 content 這個 div 設(shè)置 flex: 1; 屬性。(該 div 有類名,那我們就又可以用類選擇器啦!)

.content {flex: 1;}

我們也要給頭像設(shè)置 margin,好在頭像和文字之間加點空隙:

.avatar {margin-right: 10px;}

看起來順眼一些了吧!

margin 和 padding

那…… 為什么用 margin 而不用 padding?為什么要設(shè)置在頭像右側(cè),而不是文字內(nèi)容左側(cè)呢?

這是一條約定俗成的規(guī)則:在元素右側(cè)和下方設(shè)置 margin,不去碰左側(cè)和上方的 margin。

至少是在英文界面的布局中,文檔流的方向是從左到右、從上到下的,因此,每個元素都 依賴 其左側(cè)和上方的元素。

在 CSS 中,每個元素的定位都受到其左側(cè)和上方的元素的影響。(至少在你遇見 position: absolute 那幫家伙之前是這樣的。)

SoC 原則(Separation of Concerns)

從技術(shù)實現(xiàn)的角度來說,怎樣設(shè)置 avatar 和 content 之間的空隙都一樣。該是多寬就是多寬,沒有 border 的干擾(padding 在 border 的內(nèi)側(cè);而 margin 在外側(cè))。

但當(dāng)事關(guān)可維護性、對元素的全局觀時,這就有區(qū)別了。

我曾嘗試把元素理解為一個個獨立個體,就像每個 JavaScript 函數(shù)只實現(xiàn)單一功能一樣:如果它們都僅僅扮演單一的角色,那么寫起代碼來就很容易,報錯時調(diào)試也很容易。

如果我們把 margin 設(shè)置到 content 的左側(cè),后來有一天我們?nèi)サ袅?avatar,可是以前的縫隙還留在那。我們還得排查導(dǎo)致額外空間的原因(是來自 tweet 容器嗎?還是來自 content 呢?)并把它處理掉?;蛘?,如果 content 設(shè)置了左側(cè)的 margin,而我們想要把 content 替換成別的元素,我們還要記著再把之前那個空隙補上。

好了好了,為了 10 像素的事,沒必要費這么多口舌,干脆就把 margin 設(shè)在頭像的右側(cè)和下方。讓我們繼續(xù)埋頭敲代碼吧。

移除列表的樣式

無序列表 ul 和其中的列表項 li 在左側(cè)窩藏了很大空間,還有一些圓點。這都不是我們想要的效果。我們可以把無序列表左側(cè)的空隙都清除掉。我們還要把它變成一個 Flex 容器,這樣里面的按鈕就能排成一行了(用 flex-direction: row)。

列表項有個屬性是 list-style-type,默認(rèn)值為 disc,使得每個列表項以圓點開頭,我們用 list-style: none; (list-style 是一個縮寫屬性,整合了幾個其他屬性,其中就包括 list-style-type)將該效果關(guān)閉。

.actions {display: flex;padding: 0;}.actions li {list-style: none;}

.actions 又是一個類選擇器。原汁原味。

而 .actions li 選擇器,意即 actions 類元素中所有的 li 元素。它是類選擇器和元素選擇器的結(jié)合。

復(fù)合選擇器中用以分隔的空格代表著選擇范圍的縮小。事實上,CSS 是以倒序讀取選擇器的。其過程是 先找到頁面中所有的 li,然后在這些 li 中找到類名是 actions 的那些。但無論你用正序還是倒序的方式去理解,結(jié)果都是一樣的。(在 StackOverflow 查看更多詳解)

橫排按鈕

要橫排按鈕有好幾種方式。

一種就是設(shè)置 Flex 子項的對齊方式。你應(yīng)該對設(shè)置對齊方式很熟悉,每個富文本編輯器頂部都有這種功能的按鈕:

它們把文本進行左對齊、居中對齊、右對齊以及 兩端對齊,也就是鋪滿整行。

在 Flexbox 布局中,你可以用 justify-content 屬性來實現(xiàn)對齊。設(shè)置了 flex-direction: row(默認(rèn)值,也是本文中一直在用的設(shè)置)后,可以通過 justify-content 把子項進行或左或右地對齊。justify-content 的默認(rèn)值為 flex-start(因此所有元素都向左看齊)。如果我們給 .actions 元素設(shè)置 justify-content: space-between,它們就會均勻地鋪滿整行,就像這樣:

可我們想要的不是這樣的效果。如果這幾個按鈕可以不占滿整行會更好。所以得換一種方式。

這次,我們給每個列表項設(shè)置一個右側(cè)的 margin,把它們分隔開來。還要給整個推文組件設(shè)置一個邊框,以便我們能夠直觀地衡量效果。用 1px solid ccc 設(shè)置一個 1 像素寬的灰色實線邊框。

.tweet {display: flex;align-items: flex-start;border: 1px solid ccc;}.actions li {list-style: none;margin-right: 30px;}

現(xiàn)在效果如下:

按鈕的排列看起來優(yōu)雅多了,但灰色邊框告訴我們,所有元素都過于靠左了。還是用 padding 分配點空間吧。

.tweet {display: flex;align-items: flex-start;border: 1px solid ccc;padding: 10px;}

現(xiàn)在推文組件有內(nèi)邊距了,但有些地方還是很空。如果我們用瀏覽器調(diào)試工具將元素高亮顯示,就會發(fā)現(xiàn) p 和 ul 元素有默認(rèn)的上下 margin(在 Chrome 的調(diào)試工具中,margin 以橙色顯示,而 padding 以綠色顯示):

還有一處有意思的細節(jié);行與行之間的上下 margin 是等距的 —— 并沒有疊加出雙倍間距!因為 CSS 在豎直方向上有 margin 坍塌現(xiàn)象。當(dāng)上下兩個 margin 短兵相接時,數(shù)值大的 margin 會 吃掉 小的。詳情參見 CSS 技巧:margin 坍塌。

對于本例的布局,我會手動調(diào)整 .author-meta、p 和 ul 的右側(cè) margin。如果要真刀真槍地開發(fā)網(wǎng)站,建議你考慮用 CSS reset 作為開發(fā)基礎(chǔ),有利于跨瀏覽器兼容。

p, ul {margin: 0;}.author-meta, p {margin-bottom: 1em;}

用 , 將選擇器隔開,可以一次性把樣式應(yīng)用到多個選擇器上。因此 p , ul 的含義就是 所有的 p 元素,以及所有的 ul 元素。亦即二者的合集。

在這里我們使用了新的尺寸單位,1em 中的 em。一個單位的 em 等于 body 標(biāo)簽上的以像素為單位的字號大小。body 標(biāo)簽的默認(rèn)字號為 16px(16 像素高),所以本例中的 1em 相當(dāng)于 16px。em 隨字號改變而改變,因此可以用 1em 來表達 我想讓文字下方的 margin 和文字的高度一樣,不論文字高度是多少?,F(xiàn)在的效果如下:

現(xiàn)在讓我們把圖片縮小一些,并將其設(shè)置為圓形。我們將其寬高設(shè)置為 48 像素,正和 Twitter 的頭像寬高一樣。

.avatar {margin-right: 10px;width: 48px;border-radius: 50%;}

我們用 border-radius 屬性來設(shè)置圓角,有好幾種方式來定義該屬性的值。如果你想要小圓角效果,可以用帶 px、em 或其他單位名稱的數(shù)字賦值。例如 border-radius: 5px 的效果:

如果將 border-radius 設(shè)為寬和高的一半(在本例中即為 24 像素),其效果就是一個圓形。但更方便的寫法是 border-radius:50%,這樣我們就不必知道具體尺寸,CSS 會計算出確切結(jié)果。甚至,如果以后寬高值變了,也無需重新修改屬性值了!

再接再厲

眼下還有一些需要潤色之處。

我們要把字體設(shè)為 Helvetica(Twitter 用的那一款)、把字號縮小一些、把用戶名加粗,還有,翻轉(zhuǎn) @handle 用戶名 的順序(在 HTML 代碼中),使之與 Twitter 一模一樣。:D

.tweet {display: flex;align-items: flex-start;border: 1px solid ccc;padding: 10px;/*更改字體和字號。在 .tweet 選擇器上設(shè)置的 CSS 效果,其所有子元素都會繼承。(除了按鈕。按鈕不太合群)*/font-family: Helvetica, Arial, sans-serif;font-size: 14px;}.name {font-weight: 600;}.handle,.time {color: 657786;}

font-weight: 600; 的效果等同于 font-weight: bold;。字體有很多不同程度的字重,范圍是從 100 到 900(最淡到最濃)。normal(默認(rèn)值)等價于 400。

另外,CSS 中的注釋寫法與 JavaScript 或其他語言不用,不允許以 // 開頭。某些瀏覽器支持 // 風(fēng)格的 CSS 注釋,但并非所有瀏覽器都如此。用 C 語言風(fēng)格的 / / 包圍注釋內(nèi)容即可高枕無憂。

還有一個小竅門:可以用 偽元素在 handle 與 時間 之間添加一個凸點。這個凸點符號單純?yōu)榱搜b飾,不具有具體語義,所以用 CSS 實現(xiàn)不會污染 HTML 語義結(jié)構(gòu)。

.handle::after {content: " \00b7";}

::after 創(chuàng)建了一個偽元素,它位于 .handle 元素內(nèi)部的最后方(落后 于元素的內(nèi)容)。你還可以用 ::before 創(chuàng)建偽元素。可以給 content 屬性賦值任何文字內(nèi)容,包括 Unicode 字符。你可以恣意發(fā)揮,像給任何其他元素設(shè)置樣式一樣。偽元素用來實現(xiàn)標(biāo)記(badge)、消息提醒或其他小花樣最合適不過了。

圖標(biāo)按鈕

還有一項工作要做,那就是用圖標(biāo)替換按鈕。我們要在 head 標(biāo)簽里添加 Font Awesome 圖標(biāo)字體:

然后用下列代碼替換原來的 ul,新列表中的每個按鈕里有圖標(biāo)和隱藏文字:

ReplyRetweetLike...More Actions

Font Awesome 是一款圖標(biāo)字體,它配合斜體標(biāo)簽 i 可以展示圖標(biāo)。正因為它是字體,那些可以用于文字的 CSS 屬性(例如 color 和 font-size)都適用于圖標(biāo)字體。

我們在這兒做了些微調(diào),來提升按鈕的可訪問性:

特性 aria-hidden=true 使屏幕閱讀器忽略此圖標(biāo)。

sr-only 類是 Font Awesome 內(nèi)置的類。它讓元素在你眼前隱身,但屏幕閱讀器能讀取到它。

現(xiàn)在我們將要給按鈕添加一些樣式 —— 移除邊框、上色以及加大字號。還要設(shè)置 cursor: pointer,把鼠標(biāo)光標(biāo)變成 手 型,就像超鏈接的效果那樣。最后,用 .actions button:hover 選擇處于 hover 狀態(tài)的按鈕,把它們變成藍色。

.actions button {border: none;color: 657786;font-size: 16px;cursor: pointer;}.actions button:hover {color: 1da1f2;}

下面就是推文組件光芒四射的最終效果:

如何精進 CSS 水平

最能提高 CSS 水平的就是實踐。

仿寫你喜歡的網(wǎng)站。設(shè)計者和藝術(shù)家稱其為 臨摹。我寫過一篇用臨摹的方法學(xué) React,其中的原則也適用于 CSS。

選一些有意思的、你覺得難度大的樣式效果。用 HTML 和 CSS 臨摹該效果。如果卡殼了,用瀏覽器的調(diào)試工具看看原網(wǎng)站的效果是如何實現(xiàn)的。栽秧苗、腿跟上、抬頭看看直不直。 :)

歡迎在留言區(qū)留下你的觀點,一起討論提高。如果今天的文章讓你有新的啟發(fā),學(xué)習(xí)能力的提升上有新的認(rèn)識,歡迎轉(zhuǎn)發(fā)分享給更多人。

猜你還想看

阿里、騰訊、百度、華為、京東最新面試題匯集

微服務(wù)的生離死別,看這篇就對了!

Java中的對象都是在堆上分配的嗎?

在Spring Boot項目中整合使用Activiti

關(guān)注訂閱號「程序員小樂」,收看更多精彩內(nèi)容嘿,你在看嗎?

非常感謝您讀完創(chuàng)新互聯(lián)的這篇文章:"從原型圖到成品:步步深入CSS布局",僅為提供更多信息供用戶參考使用或為學(xué)習(xí)交流的方便。我們公司提供:網(wǎng)站建設(shè)、網(wǎng)站制作、官網(wǎng)建設(shè)、SEO優(yōu)化、小程序制作等服務(wù),歡迎聯(lián)系我們提供您的需求。

標(biāo)題名稱:從原型圖到成品:步步深入CSS布局
標(biāo)題來源:http://muchs.cn/news49/322349.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、網(wǎng)站收錄網(wǎng)站策劃、建站公司、網(wǎng)站排名、標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

營銷型網(wǎng)站建設(shè)