CSS – background and styling img
前言
之前写过一些:
W3Schools 学习笔记 (2) – CSS Image Sprites
W3Schools 学习笔记 (3) – CSS Styling Images & CSS Multiple Backgrounds
这篇作为整理.
Styling img
default behavior
img width: auto, height: auto 情况下, 会依据图片的 original size 渲染图片.
<div class="container">
<img src="./images/tifa2.PNG" />
</div>
效果
红色框是 container 的大小. 图片超过了.
max-width 100%
所以通常 Tailwind, Bootstrap 它们的 base.css 都会给图片设定一个 max-width:100%
width: 100% 配上 height : auto, 图片会按原图的比例缩小(或放大).
width, height: 100%
有些情况下, 希望图片完全覆盖框. 也就是说比例会被改变.
img {
width: 100%;
height: 100%;
}
效果
由于, 图片本来的比例是 16:9, 而被强行塞入一个 1:1 的框里, 它就变形了.
object-fit: contain
object-fix 就是用来调整它变形的.
object-fit: contain;
contain 的意思就是把图片完整的塞入, 但是不变形, 而是留白. 好处是图片信息还在, 坏处是留白.
object-fit: cover
完整图 -->
cover 没有造成留白, 但是图片信息却丢失了. 它只能保留一部分
它的步骤是先把图片压缩 (依据比例选择 width, height 其中一边来压缩), 比如上面这个是压缩高度.
图片 vertical 的信息被保留了, 那 horizontal 就需要被牺牲掉. 我们可以通过 position 来控制要牺牲掉那些部分, 比如选 center, 那就丢失掉左右的内容.
如果图片小于框, 那么就不是压反而是拉 (图片会变蒙). 比例依旧保留同样部分需要牺牲.
左图的高度是 392 x 761, 右图是 1000 x 761
高度不变, 但是 width 增加了. 可以看到被拉升后图片蒙了, 而且上下的信息也丢失了, 只剩下中间的部分 (我设置了 position: center)
object-position: horizontal vertical
object-position: 70% 0;
通常是用 % 来控制的. 由于 cover 肯定是压缩其中一边, 所以 horizontal vertical 也只需要调 1 边而已. (它的默认是 0% 0%, 还有一种写法是 center, 表示 50% 50%, 在这个情况下和 50% 0 是一样的效果)
它的 percent 算法是这样的
第一张是效果图, 第二张是解释它如果从 70% 开始 cut.
object-fit: fill
这个就是默认值, 也就是图片会变形.
object-fit: none
跟 cover 有点像, 只是它不会压小, 它就直接 clip 中间.
这时也是可以用 object-position 来调整. 通常这时就是调 2 边 holizontal 和 vertical
object-fit: none;
object-position: 70% 0%;
效果
它的算法是这样的:
假设图片 width 是 1349px. 框是 250px
那么 1349 - 250 = 1099px, 这个就是 0-100% 的 range.
除于 100 得到 10.99px = 1%
所以用 px 来表达的话是 70 * 10.99px = 769.3px (记得要用 negative value, 不然方向会错)
object-position: -769.3px 0%;
效果是一模一样的.
filters
img {
filter: grayscale(100%); /* 黑白照 */
filter: blur(4px); /* 变萌 */
}
还有许多 effects, 但常用的就只有上面 2 个, 更多参考.
Flip Image
镜子效果是通过 scaleX 来做的.
img:hover {
transform: scaleX(-1);
}
width and height attribute & aspect-ratio
参考: Setting Height And Width On Images Is Important Again (必读)
上面讲到的都是 CSS styling. 而且很多时候是等到图片加载后依据它的比例渲染
这会导致首屏渲染不完整, 图片加载后会跳, 术语叫 layout shift.
用户体验扣分, 同时 layout resize 也会导致 reflow 性能也扣分.
比较好的做法是在图片加载之前就设定好一个 frame.
早年的做法是做一个 image container 然后利用 padding 模拟 aspect ratio 的方式做出一个 aspect ratio 的 frame, 后来直接用 CSS4 的 aspect ratio 也可以.
在到现在直接利用 img 的 width 和 height attribute 就可以了. 它的发展史是比较坎坷的, 想深入了解就看上面的文章
下面我们来一个一个看. 别搞混就可以了.
1. no width and height attribute
没有设置 width height attribute, 只设置 CSS width: 100% (假设 parent 是 500px) 的情况下.
左图是图片加载后的效果, 右图是图片加载前的效果 (我用 404 来替代). 红框是图片的 outline (我们每次都关注加载前和加载后的渲染情况)
加载前整体的 height 是很小的, 图片加载后 height 就大了, 这就是所谓的 layout shift.
2. width height attribute
为 img 添加上 attribute wdith: 100; height: 100 (它的 unit 是 px)
渲染后的效果图片变形了. 另外这个比例是 100% width (来自 CSS) + 100px height (来自 attribute). 而不是依据图片的比例 (哪怕是图片加载以后)
3. CSS height auto
上面是不正确的做法. 当 img 加上 width height attribute 以后, CSS 一定要 set height auto
加了 height auto 后, 图片加载后渲染是正确了 (依据图片的比例), 图片加载前, 它的渲染逻辑是这样的
attribute width:100 和 height: 100 被当作一个 aspect ratio.
然后配合 CSS 的 width 100% 去做渲染. 而不是直接渲染成 100x100px 哦
而当图片加载后, 它会改成用图片的 aspect ratio 做渲染. 这种情况它依然会跳一下.
跳一下当然是不对的, 所以绝大部分的情况下, img width height 一定是放图片本身的 aspect ratio, 而这个 ratio 也是最终想渲染出来的 radio.
4. 2022 年该怎样用?
a. 不要用 padding aspect ratio 或者 CSS4 aspect ratio 方案去画 frame (除非图片本身的 ratio 不是你想展现的 ratio)
b. 不要用 intrinsicsize attribute (这个是以前历史过渡采用的方案)
c. 用 attribute width height 作为图片加载前, frame 渲染的 aspect ratio, 同时 CSS set 其中一边的 dimension 比如 max-width: 100%. 另一 side 就设置 auto.
d. picture > source 也是有 width height 的哦. 它和 img 的玩法是一样的. 所以可以实现不同 media query 下输出不同的图片 aspect ratio 解决 art direction 的问题.
没有设置 source 的 width height 那么会 fallback 去拿 img 的 width height 哦.
最后补上一个 RWD Image 的版本
<picture>
<source
media="(min-width: 1000px)"
srcset="https://via.placeholder.com/600x600"
width="1600"
height="1600"
/>
<source
media="(min-width: 500px)"
srcset="https://via.placeholder1.com/300x300"
width="1600"
height="900"
/>
<img
class="img"
src="https://via.placeholder1.com/300x300"
width="100"
height="100"
/>
</picture>
<img> extra 4px at the bottom
参考: 冷知识 (新手) – <img> extra 4px at the bottom
background-image
default behavior
background-image 默认就类似有了 img width, height: 100% 的概念. 它是不会超出 container 的 (废话不然它怎么是 background).
default 它的效果是 object-fit: none
background-size and background-position
它和 image 的 object-fit 和 object-position 基本是一样的
background-image: url("./images/tifa2.PNG");
background-size: cover;
background-position: 70% 0;
通常用在 background-image 大于 container 的情况,
但是, 当 background-image 小于 container 的时候. position 的功能就变成了定位.
section {
margin-top: 10rem;
height: 500px;
width: 100%;
background-image: url('./images/car.png');
background-repeat: no-repeat;
background-position: 50px 50px;
border: 1px solid red;
}
效果
background-size % percentage
特别说一下, 除了 cover, contain. background-size 也常用 percentage 做一些 effect. 它的定义是这样的.
.box {
width: 300px;
height: 50px;
background-image: linear-gradient(to right, red, yellow);
}
效果
如果设置了 background-size: 50% 效果是这样的
框 300px, 但是 background 只有 50%, 也就是 150px.
那么就会有空洞, 于是 background 就 repeat 了 (因为默认 background 就是会 repeat 的)
同理如果设置称 background-size: 200%, 效果如下:
背景比框长了一倍, 所以黄色的部分就少了, 它相等于只拿了原本的 150px 的部分来显示在 300px 的框内.
background-repeat
当图片比 container 小, 默认情况下它会自动重复. 可以 set 成 no-repeat, x-repeat, y-repeat, repeat 来控制它.
background-attachment
和 repeat 一样用在当图片比 container 小的时候
scroll 图片会随着 scroll 一起移动, 效果就类似 position absolute
fixed 图片会随着 viewport scroll 一起移动, 效果类似 position fixed
local 默认值, 图片不会随着 scroll 移动, 类似 position static
multiple background-image
background image 是可以 multiple 的
用逗号分开 1, 2
越靠前的越在上层, 用户越看见.
shorthand 的写法
一个常用的地方是 background + overlay
一个 linear-gradient 作为 overlay 的黑, 在加一张图片
background-origin
set background image render 的位置
.container {
outline: 5px solid red;
border: 1rem solid transparent;
padding: 1rem;
width: 300px;
height: 300px; background-image: url("./images/tifa2.PNG");
background-repeat: no-repeat;
background-origin: border-box;
background-size: cover;
}
border-box, 从 border 开始
boder 要 transparent 才看的出来. (红色是 outline 哦)
padding-box (default), 从 padding 开始
粉红色是 border 的颜色
content-box, 从内容开始
白色是 padding
background-clip
它和 origin 类似. 但 origin 只能用来设置 background-image.
clip 可以设置 background-color 和 image, 而且除了 border-box, padding-box, content-box 它还有一个 text
border-box (default), 从 border 开始
h1 {
outline: 5px solid red;
border: 3rem solid transparent;
padding: 3rem;
font-size: 4rem;
color: transparent;
width: fit-content;
background-color: blue;
-webkit-background-clip: border-box;
}
效果
和 image 不同, color 的范围是从 border-box 开始的
padding-box, 从 padding 开始
粉红色是 border
content-box, 从内容开始
白色是 padding
它可以用来实现 silider dot dot dot 的设计
.dot-list {
padding: 1rem; display: flex;
flex-direction: column;
gap: 2rem; .dot {
border-radius: 50%;
padding: 6px;
width: 20px;
height: 20px;
background-color: red;
background-clip: content-box; &:last-child {
border: 2px solid red;
padding: 4px;
}
&:first-child {
padding: 4px;
}
}
}
text
h1 {
outline: 5px solid red;
font-size: 8rem;
color: transparent;
width: fit-content;
background-image: url("./images/tifa2.PNG");
background-size: cover;
-webkit-background-clip: text;
}
clip color 和 image 都有效, 通常 text 是配上 image url 或者 gradient. 记得 color 要 transparent 哦.
最好加上 -webkit-background-clip, 和用 -webkit-text-fill-color
参考:
Youtube – Top 10 CSS Tricks You Didn't Know!
stackoverflow – Difference between "-webkit-text-fill-color" and "color"?
Gradients
Gradients 是渐变 color
3 大种类:
Linear Gradients (goes down/up/left/right/diagonally)
Radial Gradients (defined by their center)
Conic Gradients (rotated around a center point)
Linear Gradients
background-image: linear-gradient(to left, red, yellow);
它是 background-image 来的哦, 不是 color
最少 2 种颜色才能渐变.
默认是 top to bottom, 有很多 pattern, 比如 left to right, diagonal (对角线), degree 等
background-image: linear-gradient(to right, red 50%, yellow);
red 50% 从开始一直是纯红色到 50%, 然后渐变去黄色
background-image: linear-gradient(to right, red 25%, yellow 50%);
表示开始到 25% 纯红, 然后渐变去黄, 从 50% 的位置开始变成纯黄
除了 to left, to right 还可以做斜角 135deg
Radial Gradients
radial 就是画圈
background-image: radial-gradient(circle at center, red, yellow);
效果
从中心点以圆圈的形状往外渐变
我们还可以指定圆圈的直径和起始点
background-image: radial-gradient(100px at 30% 50%, red, yellow);
效果
x, y 是起始点的坐标,100px 是直径。红色会从最里面渐变到直径完,然后圆圈外都是黄色。
挖洞效果
background-image: radial-gradient(circle at center, red 50px, blue 51px);
red 50px 表示从 0 - 50 用纯红
blue 51px 表示从 51 - end 用纯蓝
50 - 51 则是从红到蓝的渐变。如果没有这 1 px 会很突兀。
如果我们把 red 换成 transparent 那就变成类似中间挖了一个洞的效果。
Conic Gradients
Blend Mode
参考:
混合模式 mix-blend-mode/background-blend-mode
借助 mix-blend-mode 纯CSS制作文字镂空效果
Different result when using mix-blend-mode and background-blend-mode
Creative CSS Mix Blend Mode text effect | mix-blend-mode | CSS
例子 1
Blend Mode 可以做出以下的效果
CSS Style
.container {
background-image: url("./images/tifa2.PNG"),
linear-gradient(135deg, red, yellow);
background-size: cover;
width: 40%;
height: 50vh;
background-blend-mode: screen;
}
例子 2
当有多张背景图或者颜色的时候就可以使用 background-blend-mode 来表示它们重贴后的特效.
CSS Style
body {
font-size: 8rem;
font-weight: 700;
color: black; display: flex;
justify-content: center;
align-items: center;
height: 100vh; position: relative;
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
background-color: white;
} &::after {
content: "";
position: absolute;
top: 0;
right: 0;
width: 50%;
height: 100%;
background-color: black;
z-index: -1;
}
} marquee {
color: white;
mix-blend-mode: difference;
}
mix-blend-mode 和 background-blend-mode 唯一的区别是, mix-blend-mode 是用在不同的 element 重叠, 而 background-blend-mode 是用同一个 element 但多张 background-image 或者和 background-color 重叠.
例子 3
文字镂空效果, 不一定要用 clip text.
CSS Style
.container {
width: 50%;
height: 70vh;
display: flex;
justify-content: center;
align-items: center;
background-image: url("./images/tifa2.PNG");
background-size: cover;
} h1 {
font-size: 8rem;
background-color: white;
color: black;
mix-blend-mode: screen;
}
Figma 也是有这个功能哦
Font color depend on background
它的效果中有一个是 different, 可以用来做背景色和字体颜色, 但要注意, 它的 color 并不是 black and white 而是补色哦.
其它做法:
Switch font color for different backgrounds with CSS
Top 10 CSS Tricks You Didn't Know!
做 dark mode 的方式
filter: invert(1) 能把所有子层颜色反转, background-color 和 color 都会哦.
body {
width: 50vw;
display: flex;
justify-content: center;
align-items: center;
font-size: 4rem;
background-color: black;
filter: invert(1);
} .box1 {
background-color: red;
width: 100px;
height: 100px;
}
mask-image
参考: YouTube – mask-image lets you do some really cool stuff
效果
一张图片,我们在上面放一个形状 (SVG),它会依据这个形状 clip 图片。
img {
width: 640px;
aspect-ratio: 16 / 9;
object-fit: cover;
mask-image: url('../../src/icons/solid-car-side.svg');
mask-repeat: no-repeat;
mask-size: contain;
mask-position: center;
}
注: 目前游览器兼容还不理想,需要加上 -webkit prefix,当然如果有使用 postcss-preset-env 就不需要烦恼这些啦。
它的语法和 background-image 非常类似,也是有 size, position, repeat 等等。
gradient
除了 SVG,mask-image 也支持 gradient 写法。
但是 gradient 的颜色只能是 transparent 和 black。
transparent 的部分最终会被 clip 掉。black 则会被保留起来。
.container {
background-color: red; img {
width: 640px;
aspect-ratio: 16 / 9;
object-fit: cover;
mask-image: radial-gradient(50px at 30% 40%, transparent 100%, black);
}
}
效果
我用 gradient 在 x:30%,y:40% 坐标上画了一个 50px 直径的圆圈,并且它的颜色是 transparent。于是这个部分被 clip 掉了。
最终显示了背景的红色。
题外话: mask-image 也可以 apply 在普通的 div 上,并不一定是 img element。
CSS – background and styling img的更多相关文章
- CSS 背景-CSS background
这里有个很好的样式学习网站:http://www.divcss5.com/rumen/r125.shtml 一.Css background背景语法 - TOP CSS背景基础知识 CSS 背 ...
- CSS background 属性 总结
CSS background 属性总结
- HTML CSS——background的认识(一)
今天回归bug时无意间看到了样式表中background属性,如今总结一下: 1.background-color:设置元素的背景色.其值能够为:color-name.color-rgb.color- ...
- css background之设置图片为背景技巧
css background之设置图片为背景技巧-css 背景 Background是什么意思,翻译过来有背景意思.同样在css里面作为css属性一成员同样是有背景意思,并且是设置背景图片.背景颜色. ...
- CSS background 之设置图片为背景技巧
首先先来看看background有那些值: 可以按顺序设置如下属性(可点击进入相应的css手册查看使用):background-color 背景颜色background-image 背景图片backg ...
- CSS background 属性详解
CSS background Property 语法: background: bg-color bg-image position/bg-size bg-repeat bg-origin bg-cl ...
- [CSS3] CSS Background Images
Body with background image and gradient html { background: linear-gradient(#000, white) no-repeat; h ...
- css background之设置图片为背景技巧
原文 Background是什么意思,翻译过来有背景意思.同样在css里面作为css属性一成员同样是有背景意思,并且是设置背景图片.背景颜色.背景图片截取等样式. 首先先来看看background有那 ...
- css background transparent All In One
css background transparent All In One opacity ul { max-height: 100px; /* max-height: 187px; */ overf ...
- css & background & svg
css & background & svg https://developer.mozilla.org/en-US/docs/Web/CSS/background backgroun ...
随机推荐
- oeasy教您玩转vim - 60- # vim选项
vim选项 从头开始 这次我们从头开始 从进入vim之前开始 我们可以在终端里面给vim怎么样的参数呢? man vim 这个如果不行的话 要先运行unminimize更新manual 也可以在v ...
- 记一次 Redisson 线上问题 → 你怎么能释放别人的锁
开心一刻 今天,我的又一个好哥们脱单了,只剩下我自己单身了 我向一个我喜欢的女生吐苦水 我:我这辈子是找不到女朋友了 她:怎么可能,你很优秀的,会有很多女孩子愿意当你女朋友的 我内心窃喜,问道:那你愿 ...
- 阅读翻译Mathematics for Machine Learning之2.8 Affine Subspaces
阅读翻译Mathematics for Machine Learning之2.8 Affine Subspaces 关于: 首次发表日期:2024-07-24 Mathematics for Mach ...
- Python | 解决方案 | 多个文件共用logger,重复打印问题
项目中封装了logging库为log.py,实现既把日志输出到控制台, 又写入日志文件文件. 环境:python3.7.3 项目中,多个文件共用logger,出现重复打印问题,解决流程记录如下: 文件 ...
- 【Java】JDBC Part5.1 Hikari连接池补充
Hikari Connection Pool Hikari 连接池 HikariCP 官方文档 https://github.com/brettwooldridge/HikariCP Maven依赖 ...
- 【JDBC】Extra01 Oracle-JDBC
关于驱动包依赖: 官网提供的地址: https://www.oracle.com/database/technologies/jdbc-drivers-12c-downloads.html Maven ...
- 【Oracle】Windiws-11G 安装
教程参考: https://jingyan.baidu.com/article/363872eccfb9266e4aa16f5d.html 安装包文件目录: 注意,使用[管理员运行此文件] 然后稍等许 ...
- 前端RSA密钥生成和加解密——window.crypto使用相关
转自简书,原文地址,本文介绍window.crypto关于RSA方面的API. crypto API支持常用的rsa.aes加解密,这边介绍rsa的应用. 浏览器兼容性 window.crypto需要 ...
- python画图报错:OSError: 'seaborn-whitegrid' is not a valid package style
解决方法: https://stackoverflow.com/questions/78019854/matplotlib-seaborn-whitegrid-is-not-a-valid-packa ...
- Human-centric Computing and Information Sciences期刊基本信息
letpub 地址: https://www.letpub.com.cn/index.php?page=journalapp&view=detail&journalid=10450&a ...