有些情況下,品牌、校園或政務(wù)官方公眾號需要羅列出大量的照片。如果素材出自專業(yè)攝影師之手,那么對運(yùn)營工作者尚且友善;如果照片畫質(zhì)參差不齊,則要面臨難以用統(tǒng)一設(shè)計(jì)語言調(diào)和的窘境……
那么當(dāng)照片過多時(shí),到底有沒有好的方法能優(yōu)雅地完成公眾號排版?本期專題,計(jì)育韜老師通過親自交付的若干精彩案例和部分其他團(tuán)隊(duì)的優(yōu)秀作品,講授具體的素材設(shè)計(jì)、頁面布局與交互開發(fā)思路。
方案一:讓照片更具有「照片感」
《轉(zhuǎn)眼,就站在了2023年的最后一天。》
企業(yè)年終總結(jié),往往涉及大量的照片展示。格蘭富公眾號在年底的《轉(zhuǎn)眼,就站在了2023年的最后一天。》中通過如以上的方式,將照片以不同的角度平鋪擺放。點(diǎn)擊后,一條線從刊物版面出發(fā),勾勒部分的照片細(xì)節(jié),并隨著圖文的展開持續(xù)前進(jìn)。
在現(xiàn)實(shí)中,照片內(nèi)容本就各不相同,當(dāng)我們的設(shè)計(jì)越模擬真實(shí),讀者對照片的視覺統(tǒng)一性預(yù)期就越低。通過這種設(shè)計(jì)方式,原本略顯枯燥的照片與文案內(nèi)容反而更顯生動(dòng),并且通過線索的 SVG 運(yùn)動(dòng)呼應(yīng)了年度總結(jié)的主旨。
在這篇 SVG 交互作品開發(fā)過程中,計(jì)育韜老師通過 <touchstart> - <click>的雙重觸發(fā)將軌跡描摹與畫布展開同時(shí)激活,值得一提的是此處還融入了「關(guān)懷設(shè)計(jì)」,即便用戶不做點(diǎn)擊行為,也會(huì)在若干秒后開始強(qiáng)制執(zhí)行動(dòng)畫,由此確保了企業(yè)中的中高層領(lǐng)導(dǎo)以及外籍人士等相對不熟悉 SVG 操作的讀者可以順利瀏覽內(nèi)容。
《第一個(gè),宜昌!》
我們也可以考慮在三維空間中,基于 perspective 3D 的 CSS 布局技術(shù),將照片以不同角度懸掛在開發(fā)者創(chuàng)建的公眾號坐標(biāo)系內(nèi)。正如三峽日報(bào)的《第一個(gè),宜昌!》中所呈現(xiàn)的照片群展。
計(jì)育韜老師一般推薦perspective: 1px;空間尺度,同時(shí)注意在開發(fā)過程中,避免過于密集排列圖像進(jìn)而造成 iOS 渲染故障。
方案二:宮格布局提升畫面故事性
《牧馬人冬季低調(diào)創(chuàng)造》
宮格是漫畫的通用載體,同樣也可以是公眾號排版的照片框架。如 JEEP 《牧馬人冬季低調(diào)創(chuàng)造》中的高清美圖就以宮格進(jìn)行布局,“無中生有”誕生了一段故事情節(jié),并通過彈出式海報(bào)支持用戶保存壁紙。在設(shè)計(jì)層面,車體采用了突破宮格的巧妙半摳圖設(shè)計(jì),且宮格線包含了不規(guī)則傾斜,靈動(dòng)而大氣,讓照片緊密卻不擁擠,豐富卻有重點(diǎn)。
宮格布局的另一優(yōu)勢在于故事性(Storytelling)的強(qiáng)化可以對應(yīng)弱化讀者對照片視覺統(tǒng)一性的預(yù)期。體現(xiàn)故事進(jìn)程的照片可以用更真實(shí)的色彩還原現(xiàn)場體驗(yàn),我們以百威中國《點(diǎn)滴心意,水援千里》為例:
《點(diǎn)滴心意,水援千里》
路人「生圖」,尤其賑災(zāi)工作中的圖像資料品質(zhì)是尤其難把控的。從純設(shè)計(jì)層面來講,簡單平鋪只會(huì)傳遞出一種潦草敷衍的態(tài)度,造成適得其反的傳播結(jié)果。這種情況下設(shè)計(jì)師不妨通過宮格布局,結(jié)合文案設(shè)計(jì)提升畫面的故事感,讓照片轉(zhuǎn)化成一種親臨現(xiàn)場的感官憑證。
方案三:照片風(fēng)格預(yù)處理
《雖遲但到!看這條公眾號,你一定會(huì)笑笑笑笑!》
使用相似的照片參數(shù)與濾鏡策略,即便是思政主題設(shè)計(jì),大量的照片也一樣可以美觀陳列。作為 E2.COOL 黑科技 SVG 編輯器第一屆 1024 節(jié)投稿大賽冠軍作品,西部空天的《雖遲但到!看這條公眾號,你一定會(huì)笑笑笑笑!》為廣大政務(wù)新媒體崗位同志做了極佳的示范。
對融媒體工作而言,照片品質(zhì)可能是進(jìn)展延緩的原因,但必定不是作品粗糙的理由。在這里領(lǐng)域內(nèi),將海量照片美觀排版可以說是政務(wù)新媒體人的基本功之一。我們再以東線聯(lián)勤兵的《96年過去了,這支叫人民子弟兵的軍隊(duì)從未改變……》為例,這篇圖文的設(shè)計(jì)采用史料照片與 AIGC 人工智能生成相結(jié)合的方式,基于統(tǒng)一的黑白/做舊風(fēng)格進(jìn)行 perspective 3D 視差排版,歌頌了人民軍隊(duì) 96 年來的光輝歷史:
方案四:在線數(shù)字展覽設(shè)計(jì)
此前計(jì)育韜老師在《云 看 展,請 進(jìn) → → →》中,另外為廣大運(yùn)營人介紹了幾種在線表現(xiàn)大量照片畫面的優(yōu)雅排版策略,可以點(diǎn)擊藍(lán)色標(biāo)題重溫。這里額外推薦一個(gè) 3D 櫥窗型的 SVG 交互效果,最早由計(jì)育韜老師發(fā)明并授權(quán)于 E2.COOL 黑科技 SVG 編輯器作為模版呈現(xiàn),那就是「黑科技編輯器 | 視差相冊(縱向8圖)教程」模型。
在小紅書的《起猛了,看見外灘同時(shí)升起200個(gè)月亮》中,這個(gè)模型充分實(shí)現(xiàn)了用戶投稿照片的優(yōu)雅展示:
《起猛了,看見外灘同時(shí)升起200個(gè)月亮》
更多行業(yè)頂尖 SVG 交互案例作品,歡迎移步 iSVG 公益免費(fèi)搜索引擎:http://www.isvg.com/
第二屆中國 SVG 開發(fā)者大會(huì)很快將召開,這次除了行業(yè)各領(lǐng)軍開發(fā)者/團(tuán)隊(duì)外,如果你與計(jì)育韜老師曾在學(xué)術(shù)和項(xiàng)目層面有過深度交流,屆時(shí)也歡迎通過指定渠道報(bào)名參與。如有其他合作需求,請?zhí)砑游⑿牛篫huoya_Work 咨詢。
-END-
目中需要上傳圖片可謂是經(jīng)常遇到的需求,本文將介紹 3 種不同的圖片上傳方式,在這總結(jié)分享一下,有什么建議或者意見,請大家踴躍提出來。
沒有業(yè)務(wù)場景的功能都是耍流氓,那么我們先來模擬一個(gè)需要實(shí)現(xiàn)的業(yè)務(wù)場景。假設(shè)我們要做一個(gè)后臺(tái)系統(tǒng)添加商品的頁面,有一些商品名稱、信息等字段,還有需要上傳商品輪播圖的需求。
我們就以Vue、Element-ui,封裝組件為例子聊聊如何實(shí)現(xiàn)這個(gè)功能。其他框架或者不用框架實(shí)現(xiàn)的思路都差不多,本文主要聊聊實(shí)現(xiàn)思路。
1.云儲(chǔ)存
常見的 七牛云,OSS(阿里云)等,這些云平臺(tái)提供API接口,調(diào)用相應(yīng)的接口,文件上傳后會(huì)返回圖片存儲(chǔ)在服務(wù)器上的路徑,前端獲得這個(gè)路徑保存下來提交給后端即可。此流程處理相對簡單。
主要步驟
代碼范例
我們以阿里的 OSS 服務(wù)來實(shí)現(xiàn),們試著來封裝一個(gè)OSS的圖片上傳組件。
通過element-ui的upLoad組件的 http-request 參數(shù)來自定義我們的文件上傳,僅僅使用他組件的樣式,和其他上傳前的相關(guān)鉤子(控制圖片大小,上傳數(shù)量限制等)。
<template> <el-upload list-type="picture-card" action="''" :http-request="upload" :before-upload="beforeAvatarUpload"> <i class="el-icon-plus"></i> </el-upload> </template> <script> import {getAliOSSCreds} from '@/api/common' // 向后端獲取 OSS秘鑰信息 import {createId} from '@/utils' // 一個(gè)生產(chǎn)唯一的id的方法 import OSS from 'ali-oss' export default { name: 'imgUpload', data () { return {} }, methods: { // 圖片上傳前驗(yàn)證 beforeAvatarUpload (file) { const isLt2M=file.size / 1024 / 1024 < 2 if (!isLt2M) { this.$message.error('上傳頭像圖片大小不能超過 2MB!') } return isLt2M }, // 上傳圖片到OSS 同時(shí)派發(fā)一個(gè)事件給父組件監(jiān)聽 upload (item) { getAliOSSCreds().then(res=> { // 向后臺(tái)發(fā)請求 拉取OSS相關(guān)配置 let creds=res.body.data let client=new OSS.Wrapper({ region: 'oss-cn-beijing', // 服務(wù)器集群地區(qū) accessKeyId: creds.accessKeyId, // OSS帳號 accessKeySecret: creds.accessKeySecret, // OSS 密碼 stsToken: creds.securityToken, // 簽名token bucket: 'imgXXXX' // 阿里云上存儲(chǔ)的 Bucket }) let key='resource/' + localStorage.userId + '/images/' + createId() + '.jpg' // 存儲(chǔ)路徑,并且給圖片改成唯一名字 return client.put(key, item.file) // OSS上傳 }).then(res=> { console.log(res.url) this.$emit('on-success', res.url) // 返回圖片的存儲(chǔ)路徑 }).catch(err=> { console.log(err) }) } } } </script>
傳統(tǒng)文件服務(wù)器上傳圖片
此方法就是上傳到自己文件服務(wù)器硬盤上,或者云主機(jī)的硬盤上,都是通過 formdata 的方式進(jìn)行文件上傳。具體的思路和云文件服務(wù)器差不多。
主要步驟
代碼示例
此種圖片上傳根據(jù)element-ui的upLoad組件只要傳入后端約定的相關(guān)字段即可實(shí)現(xiàn),若使用元素js也是生成formdata對象,通過Ajax去實(shí)現(xiàn)上傳也是類似的。
這里只做一個(gè)簡單的示例,具體請看el-upload組件相文檔就能實(shí)現(xiàn)
<template> <el-upload ref="imgUpload" :on-success="imgSuccess" :on-remove="imgRemove" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg" :headers="headerMsg" :action="upLoadUrl" multiple> <el-button type="primary">上傳圖片</el-button> </el-upload> </template> <script> import {getAliOSSCreds} from '@/api/common' // 向后端獲取 OSS秘鑰信息 import {createId} from '@/utils' // 一個(gè)生產(chǎn)唯一的id的方法 import OSS from 'ali-oss' export default { name: 'imgUpload', data () { return { headerMsg:{Token:'XXXXXX'}, upLoadUrl:'xxxxxxxxxx' } }, methods: { // 上傳圖片成功 imgSuccess (res, file, fileList) { console.log(res) console.log(file) console.log(fileList) // 這里可以獲得上傳成功的相關(guān)信息 } } } </script>
圖片轉(zhuǎn) base64 后上傳
有時(shí)候做一些私活項(xiàng)目,或者一些小圖片上傳可能會(huì)采取前端轉(zhuǎn)base64后成為字符串上傳。當(dāng)我們有這一個(gè)需求,有一個(gè)商品輪播圖多張,轉(zhuǎn)base64編碼后去掉data:image/jpeg;base64,將字符串以逗號的形勢拼接,傳給后端。我們?nèi)绾蝸韺?shí)現(xiàn)呢。
1.本地文件如何轉(zhuǎn)成 base64
我們通過H5新特性 readAsDataURL 可以將文件轉(zhuǎn)base64格式,輪播圖有多張,可以在點(diǎn)擊后立馬轉(zhuǎn)base64也可,我是在提交整個(gè)表單錢一次進(jìn)行轉(zhuǎn)碼加工。
具體步驟
在這里要注意一下,因?yàn)?readAsDataURL 操作是異步的,我們?nèi)绾螌⒋嬖跀?shù)組中的若干的 file對象,進(jìn)行編碼,并且按照上傳的順序,把編碼后端圖片base64字符串儲(chǔ)存在一個(gè)新數(shù)組內(nèi)呢,首先想到的是promise的鏈?zhǔn)秸{(diào)用,可是不能并發(fā)進(jìn)行轉(zhuǎn)碼,有點(diǎn)浪費(fèi)時(shí)間。我們可以通過循環(huán) async 函數(shù)進(jìn)行并發(fā),并且排列順序。請看 methods 的 submitData 方法
utils.js
export function uploadImgToBase64 (file) { return new Promise((resolve, reject)=> { const reader=new FileReader() reader.readAsDataURL(file) reader.onload=function () { // 圖片轉(zhuǎn)base64完成后返回reader對象 resolve(reader) } reader.onerror=reject }) }
添加商品頁面 部分代碼
<template> <div> <el-upload ref="imgBroadcastUpload" :auto-upload="false" multiple :file-list="diaLogForm.imgBroadcastList" list-type="picture-card" :on-change="imgBroadcastChange" :on-remove="imgBroadcastRemove" accept="image/jpg,image/png,image/jpeg" action=""> <i class="el-icon-plus"></i> <div slot="tip" class="el-upload__tip">只能上傳jpg/png文件,且不超過2M</div> </el-upload> <el-button>submitData</el-button> </div> </template> <script> import { uploadImgToBase64 } from '@/utils' // 導(dǎo)入本地圖片轉(zhuǎn)base64的方法 export default { name: 'imgUpload', data () { return { diaLogForm: { goodsName:'', // 商品名稱字段 imgBroadcastList:[], // 儲(chǔ)存選中的圖片列表 imgsStr:'' // 后端需要的多張圖base64字符串 , 分割 } } }, methods: { // 圖片選擇后 保存在 diaLogForm.imgBroadcastList 對象中 imgBroadcastChange (file, fileList) { const isLt2M=file.size / 1024 / 1024 < 2 // 上傳頭像圖片大小不能超過 2MB if (!isLt2M) { this.diaLogForm.imgBroadcastList=fileList.filter(v=> v.uid !==file.uid) this.$message.error('圖片選擇失敗,每張圖片大小不能超過 2MB,請重新選擇!') } else { this.diaLogForm.imgBroadcastList.push(file) } }, // 有圖片移除后 觸發(fā) imgBroadcastRemove (file, fileList) { this.diaLogForm.imgBroadcastList=fileList }, // 提交彈窗數(shù)據(jù) async submitDialogData () { const imgBroadcastListBase64=[] console.log('圖片轉(zhuǎn)base64開始...') // 并發(fā) 轉(zhuǎn)碼輪播圖片list=> base64 const filePromises=this.diaLogForm.imgBroadcastList.map(async file=> { const response=await uploadImgToBase64(file.raw) return response.result.replace(/.*;base64,/, '') // 去掉data:image/jpeg;base64, }) // 按次序輸出 base64圖片 for (const textPromise of filePromises) { imgBroadcastListBase64.push(await textPromise) } console.log('圖片轉(zhuǎn)base64結(jié)束..., ', imgBroadcastListBase64) this.diaLogForm.imgsStr=imgBroadcastListBase64.join() console.log(this.diaLogForm) const res=await addCommodity(this.diaLogForm) // 發(fā)請求提交表單 if (res.status) { this.$message.success('添加商品成功') // 一般提交成功后后端會(huì)處理,在需要展示商品地方會(huì)返回一個(gè)圖片路徑 } }, } } </script>
這樣本地圖片上傳的時(shí)候轉(zhuǎn)base64上傳就完成了。可是輪播圖有可以進(jìn)行編輯,我們該如何處理呢?一般來說商品增加頁面和修改頁面可以公用一個(gè)組件,那么我們繼續(xù)在這個(gè)頁面上修改。
編輯時(shí)我們首先會(huì)拉取商品原有數(shù)據(jù),進(jìn)行展示,在進(jìn)行修改,這時(shí)候服務(wù)器返回的圖片是一個(gè)路徑 http://xxx.xxx.xxx/abc.jpg 這樣,當(dāng)我們新增一張圖片的還是和上面的方法一樣轉(zhuǎn)碼即可。可是后端說,沒有修改的圖片也要賺base64轉(zhuǎn)過來,好吧那就做把。這是一個(gè)在線鏈接 圖片,不是本地圖片,怎么做呢?
2. 在線圖片轉(zhuǎn)base64
具體步驟
utils.js 文件添加在線圖片轉(zhuǎn)base64的方法,利用canvas
編輯商品,先拉取原來的商品信息展示到頁面
提交表單之前,區(qū)分在線圖片還是本地圖片進(jìn)行轉(zhuǎn)碼
utils.js
export function uploadImgToBase64 (file) { return new Promise((resolve, reject)=> { function getBase64Image (img) { const canvas=document.createElement('canvas') canvas.width=img.width canvas.height=img.height const ctx=canvas.getContext('2d') ctx.drawImage(img, 0, 0, canvas.width, canvas.height) var dataURL=canvas.toDataURL() return dataURL } const image=new Image() image.crossOrigin='*' // 允許跨域圖片 image.src=img + '?v=' + Math.random() // 清除圖片緩存 console.log(img) image.onload=function () { resolve(getBase64Image(image)) } image.onerror=reject }) }
添加商品頁面 部分代碼
<template> <div> <el-upload ref="imgBroadcastUpload" :auto-upload="false" multiple :file-list="diaLogForm.imgBroadcastList" list-type="picture-card" :on-change="imgBroadcastChange" :on-remove="imgBroadcastRemove" accept="image/jpg,image/png,image/jpeg" action=""> <i class="el-icon-plus"></i> <div slot="tip" class="el-upload__tip">只能上傳jpg/png文件,且不超過2M</div> </el-upload> <el-button>submitData</el-button> </div> </template> <script> import { uploadImgToBase64, URLImgToBase64 } from '@/utils' export default { name: 'imgUpload', data () { return { diaLogForm: { goodsName:'', // 商品名稱字段 imgBroadcastList:[], // 儲(chǔ)存選中的圖片列表 imgsStr:'' // 后端需要的多張圖base64字符串 , 分割 } } }, created(){ this.getGoodsData() }, methods: { // 圖片選擇后 保存在 diaLogForm.imgBroadcastList 對象中 imgBroadcastChange (file, fileList) { const isLt2M=file.size / 1024 / 1024 < 2 // 上傳頭像圖片大小不能超過 2MB if (!isLt2M) { this.diaLogForm.imgBroadcastList=fileList.filter(v=> v.uid !==file.uid) this.$message.error('圖片選擇失敗,每張圖片大小不能超過 2MB,請重新選擇!') } else { this.diaLogForm.imgBroadcastList.push(file) } }, // 有圖片移除后 觸發(fā) imgBroadcastRemove (file, fileList) { this.diaLogForm.imgBroadcastList=fileList }, // 獲取商品原有信息 getGoodsData () { getCommodityById({ cid: this.diaLogForm.id }).then(res=> { if (res.status) { Object.assign(this.diaLogForm, res.data) // 把 '1.jpg,2.jpg,3.jpg' 轉(zhuǎn)成[{url:'http://xxx.xxx.xx/j.jpg',...}] 這種格式在upload組件內(nèi)展示。 imgBroadcastList 展示原有的圖片 this.diaLogForm.imgBroadcastList=this.diaLogForm.imgsStr.split(',').map(v=> ({ url: this.BASE_URL + '/' + v })) } }).catch(err=> { console.log(err.data) }) }, // 提交彈窗數(shù)據(jù) async submitDialogData () { const imgBroadcastListBase64=[] console.log('圖片轉(zhuǎn)base64開始...') this.dialogFormLoading=true // 并發(fā) 轉(zhuǎn)碼輪播圖片list=> base64 const filePromises=this.diaLogForm.imgBroadcastList.map(async file=> { if (file.raw) { // 如果是本地文件 const response=await uploadImgToBase64(file.raw) return response.result.replace(/.*;base64,/, '') } else { // 如果是在線文件 const response=await URLImgToBase64(file.url) return response.replace(/.*;base64,/, '') } }) // 按次序輸出 base64圖片 for (const textPromise of filePromises) { imgBroadcastListBase64.push(await textPromise) } console.log('圖片轉(zhuǎn)base64結(jié)束...') this.diaLogForm.imgs=imgBroadcastListBase64.join() console.log(this.diaLogForm) if (!this.isEdit) { // 新增編輯 公用一個(gè)組件。區(qū)分接口調(diào)用 const res=await addCommodity(this.diaLogForm) // 提交表單 if (res.status) { this.$message.success('添加成功') } } else { const res=await modifyCommodity(this.diaLogForm) // 提交表單 if (res.status) { this.$router.push('/goods/goods-list') this.$message.success('編輯成功') } } } } } </script>
結(jié)語
至此常用的三種圖片上傳方式就介紹完了,轉(zhuǎn)base64方式一般在小型項(xiàng)目中使用,大文件上傳還是傳統(tǒng)的 formdata或者 云服務(wù),更合適。但是 通過轉(zhuǎn)base64方式也使得,在前端進(jìn)行圖片編輯成為了可能,不需要上傳到服務(wù)器就能預(yù)覽。主要收獲還是對于異步操作的處理。
以下是總結(jié)出來最全前端框架視頻,包含: javascript/vue/react/angualrde/express/koa/webpack 等學(xué)習(xí)資料。
疊樣式表(Cascading Style Sheet,簡稱:CSS)是為網(wǎng)頁添加樣式的代碼。本節(jié)將介紹 CSS 的基礎(chǔ)知識(shí),并解答類似問題:怎樣將文本設(shè)置為黑色或紅色?怎樣將內(nèi)容顯示在屏幕的特定位置?怎樣用背景圖片或顏色來裝飾網(wǎng)頁?
和 HTML 類似,CSS 也不是真正的編程語言,甚至不是標(biāo)記語言。它是一門樣式表語言,這也就是說人們可以用它來選擇性地為 HTML 元素添加樣式。舉例來說,要選擇一個(gè) HTML 頁面里所有的段落元素,然后將其中的文本改成紅色,可以這樣寫 CSS:
p {
color: red;
}
不妨試一下:首先新建一個(gè) styles 文件夾,在其中新建一個(gè) style.css 文件,將這三行 CSS 保存在這個(gè)新文件中。
然后再將該 CSS 文件連接至 HTML 文檔,否則 CSS 代碼不會(huì)對 HTML 文檔在瀏覽器里的顯示效果有任何影響。(如果你沒有完成前幾節(jié)的實(shí)踐,請復(fù)習(xí)處理文件 和 HTML 基礎(chǔ)。在筆記本里有這個(gè)方面的內(nèi)容!)
1、打開 index.html 文件,然后將下面一行粘貼到文檔頭(也就是 <head> 和 </head> 標(biāo)簽之間)。
<link href="styles/style.css" rel="stylesheet">
2、保存 index.html 并用瀏覽器將其打開。應(yīng)該看到以下頁面:
如果段落文字變紅,那么祝賀你,你已經(jīng)成功地邁出了 CSS 學(xué)習(xí)的第一步。
讓我們來仔細(xì)看一看上述CSS:
整個(gè)結(jié)構(gòu)稱為 規(guī)則集(通常簡稱“規(guī)則”),各部分釋義如下:
注意其他重要的語法:
如果要同時(shí)修改多個(gè)屬性,只需要將它們用分號隔開,就像這樣:
p {
color: red;
width: 500px;
border: 1px solid black;
}
也可以選擇多種類型的元素并為它們添加一組相同的樣式。將不同的選擇器用逗號分開。例如:
p, li, h1 {
color: red;
}
選擇器有許多不同的類型。上面只介紹了元素選擇器,用來選擇 HTML 文檔中給定的元素。但是選擇的操作可以更加具體。下面是一些常用的選擇器類型:
選擇器名稱 | 選擇的內(nèi)容 | 示例 |
元素選擇器(也稱作標(biāo)簽或類型選擇器) | 所有指定(該)類型的 HTML 元素 | p 選擇 <p> |
ID 選擇器 | 具有特定 ID 的元素(單一 HTML 頁面中,每個(gè) ID 只對應(yīng)一個(gè)元素,一個(gè)元素只對應(yīng)一個(gè) ID) | #my-id 選擇 <p id="my-id"> 或 <a id="my-id"> |
類選擇器 | 具有特定類的元素(單一頁面中,一個(gè)類可以有多個(gè)實(shí)例) | .my-class 選擇 <p class="my-class"> 和 <a class="my-class"> |
屬性選擇器 | 擁有特定屬性的元素 | img[src] 選擇 <img src="myimage.png"> 而不是 <img> |
偽(Pseudo)類選擇器 | 特定狀態(tài)下的特定元素(比如鼠標(biāo)指針懸停) | a:hover 僅在鼠標(biāo)指針懸停在鏈接上時(shí)選擇 <a>。 |
選擇器的種類遠(yuǎn)不止于此,更多信息請參閱 選擇器。
譯注:再一次說明,中文字體文件較大,不適合直接用于 Web Font。
在探索了一些 CSS 基礎(chǔ)后,我們來把更多規(guī)則和信息添加至 style.css 中,從而讓示例更美觀。首先,讓字體和文本變得更漂亮。
第一步:找到之前Google Font 輸出的地址。并以<link>元素的形式添加進(jìn)index.html文檔頭(<head>和</head>之間的任意位置)。代碼如下:
<link href="https://fonts.font.im/css?family=Open+Sans" rel="stylesheet" type="text/css">
以上代碼為當(dāng)前網(wǎng)頁下載 Open Sans 字體,從而使自定義 CSS 中可以對 HTML 元素應(yīng)用這個(gè)字體。
第二步:接下來,刪除 style.css 文件中已有的規(guī)則。雖然測試是成功的了,但是紅字看起來并不太舒服。
第三步:將下列代碼添加到相應(yīng)的位置,用你在 Google Fonts 找到的字體替代 font-family 中的占位行。( font-family 意味著你想要你的文本使用的字體。)這條規(guī)則首先為整個(gè)頁面設(shè)定了一個(gè)全局字體和字號(因?yàn)?<html> 是整個(gè)頁面的父元素,而且它所有的子元素都會(huì)繼承相同的 font-size 和 font-family):
html {
/* px 表示 “像素(pixels)”: 基礎(chǔ)字號為 10 像素 */
font-size: 10px;
/* Google fonts 輸出的 CSS */
font-family: 'Open Sans', sans-serif;
}
注:CSS 文檔中所有位于 /* 和 */ 之間的內(nèi)容都是 CSS 注釋,它會(huì)被瀏覽器在渲染代碼時(shí)忽略。你可以在這里寫下對你現(xiàn)在要做的事情有幫助的筆記。
譯注:/*``*/ 不可嵌套,/*這樣的注釋是/*不行*/的*/。CSS 不接受 // 注釋。
接下來為文檔體內(nèi)的元素(<h1> (en-US)、<li>和<p>)設(shè)置字號。將標(biāo)題居中顯示,并為正文設(shè)置行高和字間距,從而提高頁面的可讀性。
h1 {
font-size: 60px;
text-align: center;
}
p, li {
font-size: 16px;
/* line-height 后而可以跟不同的參數(shù),如果是數(shù)字,就是當(dāng)前字體大小乘上數(shù)字 */
line-height: 2;
letter-spacing: 1px;
}
可以隨時(shí)調(diào)整這些 px 值來獲得滿意的結(jié)果,以下是大體效果:
編寫 CSS 時(shí)你會(huì)發(fā)現(xiàn),你的工作好像是圍繞著一個(gè)一個(gè)盒子展開的——設(shè)置尺寸、顏色、位置,等等。頁面里大部分 HTML 元素都可以被看作若干層疊的盒子。
并不意外,CSS 布局主要就是基于盒模型的。每個(gè)占據(jù)頁面空間的塊都有這樣的屬性:
這里還使用了:
開始在頁面中添加更多 CSS 吧!大膽將這些新規(guī)則都添加到頁面的底部,而不要糾結(jié)改變屬性值會(huì)帶來什么結(jié)果。
html{
background-color:#00539f;
}
這條規(guī)則將整個(gè)頁面的背景顏色設(shè)置為 所計(jì)劃的顏色。
body{
width:600px;
margin:0 auto;
background-color:#ff9500;
padding:0 20px 20px 20px;
border:5px solid black;
}
現(xiàn)在是 <body> 元素。以上條聲明,我們來逐條查看:
h1{
margin: 0;
padding:20px 0;
color: #00539f;
text-shadow:3px 3px 1px black
}
你可能發(fā)現(xiàn)頁面的頂部有一個(gè)難看的間隙,那是因?yàn)闉g覽器會(huì)在沒有任何 CSS 的情況下 給 <h1>en-US等元素設(shè)置一些默認(rèn)樣式。但這并不是個(gè)好主意,因?yàn)槲覀兿M粋€(gè)沒有任何樣式的網(wǎng)頁也有基本的可讀性。為了去掉那個(gè)間隙,我們通過設(shè)置margin: 0;來覆蓋默認(rèn)樣式。
至此,我們已經(jīng)把標(biāo)題的上下內(nèi)邊距設(shè)置為 20 像素,并且將標(biāo)題文本與 HTML 的背景顏色設(shè)為一致。
需要注意的是,這里使用了一個(gè) text-shadow 屬性,它可以為元素中的文本提供陰影。四個(gè)值含義如下:
不妨嘗試不同的值看看能得出什么結(jié)果。
img{
display:block;
margin:0 auto;
}
最后,我們把圖像居中來使頁面更美觀。可以復(fù)用 body 的margin: 0 auto,但是需要一點(diǎn)點(diǎn)調(diào)整。<body>元素是塊級元素,意味著它占據(jù)了頁面的空間并且能夠賦予外邊距和其他改變間距的值。而圖片是內(nèi)聯(lián)元素,不具備塊級元素的一些功能。所以為了使圖像有外邊距,我們必須使用display: block 給予其塊級行為。
注:以上說明假定所選圖片小于頁面寬度(600 pixels)。更大的圖片會(huì)溢出 body 并占據(jù)頁面的其他位置。要解決這個(gè)問題,可以:
1)使用 圖片編輯器 來減小圖片寬度; 2)用 CSS 限制圖片大小,即減小 <img> 元素 width 屬性的值(比如 400 px)。
注:如果你暫時(shí)不能理解 display: block 和塊級元素與行內(nèi)元素的差別也沒關(guān)系;隨著你對 CSS 學(xué)習(xí)的深入,你將明白這個(gè)問題。
如果你按部就班完成本文的實(shí)踐,那么最終可以得到以下頁面
相關(guān)推薦:
前端新手看過來,手把手帶你輕松上手html的實(shí)操
*請認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。