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