您好,登錄后才能下訂單哦!
之前已發布了一次了。在編寫和發布的過程中一直有一個BUG困擾著我。最后被我找到了,只能暫時避開這個BUG重新發布一篇了。之前那篇就被我刪掉了,瀏覽和收藏的也沒了。
那個問題我也記錄下來了:https://blog.51cto.com/steed/2071264
網頁設計思路是把網頁分成三個層次,即:結構層(HTML)、表示層(CSS)、行為層(Javascript)。
形象的比喻,先是HTML捏了一個人,然后CSS則是給人穿上衣服,最后通過JS讓人動起來。
對于所有的Web應用,本質上其實就是一個socket服務端,用戶的瀏覽器其實就是一個socket客戶端。用戶向服務器發送一個請求。然后服務器響應,將數據和格式發回給客戶端,然后斷開這個連接。客戶端收到返回的數據后,通過瀏覽器將數據按照一定的格式呈現出來。整個過程就是一個socket的短連接。
下面是一個服務端的python代碼,實現一個簡單的Hello World:
import socket
def handle_request(conn):
data = conn.recv(1024) # 接收數據,隨便收到啥我們都回復Hello World
conn.send('HTTP/1.1 200 OK\r\n\r\n'.encode('utf-8')) # 這是什么暫時不需要知道,客戶端瀏覽器會處理
conn.send('Hello World'.encode('utf-8')) # 回復的內容,就是網頁的內容
def main():
# 先起一個socket服務端
server = socket.socket()
server.bind(('localhost', 8000))
server.listen(5)
# 然后持續監聽
while True:
conn, addr = server.accept() # 開啟監聽
handle_request(conn) # 將連接傳遞給handle_request函數處理
conn.close() # 關閉連接
if __name__ == '__main__':
main()
在本機啟動上面的socket之后,直接使用瀏覽器作為客戶端連接。在地址欄輸入 http://127.0.0.1:8000/
或 http://localhost:8000/
之后,瀏覽器上就會顯示服務端返回的內容了。
這里顯示的內容比較low,實際應用中,要返回給客戶端的網頁內容比較大。而且除了數據,還會包括格式(html標簽)。實際應用中會將所有的內容寫成一個html文件,然后再返回數據的時候調用這個文件。
先寫一個簡單的帶一點標簽的html文件,index.html:
<h2 >Hello World</h2>
<a >51CTO</a>
<table border="1">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
</table>
然后我們的socket不再發送簡單的數據,而是讀取文件,將文件中的數據發送給客戶端。
在上面代碼的基礎上修改一下handle_request函數的內容:
def handle_request(conn):
data = conn.recv(1024) # 接收數據,隨便收到啥我們都回復Hello World
conn.send('HTTP/1.1 200 OK\r\n\r\n'.encode('utf-8')) # 這是什么暫時不需要知道,客戶端瀏覽器會處理
# conn.send('Hello World'.encode('utf-8')) # 回復的內容
# 讀取html文件,將文件內容返回給客戶端
with open('index.html' , encoding='utf-8') as file:
html = file.read()
conn.send(html.encode('utf-8'))
現在已經將html和我們的socket服務分離了,需要返回給客戶端什么樣的頁面,我們只需要編輯修改我們的html文件即可。而我們的socket服務器代碼則負責和客戶端的數據交換。
之后學習Web暫時只需要關注html的部分就好了,直接使用瀏覽器打開本地的html文件就可以查看實現的效果。
使用pycharm直接創建一個html文件,內容如下(HTML5的模板):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>
<!DOCTYPE html> :這是一個聲明,聲明下面html的版本。這里是一個html5的聲明。這個不是html標簽,下面的都是。
<html lang="en"> :這是一個html標簽,里面的 lang="en"
是標簽內部的屬性。一般html標簽這么寫就行了。這個屬性也用不著。
<head> :head標簽,html的頭,后面詳講
<body> :body標簽,html的主體,后面詳講
最后補充一個
注釋 :<!-- 注釋的內容 -->
主動閉合標簽:大多數的標簽都是這種形式。標簽有兩部分,比如上面的<html>、<head>、<body>,后面都有一個對應的</html>、</head>、</body>來主動閉合這個標簽。
自閉合標簽:像上面 head 中的 meta 標簽,就是一個自閉合標簽。這類標簽比較少。另外也可以這樣寫<meta />,加上一個/
符號,不影響瀏覽器的識別,但是可以直觀的讓人看明白各個標簽已經閉合了。推薦加上表示閉合的/
。
<meta charset="UTF-8"> :指定頁面的字符編碼,否則中文可能會變成亂碼。
<title> :定義頁面標題。一般會顯示在瀏覽器的標題欄或標簽頁上。
還可以加一些其他標簽,舉例一些比較常用的,基本上都用處不大
<meta http-equiv="Refresh" Content="30"> :頁面30秒自動刷新
<meta http-equiv="Refresh" Content="5;url=http://www.51cto.com" > :頁面5秒后自動跳轉,這種跳轉用的少,因為不是動態的無法顯示倒計時或進度條,學了JS可以用JS來實現跳轉并且能顯示倒計時。
<meta name='keywords' content='NGA,National Geographic Azeroth,游戲社區,魔獸世界,魔獸世界中文數據庫,wow,World of Warcraft'> :加關聯字,給搜索引擎搜索用的。告訴搜索引擎搜索什么關鍵字可以搜索到你的網站。對我們用處不大。
<meta name='description' content='NGA 最專業的魔獸世界討論 及綜合游戲社區'> :加網站描述,同樣用處不大
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> :網站兼容模式的設置,就是告訴瀏覽器選擇什么模式來打開網頁,通過content的屬性識別。以上代碼IE = edge告訴IE使用最新的引擎渲染網頁,chrome = 1則是告訴chrome可以激活Chrome Frame。
<link rel="shortcut icon" href="image/favicon.ico"/> :指定網站的圖標
還有更多的 <link> 標簽,以及 <style> 標簽和 <script> 標簽后面的章節用到的時候會再講。
有些特殊符號瀏覽器可能無法直接識別,需要轉義。下面列舉幾個常用的,更多的只能到時候再去查了:
HTML源代碼 | 顯示符號 | 描述 |
---|---|---|
? |
空格 | |
< |
< | 小于號或顯示標記 |
> |
> | 大于號或顯示標記 |
& |
& | 可用于顯示其它特殊字符 |
" |
“ | 雙引號 |
? |
? | 已注冊 |
? |
? | 版權 |
? |
? | 商標 |
上面的源碼可能會被翻譯成符號,如果顯示有問題,就去別處查吧
先了解一下下面幾個簡單的標簽
<p> :段落標簽,段落和段落直接會有行間距
<br> :換行標簽,自閉合,也可以這么寫<br />
<h2> - <h7> :標題標簽,只有6個級別
<br> 這種是自閉和的,標簽之間沒有內容,所以都不屬于
塊級標簽:標簽之間的內容會占一整行,上面的幾個都是塊級標簽
行內標簽:也叫內聯標簽,標簽之間的內容接著前面的內容顯示,不會換行
<span> :這就是一個行內標簽。這個標簽本身沒有任何格式就是一個白板,但是可以通過定義標簽的屬性,來定義標簽之間內容的格式。
<div> :也是一個白板,但是是一個塊級標簽。這個標簽很重要,做前端最重要的就是要掌握div+css,做頁面布局的。
<form> :表單標簽,在下面的input里面講。
下面的這些標簽都是用于客戶端向服務器提交數據的
通過登錄表單來講一下input標簽,還有一個form標簽會用到,順便也講了
<input> :根據不同的type屬性,會有多種形式。
下面的body中有4種input,可以在瀏覽器中打開。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action=" ">
<input type="text" />
<input type="password" />
<input type="button" value="登錄1" />
<input type="submit" value="登錄2" />
</form>
</body>
</html>
type="text" :可以輸入文本,
type="password" :可以輸入密碼,
type="button" :是一個按鈕,現在點下去沒效果,還需要其他東西。
type="submit" :提交表單,是另外一種按鈕。同樣沒效果,直接將form表單的內容提交到form的action屬性指定的url。
不過上面的input內容還無法識別,需要加上name屬性:
<input type="text" name="username" />
<input type="password" name="pwd" />
這樣就會把數據組織成一個字典的形式提交出去,name就是字典的key,你在前端文本框輸入的數據就是字典的value。這樣提交之后,就可以通過name屬性的值也就是字典的key獲取到前端文本的內容。這部分還得后面再講了,暫時只要會以這樣的形式提交,之后再學怎么獲取到值以及處理。
<form> 標簽還有一個method屬性,指定提交的形式,默認是GET。一共就2個可選值GET和POST。指定的話就是這么寫:
<form action=" " method="get">或
<form action=" " method="post"> 。
以GET形式提交,會把表單的內容拼接到url后面,然后發送出去。放在http的請求頭中。
以POST形式提交,會把表單的內容放在內容中發送出去。放在http的請求體中。
HTTP請求報文:HTTP請求報文由3部分組成(請求行+請求頭+請求體)。具體這里就不研究了。
現在還不會寫web服務,不過有現成的服務器可以測試提交表單。打開瀏覽器,在瀏覽器中輸入這樣的url:“https://www.baidu.com/s?wd=你要搜索的內容“
,就可以直接打開搜索結果的頁面。于是自己編輯一個網頁,內容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="https://www.baidu.com/s">
<input type="text" name="wd" />
<input type="submit" value="搜索" />
</form>
</body>
</html>
現在用瀏覽器打開我們自己的網頁,在文本框輸入你要搜索的內容,然后點擊搜索按鈕查看效果。
<input type="text" name="wd" value="默認值" /> :這里也可以加上value屬性,這樣打開的頁面中文本框中不再是空白,而是會有一個默認值。
type="radio" :單選框,相同的name屬性表示是一個選擇項的,定義不同的value值可以獲取到你的選擇
type="checkbox" :復選框,相同的name屬性表示是一個選擇項的,每個選項給不用的value值,可以判斷你選中了哪些,沒選中哪些。
<body>
<p>請選擇性別:<br /></p>
男:<input type="radio" name="sex" value="M" />
女:<input type="radio" name="sex" value="F" />
<p>愛好:</p>
足球:<input type="checkbox" name="favor" value="football" />
藍球:<input type="checkbox" name="favor" value="basketball" />
排球:<input type="checkbox" name="favor" value="volleyball" />
棒球:<input type="checkbox" name="favor" value="baseball" />
</body>
通過屬性 checked="checked"
可以設置選項默認被選中。
上傳文件
<input type="file" name="filename" /> :可以用于上傳文件。要上傳文件,需要將這個input放到form標簽中,并且在form標簽中要定義 enctype="multipart/form-data" 。因為還需要服務器端處理,在講到web框架的時候再細講了。
<input type="reset" value="重置" /> :可以重置form中的所有內容,還原到打開時候的默認值。
textarea標簽,用于實現輸入多行文本,主動閉合標簽,在標簽之間的部分可以寫上默認值。一般會加上name屬性,用于取數據。
這個就不貼代碼了。而且就是這個標簽會被頁面識別為代碼,即使你放在代碼塊中,感覺是個BUG。導致后面的內容都會有問題。
簡單的下拉列表代碼如下:
<select name="city1">
<option value="BJ">北京</option>
<option value="SH">上海</option>
<option value="GJ">廣州</option>
<option value="SZ">深圳</option>
</select>
在select標簽里設置name屬性,用于取數據
每個option標簽里設置value屬性,用于確認該選項是否被選中
size屬性 :可以設置size屬性,將列表自動展開一定的項目
selected屬性 :設置 selected="selected"
,將該選項設為默認
multiple屬性 :設置 multiple="multiple"
,將列表定義為多選。可以通過Ctrl選中多個,也可以通過Shift或者拖拽來連續選中多個
<select name="city2" size="3">
<option value="BJ">北京</option>
<option value="SH" selected="selected">上海</option>
<option value="GJ">廣州</option>
<option value="SZ">深圳</option>
</select>
<select name="city3" size=6 multiple="multiple">
<option value="BJ">北京</option>
<option value="SH" selected="selected">上海</option>
<option value="GJ">廣州</option>
<option value="SZ">深圳</option>
</select>
另外還有一個分組的下拉列表,代碼如下:
<select name="city1">
<optgroup label="直轄市">
<option value="BJ">北京</option>
<option value="SH">上海</option>
</optgroup>
<optgroup label="江蘇省">
<option value="NJ">南京</option>
<option value="SZ">蘇州</option>
<option value="WX">無錫</option>
</optgroup>
</select>
以上,能夠把數據提交給服務器的標簽就講完了。
之后的標簽就是用來點綴,用來頁面布局等等這類功能了。
下面是一些常用的功能性的或者是頁面布局的標簽
通過a標簽可以定義超鏈接,通過超鏈接我們可以實現頁面的跳轉:
<body>
<a >百 度</a>
<a target="_blank">網易</a>
</body>
標簽之間的內容是你的超鏈接顯示的內容,然后定義href的屬性,指向你要跳轉的頁面。
另外還可以定義target屬性,這里用了“_blank”,可以在新的標簽頁打開。另外target還有別的屬性,反正不是很重要,有興趣就自己再去試了。
另外a標簽還有一個作用,就是錨。我理解為頁面內的跳轉。
為了讓頁面內容足夠大(需要滾動),定義一下div的高度,這個以后會講。
另外這里不能用name屬性定位了,需要用id屬性。
<body>
<a href="#chapter_1">第一章</a>
<a href="#chapter_2">第二章</a>
<a href="#chapter_3">第三章</a>
<a href="#chapter_4">第四章</a>
<div id="chapter_1">第一章節的內容</div>
<div id="chapter_2">第二章節的內容</div>
<div id="chapter_3">第三章節的內容</div>
<div id="chapter_4">第四章節的內容</div>
</body>
a標簽中的href屬性在定位錨點的時候需要在前面加上"/#"號,后面跟上id的值。另外,如果在瀏覽器中直接輸入url,后面跟上"#chapter_3"的話,也是打開頁面并且直接定位到錨點。
先準備好出的圖片的路徑,可以是本地的圖片,也可以是網上的圖片。本地圖片貌似不能是絕對路徑,不過應該可以用 ..\ 表示上一級目錄。 我這里都把圖片放到html文件的同級目錄里測試了。
另外,還可以為圖片加上超鏈接。只需要將圖片包在一個a標簽里面就行了(之前放的是文字,這里只是換成了圖片)。
<body>
<body>
<img src="1.jpg">
<a >
<img src="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo_top_ca79a146.png">
</a>
</body>
</body>
圖片的大小也可以調整,在img標簽中設置style屬性(這個還得后面講):
<img src="2.jpg" >
alt屬性:為img加上alt屬性,如果圖片不存在,則會顯示alt的值。
title屬性:為img加上title屬性,鼠標懸停在圖片上的時候,會顯示title的值。
<body>
<img src="123.jpg" alt="圖沒了">
<img src="1.jpg" title="這是一張測試圖">
</body>
ul是無序列表,ol是有序列表。效果直接上代碼試:
<ul>
<li>薩爾</li>
<li>沃金</li>
<li>希爾瓦娜斯</li>
</ul>
<ol>
<li>耐奧祖</li>
<li>阿爾薩斯</li>
<li>伯瓦爾·弗塔根</li>
</ol>
還有一個是分組的列表:
<dl>
<dt>部落:</dt>
<dd>獸人</dd>
<dd>巨魔</dd>
<dd>牛頭人</dd>
<dd>被遺忘者</dd>
<dt>聯盟:</dt>
<dd>人類</dd>
<dd>矮人</dd>
<dd>侏儒</dd>
<dd>暗夜精靈</dd>
</dl>
table標簽包住一張表格,設置一下border屬性,可以顯示幾種邊框效果。
table內嵌tr標簽包住一行,tr內嵌td標簽是每一列。
簡單的表格,就這樣:
<table border="1">
<tr>
<td>瑪法里奧</td>
<td>伊利丹</td>
<td>泰蘭德</td>
</tr>
<tr>
<td>吉安娜</td>
<td>烏瑟爾</td>
<td>安度因</td>
</tr>
</table>
這里還缺少表頭,一般第一行是標題行,我們用thead標簽包起來,并且這一行里都是標題,所以不用td標簽,而是用th標簽。
然后,后面的行都內嵌在tbody標簽中。另外,如果需要,每行的第一列,也可以用th標簽,或者也可以不要行標題,那就全用td標簽
這么做主要是為了規范,下面是更加規范完整的表格:
<table border="1">
<thead>
<tr>
<th>種族</th>
<th>英雄1</th>
<th>英雄2</th>
<th>英雄3</th>
</tr>
</thead>
<tbody>
<tr>
<th>暗夜精靈</th>
<td>瑪法里奧</td>
<td>伊利丹</td>
<td>泰蘭德</td>
</tr>
<tr>
<th>人類</th>
<td>吉安娜</td>
<td>烏瑟爾</td>
<td>安度因</td>
</tr>
</tbody>
</table>
colspan 和 rowspan 屬性可以實現合并單元格的效果。下面把標題行和標題列都合并了。
合并效果的表格可以這么寫:
<table border="1">
<thead>
<tr>
<th></th>
<th colspan="3">英雄</th>
</tr>
</thead>
<tbody>
<tr>
<th rowspan="2">名字</th>
<td>瑪法里奧</td>
<td>伊利丹</td>
<td>泰蘭德</td>
</tr>
<tr>
<td>吉安娜</td>
<td>烏瑟爾</td>
<td>安度因</td>
</tr>
</tbody>
</table>
典型的用法,一般lable標簽會結合input標簽一起使用。
"for" 屬性可把 label 綁定到另外一個元素。請把 "for" 屬性的值設置為相關元素的 id 屬性的值。
建議使用的時候在lable中設置一個for屬性,指向input的id,這樣點擊lable的內容的時候,光標也會出現在指向的input框內。代碼如下,可以比較一下差別(點一下用戶名看看有沒有效果,點一下昵稱看看有沒有效果):
<body>
<p>
<label>姓名:</label>
<input type="text" />
</p>
<p>
<label for="nickname">昵稱:</label>
<input id="nickname" type="text" />
</p>
首先這個標簽不常用,不過還是知道一下。效果就是繪制一個邊框,邊框上面可以加個標題。把其他標簽都放在一個fileset標簽里實現分組。
內部寫一個legend標簽,定義一個標題,如果什么內容的沒有,那么就一直一個邊框,邊框上部邊緣有一個標題:
<fieldset>
<legend>
標題
</legend>
</fieldset>
當然使用的時候,內部添加一些相關的內容,現在只能粗糙的弄一個:
<fieldset>
<legend>登錄</legend>
<label for="username">用戶名:</label>
<input id="username" type="text" name="username" />
<br />
<label for="pwd">密碼:</label>
<input id="pwd" type="password" name="passwd" />
</fieldset>
上面總共也就講了20個左右標簽,去掉那幾個不常用的,基本只要掌握15個左右的標簽就OK了。
在標簽上可以設置style屬性,style屬性的值寫在引號內。
每一個樣式都是一個key:value的形式,樣式之間用";"分號隔開。
寫前端,一般是先用div標簽把頁面進行分塊,然后對每一塊分別設置css即style屬性:
<body>
<div >紅色</div>
<div >綠色</div>
<div >藍色</div>
</body>
上面的代碼,寫了3個div,設置了一個背景色,和一個高度。
看前面的例子,分別用了3中方式表示顏色。3種方式都是一樣的,但是顏色和代碼的對應關系可以去搜索一下rgb,有一個叫做RGB顏色對照表的東西,可以查詢到顏色和對應的編碼。
我們可以在head標簽內事先設置好style標簽,然后在body里需要應用該樣式的標簽內引用這個樣式,即選擇對應的css樣式。
有多種方式來選擇css。
以#id設置樣式,對應的id的標簽就會應用該樣式。上面的代碼也可以這樣實現:
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#i1{
background-color: red;
height: 48px;
}
#i2{
background-color: rgb(0,255,0);
height: 48px;
}
#i3{
background-color: #0000FF;
height: 48px;
}
</style>
</head>
<body>
<div id="i1">第一塊</div>
<div id="i2">第二塊</div>
<div id="i3">第三塊</div>
</body>
body中的標簽只要id正確,就是應用上對應的style樣式了。
這樣貌似看著更復雜了,但是body內的結果更加清晰了,而且這只是因為我們的web頁面還不是太復雜。
另外如果多個標簽的樣式其實是一樣的,但是id只能用一次,我們可以為一個樣式定義多個id,就是這樣,如此也解決的代碼重用的問題:
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#i1,#i2,#i3{
background-color: green;
height: 48px;
}
</style>
</head>
<body>
<div id="i1">第一塊</div>
<div id="i2">第二塊</div>
<div id="i3">第三塊</div>
</body>
因為id不能重復,上面的方式應用起來不方便。最常用的是這里的方式。
現在以 .class 來設置sytle,標簽中只要設置對應項class屬性,就會應用該樣式。關鍵是class屬性是可以重復使用的:
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.c1{
background-color: red;
height: 48px;
}
.c2{
background-color: rgb(0,255,0);
height: 48px;
}
</style>
</head>
<body>
<div class="c1">第一塊</div>
<div class="c2">第二塊</div>
<div class="c1">第三塊</div>
</body>
就是標簽選擇器。以標簽的名字來設置style,這樣所有的標簽都會應用這個樣式:
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div{
background-color: green;
height: 48px;
}
span{
background-color: red;
height: 48px;
}
p{
background-color: blue;
color: red;
}
</style>
</head>
<body>
<div class="c1">第一塊
<span>紅色的內容</span>
</div>
<div class="c2">第二塊</div>
<p>2.1</p>
<div class="c1">第三塊</div>
</body>
也可以理解為層級選擇器,每一個層級關系之間用空格分隔。現在我們以 "div span" 來設置style。如此,所有div標簽下的span標簽就都會應用這個樣式。
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div span{
background-color: red;
height: 48px;
}
</style>
</head>
<body>
<div class="c1">第一塊
<span>第一模塊的內容</span>
</div>
<div class="c2">第二塊
<span>第二模塊的內容</span>
</div>
<div class="c1">第三塊
<span>第三模塊的內容</span>
</div>
</body>
另外,這里的層級也可以使用class,比如以 ".c1 spen" 來設置style:
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.c1 span{
background-color: red;
height: 48px;
}
</style>
</head>
<body>
<div class="c1">第一塊
<span>第一模塊的內容</span>
</div>
<div class="c2">第二塊
<span>第二模塊的內容</span>
</div>
<div class="c1">第三塊
<span>第三模塊的內容</span>
</div>
</body>
這樣c2這個class下的pan就會應該到這個樣式。
使用#id也是一樣的道理。
和層級關系類似,組合之間用","逗號分隔。在id選擇器后面的例子里,其實就是組合了。所以就不試了。
現在我們知道,不只是id,class和標簽都可以用來組合。
另外,組合是一個或的關系,上面的層級是一個與的關系。
這里先用 input[type='text']
來舉例,前面是一個選擇器,后面中括號是判斷屬性,如果有這個屬性,就應該改樣式。
對于前半部分,同樣可以使用 #id 或 .class 。
對于后半部分,我們還可以使用自定義的屬性,比如下面例子用自定義了一個myattr屬性,來應用了一個樣式:
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
input[type='text']{
background-color: blue;
}
#password[type='password']{
background-color: green;
}
label[for="username"]{
background-color: yellow;
}
label[myattr="pink"]{
background-color: pink;
}
</style>
</head>
<body>
<label for="username">姓名:</label>
<input id="username" type="text" />
<p>
<label myattr="pink" for="password">昵稱:</label>
<input id="password" type="password" />
</p>
</body>
我們可以在標簽內設置有限級,還可以在head里設置優先級模板,按幾個選擇器的規則應用其中的樣式。所有可能出現符合多個要求而會應用到多個要是的情況。這里就有了一個優先級的概念。
對于不重復的樣式,要么會全部應用上。
對于重復的要是,會應用最下面的那個樣式。即body中的樣式優先級高于head中的樣式。同在body或head中,那么下面的樣式優先級高。
總結,按我的理解,應該就是最新加載的樣式會覆蓋之前的樣式。不沖突就追加上是,有沖突就替代掉。
上一個例子:
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.c1{
background-color: blue;
}
.c2{
background-color: red;
color: white;
}
</style>
</head>
<body>
<div class="c1 c2">優先級測試1</div>
<div class="c2 c1">優先級測試2</div>
<div class="c2 c1" >優先級測試3</div>
</body>
這里標簽中的字體顏色屬性就覆蓋掉了 .c2 中的字體顏色。
而前2個div都是同時屬于 c1 和 c2 這2個class,背景色的樣式應用的都是處于下面的 c2 的樣式。
class屬性賦予多個值 :這里的class屬性同時賦了2個值,注意一下這個賦值的格式。
如果有多個頁面文件,但用的是同一套css樣式。我們目前只能在每個頁面文件的head里都寫上全部的css代碼。這樣又有代碼重復的問題了。
可以創建一個css文件(pycharm里選擇New->Stylesheet),將 <style> 標簽中的內容(不包含標簽),寫到這個css文件里。比如創建一個文件名是 "commons.css" ,文件內容如下:
.c1{
background-color: blue;
}
.c2{
background-color: red;
color: white;
}
然后就是在html文件的head里,導入這個這個樣式文件就可以應用上文件中的樣式。這需要用到link標簽,用href屬性指定文件路徑,用rel屬性指定文件的內容是stylesheet:
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="commons.css" />
</head>
<body>
<div class="c1 c2">優先級測試1</div>
<div class="c2 c1">優先級測試2</div>
<div class="c2 c1" >優先級測試3</div>
</body>
導入css文件后,本地的head里依然可以寫style標簽。這個style應該現在link的下面。然后優先級的問題就是位于下面的style的樣式優先級高于css文件中的樣式。
:這里的border有3個屬性。
第一個是邊框線的寬度,這里是1像素;
第二個是線的樣式,這里是soild實線,還有dotted虛線等等其他樣式;
第三個是邊框線的顏色。
這里3個屬性沒有順序的問題
<body>
<div >邊框測試1</div>
<br />
<span >邊框測試2</span>
</body>
另外還可以通過這4個屬性 border-top、border-left、border-right、border-bottom 分別設置每一邊的樣式。就是可以做出4邊不同的邊框。
:高度和寬度可以用像素px表示,也可以用百分比表示。
注意1,瀏覽器的高度是無限的(內容多了會有滾動條),所以高度用不了百分比。不過如果內嵌在一個有高度的標簽里,就可以用百分比了。
注意2,div由于是塊級標簽,雖然我們指定了寬度,但是實際出占了整行的,之后的標簽還是只能在下一行顯示。設置的背景色是只顯示80%,但是后面的部分依然用不了。
<body>
<div >高度和寬度</div>
</body>
font-size: 16px
:字體大小。text-align: center
:水平居中,也可以設置靠左或靠右。line-height: 48x
:有水平居中,自然也會有垂直居中。但是垂直居中不好用。可以通過設置行高來達到類似的效果。具體數值參考height的值,設置的和height的值一樣,就能實現垂直居中的效果。font-weight: bold
:字體加粗color: red
:字體顏色
<body>
<div style="height: 48px;
width: 80%;
background-color: yellow;
font-size: 16px;
text-align: center;
line-height: 48px;
font-weight: bold;
color: red;"
>字體的設置</div>
</body>
float設置后,元素就會浮動起來。浮動之后即使是塊級標簽(比如div),也不會像之前那樣占滿一整行了。沒有float的效果:
<body>
<div >浮動</div>
<span>占位</span>
</body>
上面的div標簽雖然設置了30%的寬度,但是作為塊級標簽,他要占1整行。后面的內容只能換行。
現在給div加上float:
<body>
<div >浮動</div>
<span>占位</span>
</body>
現在的div就真的只占30%的寬度了,后面的內容會繼續接在后面顯示,而不是之前那樣要換行。
下面設置2個浮動的標簽,并且都是往一個方向飄:
<body>
<div >浮動1</div>
<div >浮動2</div>
</body>
這里,2個div是接著的。第1個div先把位置占住之后,剩余的空間再放置第2個div。
如果空間夠,就會在剩余的空間放置。如果空間不夠,就會另起一行放置:
<body>
<div >浮動1</div>
<div >浮動2</div>
<div >浮動3</div>
</body>
標簽嵌套的情況,如果父級標簽沒有float,而子標簽float的話,可能會有一點問題。現在把上面的代碼中的3個div內嵌到一個沒有float的div中:
<div >
<div >浮動1</div>
<div >浮動2</div>
<div >浮動3</div>
<!--<div ></div>-->
</div>
最后一句先注釋掉,現在外層的div的邊框效果是有問題的。可以這么理解,子標簽浮點起來之后,和父標簽不在同一個層級了。現在父標簽的邊框內什么內容都沒有。我們需要的效果是邊框包圍在子標簽的外面,現在可以把最后那一句的注釋去掉,看看效果是否滿足。
<div style="clear: both;"></div>" :在最后加上這么一句,相當于把原本浮動起來的子標簽再拉回來。
當然也可以把外層的標簽也設置成float,同樣可以達到效果。不過浮動起來之后,就不再像之前那樣作為塊級標簽能占滿一行了,這里加上了寬度的設置:
<div >
<div >浮動1</div>
<div >浮動2</div>
<div >浮動3</div>
</div>
之前講過有塊級標簽和行內標簽,但是其實這個也不是絕對的。display就是來定義這個屬性的。即可以通過設定display的屬性將塊級標簽變成行內標簽,反之亦然。
display: inline
:設為行內標簽dispaly: block
:設為塊級標簽<body>
<div >DIV</div>
<span >SPAN</span>
</body>
現在div變成了一個行內標簽,而span卻變成了塊級標簽了。
行內標簽:無法設置 高度、寬度、邊距(邊距后面馬上會講)。并且默認只占自己內容的部分
塊級標簽:可以設置。并且默認占父級的100%
另外如果需要一個可以設置的行內標簽,還可以采用如下設置。display: inline-block
:默認只占自己內容部分(inline屬性),但是同時可以設置高度、寬度等屬性(block屬性)。
display: none
:只要把標簽定義上這個屬性,這個標簽就不再顯示了。以后可以做個開關(通過JS),讓某些元素顯示出來或者不顯示。
邊距分內邊距(padding)和外邊距(margin)。
沒有設置邊距是這樣的效果:
<div >
<div >邊距的效果</div>
</div>
現在給外層的那層div設置一個內邊距,即padding:
<div >
<div >邊距的效果</div>
</div>
設置了邊距后,兩個div標簽的內容之間就會有空隙。如果換做是給內層的div設置一個外邊距,顯示的效果也是一樣的。
另外,邊距還可以為上、下、左、右分別設置。
之前也有別的屬性可以分別設置4個方向的屬性,這里就拿margin來舉例說明:margin: 10px
:同時設置4個方向的屬性值margin: 10px 20px
:上下設為10px,左右設為20pxmargin: 10px 20px 30px
:上下一樣是10px,左邊是20px,右邊是30pxmargin: 10px 20px 30px 40px
:分別對應上、右、下、左
可以這么理解,第4個值是左,如果沒有,就和右一樣;下如果沒有設置,就同上;右如果也沒有設置,那么也同上。
可以用下面的例子測試:
<body >
<div >上面的框</div>
<div >下面的框</div>
</body>
另外還可以通過margin-top、margin-bottom、margin-left、margin-right來設置4個方向的屬性。如果這么設置,那么沒有設置的幾個方向就都是0.
可能都沒注意,之前的代碼在設置了背景色后,其實頁面的最上面并不是你的背景色,而是有一條白色(就是body的邊距)。仔細看看:
<body>
<div >看看上面有沒有縫</div>
</body>
這里要給body設置一個內邊距(margin)屬性:
<body >
<div >看看上面有沒有縫</div>
</body>
去掉了邊距之后,現在是真正的處于最上面了。再仔細看看,其實之前缺的不是頂上一層,而是周圍一圈。并且看了看別的網站,貌似都是把給body的margin設為0的。
在設置body屬性的時候,老師推薦是這么寫的: ,這里就看看auto的意思看意思就是自動設置,但是怎么個自動法呢?這里auto的值對應的左右的邊距,實現的效果就是左右2邊邊距一樣,即水平居中了。
上下似乎也可以設成auto,效果看上去就是0,也就是說貌似全部設置成auto也行。
知識點暫時就掌握這些就夠了。頁面布局就是要把頁面分隔成一個一個的div。有拼接,也有嵌套,而且如果需要,還要嵌套多層。最后還要寫上css,設置好格式。下面是課上的示例代碼,作業可以參考一下:
<body >
<div >
<div >
<div >收藏本站</div>
<div >
<a>登錄</a>
<a>注冊</a>
</div>
<div ></div>
</div>
</div>
<div>
<div >
<div >Logo</div>
<div >購物車</div>
<div ></div>
</div>
</div>
<div >
<div >
商品分類
</div>
</div>
<div >
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
</div>
</body>
開一個商城的商品列表頁面(非動態)(仿京東)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。