认识CSS的background(十)
本帖最后由 马黑黑 于 2024-3-20 19:46 编辑 <br /><br /><style>#pa { font: normal 18px/26px sans-serif;}
#pa p { margin: 16px 0; }
#mama {
margin: auto;
width: 600px;
height: 400px;
background: url('https://638183.freep.cn/638183/t24/1/10.jpg') no-repeat center/cover;
position: relative;
--left: 260px;
}
#mama::before {
position: absolute;
content: '';
top: 0;
left: var(--left);
width: 160px;
height: 160px;
border-radius: 50%;
background: url('https://638183.freep.cn/638183/t24/1/10.jpg') no-repeat -260px 0;
transition: 2s;
}
.tMid { text-align: center; }
.mum { position: relative; margin: 0; padding: 10px; font: normal 16px/20px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; color: black; background: rgba(240, 240, 240,.95); box-shadow: 2px 2px 4px gray; border: thick groove lightblue; border-radius: 6px; }
.mum ::selection { background-color: rgba(0,100,100,.35); }
.mum div { margin: 0; padding: 0; }
.mum cl-cd { display: block; position: relative; margin: 0 0 0 50px; padding: 0 0 0 10px; white-space: pre-wrap; overflow-wrap: break-word; border-left: 1px solid silver; }
.mum cl-cd::before { position: absolute; content: attr(data-idx); width: 50px; color: gray; text-align: right; transform: translate(-70px); }
.tRed { color: red; }
.tBlue { color: blue; }
.tGreen { color: green; }
.tDarkRed { color: darkred; }
.tMagenta { color: magenta; }
</style>
<div id="pa">
<p>先来做个小游戏:以下演示,div盒子用了一张尺寸和它一样的图片做背景,盒子下方有一个按钮,点击按钮看看发生了什么。</p>
<div id="mama"></div>
<p class="tMid"><button id="btnMove" type="button" value="0">移动</button></p>
<p>不要方,没什么可怕的,刘谦见了也只不过是吓一跳而已,然后含泪离开现场。嗯嗯,我们的魔术显然刘谦做不出来,迄今为止,刘谦的魔术貌似没有拿过人体做道具,他不应该伤心离去,这可是我们关于 background 属性的最后一课了。现在我们来见证奇迹的原理,先看代码:</p>
<div class='mum'>
<cl-cd data-idx="1"><<span class="tDarkRed">style</span>></cl-cd>
<cl-cd data-idx="2">#myDiv {</cl-cd>
<cl-cd data-idx="3"> <span class="tBlue">margin:</span> 30px auto;</cl-cd>
<cl-cd data-idx="4"> <span class="tBlue">width:</span> 600px;</cl-cd>
<cl-cd data-idx="5"> <span class="tBlue">height:</span> 400px;</cl-cd>
<cl-cd data-idx="6"> <span class="tBlue">background:</span> url(<span class="tMagenta">'123.jpg'</span>) no-repeat center/cover;</cl-cd>
<cl-cd data-idx="7"> <span class="tBlue">position:</span> relative;</cl-cd>
<cl-cd data-idx="8"> <span class="tBlue">--left:</span> 260px;</cl-cd>
<cl-cd data-idx="9">}</cl-cd>
<cl-cd data-idx="10">#myDiv::before {</cl-cd>
<cl-cd data-idx="11"> <span class="tBlue">position:</span> absolute;</cl-cd>
<cl-cd data-idx="12"> <span class="tBlue">content:</span> <span class="tMagenta">''</span>;</cl-cd>
<cl-cd data-idx="13"> <span class="tBlue">top:</span> 0;</cl-cd>
<cl-cd data-idx="14"> <span class="tBlue">left:</span> <span class="tBlue">var</span>(--left);</cl-cd>
<cl-cd data-idx="15"> <span class="tBlue">width:</span> 160px;</cl-cd>
<cl-cd data-idx="16"> <span class="tBlue">height:</span> 160px;</cl-cd>
<cl-cd data-idx="17"> <span class="tBlue">border-radius:</span> 50%;</cl-cd>
<cl-cd data-idx="18"> <span class="tBlue">background:</span> url(<span class="tMagenta">'123.jpg'</span>) no-repeat -260px 0;</cl-cd>
<cl-cd data-idx="19"> <span class="tBlue">transition:</span> 2s;</cl-cd>
<cl-cd data-idx="20">}</cl-cd>
<cl-cd data-idx="21"><<span class="tDarkRed">/style</span>></cl-cd>
<cl-cd data-idx="22"> </cl-cd>
<cl-cd data-idx="23"><<span class="tDarkRed">div</span> <span class="tRed">id</span>=<span class="tMagenta">"myDiv"</span>><<span class="tDarkRed">/div</span>></cl-cd>
</div>
<p>再看解释:</p>
<p>这是一个 600*400 的 div 盒子,它有一个背景图片(第6行代码),它的伪元素 ::before 也有一个相同的背景图片(第18行代码)。主元素的背景图片真实还原底图的样貌,因为图片的大小也是 600*400,因此第6行代码的 center/cover 作用不大,可以不要;伪元素本质上是主元素的子元素,它浮动于宿主元素之上,而我们这个 ::before 伪元素尺寸为 160*160(代码第15、16行),我们要截取美女的头像做它的背景图像,所以要对底图进行定位。对背景图片进行定位,使用的是 background-position 属性,上面代码我们是用了 background 这个简写属性,no-repeat 之后的数据 -260px 0 就是 background-position 的数据,意思是,伪元素 ::before 的背景图片水平方向往左移动 260 个像素,垂直方向往上移动 0 个像素(0px 可以省略像素单位)。</p>
<p>很多应用场景会需要从一整张图片中截取一部分作为元素的背景图像,比如工具条按钮,那么,上面的 ::before 伪元素对背景图片的处理方法就能大显身手,我们要掌握的技巧是如何调遣 background-position 属性,例如代码中,我们设置 background-position 为 -260px 0,其含义上面已做解释,而具体从图片的什么地方开始截取图片片段则依据我们对背景图像样貌的需求,本例我们要的是美女的头部和肩膀,我们需要PS或任意作图软件乃至像素尺来测量一下图片,获取我们需要的图像部分的起始点xy两个方向的数据,上面的演示例子是从图片左边260px处、上边0px处截取,所得数据用到 background-position 时,大于零的数据均使用负数表示图片往左边移动背景图片。被截取的宽度和高度则为元素的宽高尺寸,这个无需测量,仅需要保证被截取的图像片段是完好的就行。必须注意,截取图片的一部分做背景图片的这种操作就不要再去设置 background-size 属性,设定好图片的“裁剪”位置之后其他的一切依赖于图片自身,就是说,从“裁剪”点开始,往右、往下的图片内容取真实图片的若干单位,以元素的宽高尺寸为标准,图片不做任何伸缩;否则,如果设置 background-size,所得结果可能将不是自己所预期的。</p>
<p>大家可能对移动头像的特效感兴趣,那就发个福利吧。实现代码如下:</p>
<div class='mum'>
<cl-cd data-idx="1"><<span class="tDarkRed">p</span> style=<span class="tMagenta">"<span class="tBlue">text-align:</span> center;"</span>><<span class="tDarkRed">button</span> <span class="tRed">id</span>=<span class="tMagenta">"btnMove"</span> type=<span class="tMagenta">"button"</span> value=<span class="tMagenta">"0"</span>>移动<<span class="tDarkRed">/button</span>><<span class="tDarkRed">/p</span>></cl-cd>
<cl-cd data-idx="2"> </cl-cd>
<cl-cd data-idx="3"><<span class="tDarkRed">script</span>></cl-cd>
<cl-cd data-idx="4">btnMove.onclick = () => {</cl-cd>
<cl-cd data-idx="5"> <span class="tBlue">let</span> ar1 = [<span class="tMagenta">'600px'</span>,<span class="tMagenta">'260px'</span>], ar2 = [<span class="tMagenta">'复位'</span>,<span class="tMagenta">'移动'</span>], idx = btnMove.value;</cl-cd>
<cl-cd data-idx="6"> myDiv.style.setProperty(<span class="tMagenta">'--left'</span>, ar1);</cl-cd>
<cl-cd data-idx="7"> btnMove.innerText = ar2;</cl-cd>
<cl-cd data-idx="8"> btnMove.value = btnMove.value == 0 ? 1 : 0;</cl-cd>
<cl-cd data-idx="9">};</cl-cd>
<cl-cd data-idx="10"><<span class="tDarkRed">/script</span>></cl-cd>
</div>
<p>至此,关于 background 属性,该讨论的内容我们都已经讨论完了。讲义共十个,看上去有点多,内容却不复杂,用心领会,三下五除二就能掌握。</p>
</div>
<script>
btnMove.onclick = () => {
let ar1 = ['600px','260px'], ar2 = ['复位','移动'], idx = btnMove.value;
mama.style.setProperty('--left', ar1);
btnMove.innerText = ar2;
btnMove.value = btnMove.value == 0 ? 1 : 0;
};
</script>
太好了,就等着这节的内容呢。之前一直不明白background-position:里的负值是从哪为参照算的,看了这个明白了。类似于伪元素左移和上移,就对应上需要裁剪的位置了,然后动剪刀,OK,完美{:4_199:} 这帖子的语言太幽默了,能吓到刘谦的移头魔术{:4_196:} 把美人切头太狠了点,弄个犯人来多好{:4_170:} 选取背景一部分裁剪成元形奇妙!! 亚伦影音工作室 发表于 2024-3-20 16:36
选取背景一部分裁剪成元形奇妙!!
那是因为 ::before 伪元素使用了了 border: 50% 的缘故,这是很常见的头像封装方法 红影 发表于 2024-3-20 14:10
太好了,就等着这节的内容呢。之前一直不明白background-position:里的负值是从哪为参照算的,看了这个明 ...
其实你应该早明白额,文科生。即使是看了这个教程才知道background-position,也能从前面介绍的专门章节理解背景图像位置的设定是针对元素坐标系的。本节则截取图片的一部分,将图片摆放在元素水平方向的负数位置,它等于将图片对应左边距作为元素自己的最左边缘。 红影 发表于 2024-3-20 14:11
把美人切头太狠了点,弄个犯人来多好
那要提请最高人民法院才能用的。普通人的图像我们用用没人管,只要不用于非法目的;罪犯则受严格的法律保护,不能乱用的。 红影 发表于 2024-3-20 14:10
这帖子的语言太幽默了,能吓到刘谦的移头魔术
{:4_181:} 马黑黑 发表于 2024-3-20 17:56
那是因为 ::before 伪元素使用了了 border: 50% 的缘故,这是很常见的头像封装方法
得好好学学伪元素! 亚伦影音工作室 发表于 2024-3-20 18:32
得好好学学伪元素!
哦,这个是不是伪元素都行的,子元素就好 挺有意思的,一点也不可怕。我不懂代码,就看成是复制了一层头像,然后再移开{:4_173:} 马黑黑 发表于 2024-3-20 18:01
其实你应该早明白额,文科生。即使是看了这个教程才知道background-position,也能从前面介绍的专门章节 ...
“等于将图片对应左边距作为元素自己的最左边缘”。嗯嗯,知道了{:4_187:} 马黑黑 发表于 2024-3-20 18:02
那要提请最高人民法院才能用的。普通人的图像我们用用没人管,只要不用于非法目的;罪犯则受严格的法律保 ...
弄个古代的,谁管啊{:4_173:} 马黑黑 发表于 2024-3-20 18:03
用幽默的语言讲解枯燥的理论,是黑黑特色之一{:4_187:} 这个好象是天镜里出现过的那个裁剪。{:4_173:}
能移动和复位,游戏一样好玩。。。这个教程设计的绝好。。{:4_199:}
南无月 发表于 2024-3-20 20:31
能移动和复位,游戏一样好玩。。。这个教程设计的绝好。。
还不差 红影 发表于 2024-3-20 20:07
用幽默的语言讲解枯燥的理论,是黑黑特色之一
哪里,胡乱说来着,因为不专业 红影 发表于 2024-3-20 20:05
弄个古代的,谁管啊
对古人不敬,天诛地灭