设计小哥哥说,这次需求有点复杂哦! 我心想,不就是样式吗?能有多复杂?再复杂的样式不过多些几行而已! 等我拿到设计图的时候,发现是真复杂啊!
图片区域分为单图和多图。
- 单图情况
- 正常图 160x160
- 超宽图 长边160,高为宽边的3/8
- 超高图 高边160,宽为高边的3/8
- 多图情况 80x80
我一看这么复杂,根本不想用css来写了,还是用js吧。
function computeImageStyle(imgs) {
const maxSize = 160; // 单张图片的最大宽高
const normalSize = 80; // 两张及以上的图片宽高
const imageStyle = {};
if (imgs.length >= 2) {
imageStyle.width = normalSize + 'px';
imageStyle.height = normalSize + 'px'
} else {
const { width, height } = imgs[0];
let finalWidth = 'auto';
let finalHeight = 'auto';
if (width > 8 * height / 3) {
// 超宽图
finalWidth = maxSize;
finalHeight = Math.floor((finalWidth * 3) / 8);
} else if (height > 8 * width / 3) {
// 超高图
finalHeight = maxSize;
finalWidth = Math.floor((finalHeight * 3) / 8);
} else if (width > height) {
finalWidth = maxSize;
} else {
finalHeight = maxSize;
}
imageStyle.width = typeof finalWidth === 'number' ? finalWidth + 'px' : finalWidth;
imageStyle.height = typeof finalHeight === 'number'
? finalHeight + 'px'
: finalHeight;
}
return imageStyle;
}
当我写完还是很得意的,哼,小需求小需求~
等到我提交代码的时候,我们组的大佬说用css写就好了,我🤯惊呆,果然一年过去了,我还是那个小菜鸡。
仔细研究了一下大佬的代码,我知道了关键点就在css的属性:only-child上,这个属性的意思是没有任何兄弟元素的元素。
利用这个:only-child属性,就可以很好的区分单图和多图的情况下。多图的情况比较简单,不用多说。那怎么处理单图的三种情况呢?
噔噔噔,还是得js出马。用js对比图片的宽高,如果是超高图,给超高图的样式;如果是超宽图,给超宽图的样式。
话不多说,直接看代码
.imgs_wrp {
display: flex;
}
.img_item {
width: 80px;
height: 80px;
background-position: 50% 50%;
background-size: cover;
object-fit: cover;
// 如果有相邻左的节点,添加左间距
&+& {
margin-left: 4px;
}
// 单图默认宽高相等
&:only-child {
width: 160px;
height: 160px;
// 超宽图的高为宽的3/8
&.img_item_lw {
height: auto;
min-height: ~"calc(160px * 3 / 8)";
}
// 超高图的宽为高的3/8
&.img_item_lh {
width: auto;
min-width: ~"calc(160px * 3 / 8)";
}
}
}
最终效果如下
题外话
除了用:only-child,还可以用一个非常神奇的属性:first-child:last-child替代。看着这个属性很绕,解释一下,就是既是第一个又是最后一个元素。什么情况下第一个会是最后一个呢?不就是只有一个元素的情况嘛!
这个属性太绕了,不好好想想都想不清楚,最好不要写,容易挨打。
如果想挨更毒的打,也可以写:nth-child(1):nth-last-child(1)。
完整代码
如果想亲自尝试一下,可以用下面的完整代码。在codepen里就可以跑起来了。
html部分
<div class="blocks">
<div>
<h1>单图</h1>
<div class="imgs_wrp">
<img
class="img_item"
src="https://i.pinimg.com/564x/f8/1a/74/f81a74e6a15329c0343ba6279ccaeb6f.jpg"
/>
</div>
</div>
<div>
<h1>多图</h1>
<div class="imgs_wrp">
<img
class="img_item"
src="https://i.pinimg.com/564x/f8/1a/74/f81a74e6a15329c0343ba6279ccaeb6f.jpg"
/>
<img
class="img_item"
src="https://img95.699pic.com/xsj/0r/r9/pc.jpg!/fw/700/watermark/url/L3hzai93YXRlcl9kZXRhaWwyLnBuZw/align/southeast"
/>
</div>
</div>
<div>
<h1>超宽图</h1>
<div class="imgs_wrp">
<img
class="img_item img_item_lw"
src="https://img95.699pic.com/xsj/0r/r9/pc.jpg!/fw/700/watermark/url/L3hzai93YXRlcl9kZXRhaWwyLnBuZw/align/southeast"
/>
</div>
</div>
<div>
<h1>超高图</h1>
<div class="imgs_wrp">
<img
class="img_item img_item_lh"
src="https://i.pinimg.com/564x/f8/1a/74/f81a74e6a15329c0343ba6279ccaeb6f.jpg"
/>
</div>
</div>
</div>
css部分
.blocks {
display: flex;
gap: 30px;
}
.imgs_wrp {
display: flex;
}
.img_item {
width: 80px;
height: 80px;
background-position: 50% 50%;
background-size: cover;
object-fit: cover;
// 如果有相邻左的节点
&+& {
margin-left: 4px;
}
// 单图默认宽高相等
&:only-child {
width: 160px;
height: 160px;
// 超宽图的高为宽的3/8
&.img_item_lw {
height: auto;
min-height: ~"calc(160px * 3 / 8)";
}
// 超高图的宽为高的3/8
&.img_item_lh {
width: auto;
min-width: ~"calc(160px * 3 / 8)";
}
}
}