英文:
Making CSS cards slightly transparent
问题
如您所见,中间相邻的边框略暗于其他部分。如何使用CSS实现?
英文:
I want to make something like this:
As you can see, the adjacent borders in the center are slightly darker than other parts. How to make it with CSS?
答案1
得分: 3
更新 # 2023年08月22日
似乎将动画说明清楚也是个好主意。我的原始回答可以在下面找到。
这相当简单。我们使用JavaScript设置了一个鼠标移动事件的监听器。当这种情况发生时,我们根据.fakeblob
(固定位置)类的位置和当前鼠标位置来调整.blob
类的位置。这样,当您移动鼠标指针时,一个淡淡的圆圈会在卡片上跟随移动。通过使用CSS的z-index设置,我们确保圆圈仅在卡片内可见。玩得开心,尝试不同的图案!
这个想法受到了"yxsh"的代码的启发。
const all = document.querySelectorAll(".grid > div");
/* 鼠标移动事件的监听器 */
window.addEventListener("mousemove", (ev) => {
/* 在所有元素上设置 blob */
all.forEach((e) => {
const blob = e.querySelector(".blob");
const fakeblob = e.querySelector(".fakeblob");
const rec = fakeblob.getBoundingClientRect();
blob.style.opacity = "1";
blob.animate(
[
{
transform: `translate(
${(ev.clientX - rec.left) - (rec.width / 2)}px,
${(ev.clientY - rec.top) - (rec.height / 2)}px
)`,
},
],
{
duration: 300,
fill: "forwards",
}
);
});
});
:root {
/* 用于动画 */
--blob-color: rgb(255, 255, 255, 0.5);
--blob-size: 123px;
--blob-strong: 30px; /* 圆圈:30+ 像素,正方形:0 */
--blob-radius: 20%; /* 圆圈:50%,正方形:0 */
}
/* 网格 */
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 20px;
padding: 20px;
box-sizing: border-box;
width: 500px;
height: 300px;
background-image: url(https://i.stack.imgur.com/QYZq3.png);
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
/* 元素 */
.grid > div {
position: relative; /* <--- 用于动画 */
overflow: hidden;
padding: 3px;
margin: 0;
}
/* 元素部分:inner、blob、fakeblob */
/* inner:用于可读内容 */
.grid > div > .inner {
position: relative;
z-index: 1;
padding: 10px;
width: 210px;
height: 150px;
color: white;
backdrop-filter: blur(1px); /* <--- 用于可读文本 */
}
/* blob:用于动画 */
.grid > div > .blob {
filter: blur(var(--blob-strong));
position: absolute;
z-index: 0;
top: 0;
opacity: 0;
left: 0;
width: var(--blob-size);
height: var(--blob-size);
border-radius: var(--blob-radius);
background: var(--blob-color);
}
/* fakeblob:用于动画 */
.grid > div > .fakeblob {
display: hidden;
position: absolute;
z-index: 0;
top: 0;
left: 0;
width: calc(var(--blob-size) * 0.8);
height: calc(var(--blob-size) * 0.8);
border-radius: var(--blob-radius);
}
<div class="grid">
<div>
<div class="inner">这里是文本</div>
<div class="blob"></div>
<div class="fakeblob"></div>
</div>
<div>
<div class="inner">这里是文本</div>
<div class="blob"></div>
<div class="fakeblob"></div>
</div>
<div>
<div class="inner">这里是文本</div>
<div class="blob"></div>
<div class="fakeblob"></div>
</div>
<div>
<div class="inner">这里是文本</div>
<div class="blob"></div>
<div class="fakeblob"></div>
</div>
</div>
原始回答
可以使用 linear-gradient()
或 radial-gradient
。
要设置渐变背景,可以使用 background
参数。对于渐变边框,可以使用 border-image-source
。
您的请求不是很清楚,但我假设您想将四个元素的端点指向网格的中心。在这种情况下,我必须分别设置每个四个元素的背景和边框渐变,以使其朝着所需的方向辐射。
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 20px;
padding: 20px;
box-sizing: border-box;
width: 500px;
height: 300px;
background-image: url(https://i.stack.imgur.com/QYZq3.png);
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.grid div {
background-color: rgba(255, 255, 255, 0.1); /* 如果线性渐变在浏览器上不起作用 */
border-width: 1px;
border-style: solid;
border-image-slice: 1;
height: 100%;
width: 100%;
}
.grid div:nth-child(1) {
background: linear-gradient(to bottom right, rgba(255, 255, 255, 0.0) 50%, rgba(255, 255, 255, 0.4) 100%);
border-top-width: 0;
border-left-width: 0;
border-image-source: linear-gradient(to
<details>
<summary>英文:</summary>
### Updated # 2023-08-22
It seemed like a good idea to illustrate the animation as well. My original response can be read below.
It's quite simple. We set up a listener for mouse movement events using JavaScript. When this happens, we adjust the position of the `.blob` class based on the position of the `.fakeblob` (fixed position) class and the current cursor position. This way, as you move the mouse cursor, a faint circle follows along on the cards. By using CSS z-index settings, we ensure that the circle is only visible within the cards. Have fun experimenting with the pattern!
The idea was inspired by the [code of "yxsh"](https://codepen.io/yxshv/pen/JjaRZmb).
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const all = document.querySelectorAll(".grid > div");
/* event listener for mouse moving */
window.addEventListener("mousemove", (ev) => {
/* set blob on all elements */
all.forEach((e) => {
const blob = e.querySelector(".blob");
const fakeblob = e.querySelector(".fakeblob");
const rec = fakeblob.getBoundingClientRect();
blob.style.opacity = "1";
blob.animate([{
transform: `translate(
${(ev.clientX - rec.left) - (rec.width / 2)}px,
${(ev.clientY - rec.top) - (rec.height / 2)}px
)`
}], {
duration: 300,
fill: "forwards"
});
});
});
<!-- language: lang-css -->
:root {
/* to animation */
--blob-color: rgb(255, 255, 255, 0.5);
--blob-size: 123px;
--blob-strong: 30px; /* circle: 30+ px, square: 0 */
--blob-radius: 20%; /* circle: 50%, square: 0 */
}
/* grid */
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 20px;
padding: 20px;
box-sizing: border-box;
width: 500px;
height: 300px;
background-image: url(https://i.stack.imgur.com/QYZq3.png);
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
/* element */
.grid > div {
position: relative; /* <--- to animation */
overflow: hidden;
padding: 3px;
margin: 0;
}
/* element parts: inner, blob, fakeblob */
/* inner: to readable content */
.grid > div > .inner {
position: relative;
z-index: 1;
padding: 10px;
width: 210px;
height: 150px;
color: white;
backdrop-filter: blur(1px); /* <--- to readable text */
}
/* blob: to animation */
.grid > div > .blob {
filter: blur(var(--blob-strong));
position: absolute;
z-index: 0;
top: 0;
opacity: 0;
left: 0;
width: var(--blob-size);
height: var(--blob-size);
border-radius: var(--blob-radius);
background: var(--blob-color);
}
/* fakeblob: to animation */
.grid > div > .fakeblob {
display: hidden;
position: absolute;
z-index: 0;
top: 0;
left: 0;
width: calc(var(--blob-size) * 0.8);
height: calc(var(--blob-size) * 0.8);
border-radius: var(--blob-radius);
}
<!-- language: lang-html -->
<div class="grid">
<div>
<div class="inner">Text Here</div>
<div class="blob"></div>
<div class="fakeblob"></div>
</div>
<div>
<div class="inner">Text Here</div>
<div class="blob"></div>
<div class="fakeblob"></div>
</div>
<div>
<div class="inner">Text Here</div>
<div class="blob"></div>
<div class="fakeblob"></div>
</div>
<div>
<div class="inner">Text Here</div>
<div class="blob"></div>
<div class="fakeblob"></div>
</div>
</div>
<!-- end snippet -->
### Original Answer
Can use [`linear-gradient()`](https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/linear-gradient) or [`radial-gradient`](https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/radial-gradient).
To set a gradient background, you can use the [`background`](https://developer.mozilla.org/en-US/docs/Web/CSS/background) parameter. For a gradient border, you can use [`border-image-source`](https://developer.mozilla.org/en-US/docs/Web/CSS/border-image-source).
Your request wasn't very clear, but I assume you want to direct the endpoints of the four elements towards the center of the grid. In that case, I had to individually set the gradient for both the background and the border at each of the four elements to radiate in the desired direction.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 20px;
padding: 20px;
box-sizing: border-box;
width: 500px;
height: 300px;
background-image: url(https://i.stack.imgur.com/QYZq3.png);
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.grid div {
background-color: rgba(255, 255, 255, 0.1); /* if linear-gradient() not working on browser */
border-width: 1px;
border-style: solid;
border-image-slice: 1;
height: 100%;
width: 100%;
}
.grid div:nth-child(1) {
background: linear-gradient(to bottom right, rgba(255, 255, 255, 0.0) 50%, rgba(255, 255, 255, 0.4) 100%);
border-top-width: 0;
border-left-width: 0;
border-image-source: linear-gradient(to bottom right, rgba(255, 255, 255, 0.0) 50%, rgba(255, 255, 255, 0.8) 100%);
}
.grid div:nth-child(2) {
background: linear-gradient(to bottom left, rgba(255, 255, 255, 0.0) 50%, rgba(255, 255, 255, 0.4) 100%);
border-top-width: 0;
border-right-width: 0;
border-image-source: linear-gradient(to bottom left, rgba(255, 255, 255, 0.0) 50%, rgba(255, 255, 255, 0.8) 100%);
}
.grid div:nth-child(3) {
background: linear-gradient(to top right, rgba(255, 255, 255, 0.0) 50%, rgba(255, 255, 255, 0.4) 100%);
border-bottom-width: 0;
border-left-width: 0;
border-image-source: linear-gradient(to top right, rgba(255, 255, 255, 0.0) 50%, rgba(255, 255, 255, 0.8) 100%);
}
.grid div:nth-child(4) {
background: linear-gradient(to top left, rgba(255, 255, 255, 0.0) 50%, rgba(255, 255, 255, 0.4) 100%);
border-bottom-width: 0;
border-right-width: 0;
border-image-source: linear-gradient(to top left, rgba(255, 255, 255, 0.0) 50%, rgba(255, 255, 255, 0.8) 100%);
}
<!-- language: lang-html -->
<div class="grid">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<!-- end snippet -->
[1]: https://i.stack.imgur.com/QYZq3.png
</details>
# 答案2
**得分**: 0
你需要稍微调整一下设置才能获得你想要的效果,但这里有一个使用图像遮罩的示例。我使用了遮罩,因为它还可以覆盖组件上的边框。但是,我无法让它考虑到盒子阴影,并且透明度也会影响到卡片中的任何内容。要避免这种情况,您需要将两个元素叠加在一起。
另一种选择是使用卡片背景的透明渐变,完全忽略遮罩,但这样就不会淡化边框。我只在第一个框上看到了边框,其他框没有,所以不太确定您想要的是什么。是否要与图像显示的完全一样?您可能需要分别调整4个框的每一个,并且可能需要将多个元素包装在一起,以获得确切的外观。
```css
body {
background: -webkit-linear-gradient(to right, #4BC0C8, #C779D0, #FEAC5E);
background: linear-gradient(to right, #4BC0C8, #C779D0, #FEAC5E);
}
.card {
width: 200px;
height: 200px;
background: linear-gradient(135deg, rgba(53, 56, 57, 1) 0%, rgba(53, 56, 57, 1) 100%);
border: 2px solid #888;
-webkit-mask-image: linear-gradient(90deg, transparent, rgba(0, 0, 0, 1));
-webkit-box-shadow: 0px 0px 24px 3px rgba(0, 0, 0, 0.65);
-moz-box-shadow: 0px 0px 24px 3px rgba(0, 0, 0, 0.65);
box-shadow: 0px 0px 24px 3px rgba(0, 0, 0, 0.65);
}
<div class="card">
</div>
英文:
You'll have to play with the settings a bit to get exactly what you want, but here's an example using image mask. I used mask because it can also cover a border on the component. I couldn't get it to account for a box shadow however, and the transparency would also effect any content in the card. To avoid that you'd need to layer two elements.
An alternative is to use the transparent gradient for the card background and forget about mask altogether, but then it wouldn't fade the border. I only saw a border on the first box and not the others, so not entirely sure what you wanted. Exactly as the image shows? You'd probably need to adjust each of the 4 boxes individually and likely need to wrap multiple elements together to get the exact appearance.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
body{
background: -webkit-linear-gradient(to right, #4BC0C8, #C779D0, #FEAC5E);
background: linear-gradient(to right, #4BC0C8, #C779D0, #FEAC5E);
}
.card{
width:200px;height:200px;
background: linear-gradient(135deg, rgba(53,56,57,1) 0%, rgba(53,56,57,1) 100%);
border:2px solid #888;
-webkit-mask-image: linear-gradient(90deg, transparent, rgba(0, 0, 0, 1));
-webkit-box-shadow: 0px 0px 24px 3px rgba(0,0,0,0.65);
-moz-box-shadow: 0px 0px 24px 3px rgba(0,0,0,0.65);
box-shadow: 0px 0px 24px 3px rgba(0,0,0,0.65);
}
<!-- language: lang-html -->
<div class="card">
</div>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论