Add a semi-transparent layer on top of a div - html

I would like to allow my user to click on the card to "cancel it". I can take care of the JS, but I am wondering what's the best way to add a "red opaque overlay" on top of the card after the user clicks it.
So ideally I can write a css class such as but also make it that it's not simply transparent at 40% but also slightly "red". And I don't want to create another dive that wraps the whole card if possible.
.card-deactivated{
opacity:40%
}
.card{
max-width:300px;
min-width:200px;
height: 350;
display: flex;
flex-direction: column;
padding: 0px 0px 20px;
gap: 10px;
background: #FFFFFF;
/* Gray/4px */
box-shadow: 0px 4px 8px rgba(41, 41, 41, 0.08);
border-radius: 10px;
overflow:hidden;
}
.card-img{
order: 0;
display:block;
margin-bottom:2rem;
}
.card-title{
align-self:center;
margin-bottom:1rem;
}
.card-description{
align-self:center;
margin:0px 20px 1rem;
text-align:center;
}
<div class='card'>
<img class='card-img' alt='Card Image' src='data:image/jpeg;base64,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'>
<h3 class='card-title'>Name Surname</h3>
<p class='card-description'>This is a long descriptionThis is a long descriptionThis is a long descriptionThis is a long descriptionThis is a long description </p>
</div>
Edit
I am achieving some sort of result by leveraging this css but I don't think I am doing it "right"...or at least in the best possible way.
.card{
max-width:300px;
min-width:200px;
height: 350;
display: flex;
flex-direction: column;
padding: 0px 0px 20px;
gap: 10px;
background: #FFFFFF;
/* Gray/4px */
box-shadow: 0px 4px 8px rgba(41, 41, 41, 0.08);
border-radius: 10px;
overflow:hidden;
position:relative;
}
.overlay-selected::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: .3;
background-image: linear-gradient(90deg, #eaee44, #eaee44);
}

You can achieve this by using one of the pseudo-elements, either ::before or ::after, that will act as an overlay when the user clicks on the .card element.
Basically, we'll initially style that overlay, we'll use the ::after pseudo-element, and place it behind the .card element using z-index of -1 so that the overlay is hidden initially. When a click occurs, we add a class, let's call it is-canceled, to the .card element that simply sets the z-index of the overlay to a higher value (like 2 or 999) so that the overlay appears on top of the .card element and act as the intended overlay.
To make the overlay transition smoothly, we'll initially set its background-color to transparent and override that when the is-canceled class is attached to the .card element. When the is-canceled class is attached to the .card element, we'll set the background-color to a reddish background (something like rgba(255, 0, 0, .7). Using the transition property we can instruct the browser to have a smooth transition when the is-canceled is added/removed from the .card element.
To illustrate, here's alive demo that allows you to toggle the overlay when you click on the .card element:
const card = document.querySelector('.card');
card.addEventListener('click', () => card.classList.toggle('is-canceled'));
.card {
position: relative; /* required to correctly position the overlay */
max-width: 300px;
min-width: 200px;
display: flex;
flex-direction: column;
padding: 0px 0px 20px;
gap: 10px;
box-shadow: 0px 4px 8px rgba(41, 41, 41, 0.08);
border-radius: 10px;
overflow: hidden;
}
/* initial overlay styles */
.card::after {
content: "";
position: absolute;
width: 100%;
height: 100%;
inset: 0;
background-color: transparent;
transition: all .4s 0s ease;
z-index: -1;
}
/* styles to be applied to the overlay when the "is-canceled" class is added */
.card.is-canceled::after {
background-color: rgba(255, 0, 0, .7);
z-index: 999;
}
.card-img {
order: 0;
display: block;
margin-bottom: 2rem;
}
.card-title {
align-self: center;
margin-bottom: 1rem;
}
.card-description {
align-self: center;
margin: 0px 20px 1rem;
text-align: center;
}
<div class="card">
<img class="card-img" alt="Card Image" src="https://via.placeholder.com/250">
<h3 class="card-title">Name Surname</h3>
<p class="card-description">This is a long descriptionThis is a long descriptionThis is a long descriptionThis is a long descriptionThis is a long description </p>
</div>
The above demo is just for demonstration purposes and you're invited to build upon it and customize it the way you see fit.

Related

Smooth simultaneous transition of height and margin

How can I make smooth transition of block with margin? See my code below:
.counter {
margin: 5rem auto;
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.2);
width: 40rem;
border-radius: 8px;
padding: 1rem;
text-align: center;
background-color: #f4f0fa;
}
.value {
font-size: 2rem;
color: #3c0080;
margin: 2rem 0;
font-weight: bold;
transition: all 1s;
max-height: 500px;
overflow: hidden;
}
.value.hidden {
margin: 0;
max-height: 0px;
}
<main class="counter">
<h1>Counter</h1>
<div id="val" class="value">10</div>
<button onClick="document.getElementById('val').classList.add('hidden')">Hide Counter</button>
<button onClick="document.getElementById('val').classList.remove('hidden')">Show Counter</button>
</main>
If you click on "Hide Counter", it is not smooth, but it looks like there are two different transitions (look on codepen). Why and how can I make smooth transition?
I just decided to change max-height to height and setting height to a fixed number
body {
display: flex;
height: calc(100vh - 16px);
align-items: center;
}
.counter {
margin: 0px auto;
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.2);
width: calc(100vw - 48px);
border-radius: 8px;
padding: 1rem;
text-align: center;
background-color: #f4f0fa;
}
.value {
font-size: 2rem;
color: #3c0080;
margin: 2rem 0;
font-weight: bold;
transition: all 1s;
height: 50px;
overflow: hidden;
}
.value.hidden {
margin: 0;
height: 0px;
}
<main class="counter">
<h1>Counter</h1>
<div id="val" class="value">10</div>
<button onclick="document.getElementById('val').classList.add('hidden')">Hide Counter</button>
<button onclick="document.getElementById('val').classList.remove('hidden')">Show Counter</button>
</main>
I have found the bug in your code... you just need to go on line no. 24 in css in your codepen and change max-height to height and you are all set to go!!
Terry is right in his comment: transitioning e.g. something with actual height 50px from max-height: 100px; to max-height: 0; produces visible change only during the second half of animation, when it reaches the actual height.
CSS can transition or animate only explicitly given values.
Satyam is also right suggesting you can transition real effective height to get all transitions run simultaneously. So you have to either give element explicit (max-)height in CSS, or you can obtain it from actual computedStyle before triggering the transition. There are few important caveats, see comments POC:
.counter {
margin: 0 auto;
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.2);
border-radius: 8px;
padding: 1rem;
text-align: center;
background-color: #f4f0fa;
}
.value {
font-size: 2rem;
color: #3c0080;
font-weight: bold;
transition: all 1s linear;
overflow: hidden;
background-color: grey;
margin: 2rem 0;
height: auto; /* you cannot transition this;
will be set in inline style
with JS */
}
.value.hidden {
height: 0px !important; /* to fight inline style, !important is necessary */
margin: 0 0;
font-size: 0;
}
<main class="counter">
<div id="val" class="value">10</div>
<button onClick="
if(!val.style.height){
val.style.height = getComputedStyle(val).height
}
/* caveat: 'seal' that value to give transition chance to start at it
(enforce style recalc and reflow)
*/
val.getBoundingClientRect();
val.classList.toggle('hidden');">Toggle Counter</button>
</main>

Is there a CSS solution for this design?

Here's my issue:
I have a mockup from a design company that wants a text block with a 'broken' square border behind some big text that looks like this (description: there is a small white frame behind large text that is broken up by the text, and then a smaller text link below):
Image of an element on client's website,
In the design, the text is displayed accross the white square frame. The way I have implemented it right now is to make the big text's background color gray. Because the current image's background is gray the desired effect is achieved.
What is needed is to achieve that effect (of breaking the white frame) REGARDLESS of the appearance of the image. Because right now, this happens:
the gray background of the text appears like a box in front of the image -- it ought to be transparent
To further illustrate, if I set the background-color of the big text to transparent, the whole frame is shown (the desired effect is a broken frame):
background: transparent #1
More info if it helps:
The white frame element is just a div with a white border.
I am not sure exactly what to search for in this case, if there is an appropriate CSS solution (preferrable) or if I need to use SVG or maybe a PNG? Thank you for any help.
As #Temani Afif pointed out in the comments, it's not one box, but two separate shapes in CSS.
I made an example to illustrate this using flexbox.
.page {
background-color: black;
width: 400px;
height: 400px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.box-top {
width: 100px;
height: 10px;
border-color: white;
border-width: 2px;
border-style: solid;
border-bottom: none;
}
.box-bottom {
width: 100px;
height: 30px;
border-color: white;
border-width: 2px;
border-style: solid;
border-top: none;
}
.separator {
color: white;
width: 100%;
margin: 5px 0;
padding: 0;
font-size: 40px;
text-align: center;
}
<div class="page">
<div class="box-top"></div>
<p class="separator">
Headline
</p>
<div class="box-bottom"></div>
</div>
You can make a square element with a border and use a mask on it:
body {
margin: 0;
min-height: 100vh;
background: black;
box-sizing: border-box;
padding-top: 1px;
}
h2.fancy {
position: relative;
text-align: center;
color: white;
padding-top: 12px;
}
h2.fancy:before {
content: '';
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 100px;
height: 100px;
border: 5px solid white;
clip-path: polygon(0 0, 100% 0, 100% 10px, 0 10px, 0 40px, 100% 40px, 100% 100%, 0 100%);
}
<h2 class=fancy>I'm a fancy title...</h2>
The advantage of this solution is that you can make it scale easily with what might change on various screen sizes. For example, with the title's font-size:
document.querySelector('input.font-size').addEventListener('input', function(e) {
document.querySelector('h2').style.fontSize = e.target.value + 'px';
})
body {
margin: 0;
min-height: 100vh;
background: url(https://picsum.photos/800) center /cover;
box-sizing: border-box;
padding-top: 1px;
}
.overlay {
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.5);
}
h2.fancy {
z-index: 1;
position: relative;
text-align: center;
color: white;
padding-top: 12px;
}
h2.fancy:before {
content: '';
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 100px;
height: 100px;
display: block;
border: 5px solid white;
clip-path: polygon(0 0, 100% 0, 100% 10px, 0 10px, 0 calc(10px + 1.3em), 100% calc(10px + 1.3em), 100% 100%, 0 100%);
}
input[type=range] {
position: absolute;
bottom: 1rem;
left: 1rem;
z-index: 1;
}
<h2 class=fancy>I'm a fancy title...</h2>
<div class=overlay></div>
<input type=range min=12 max=36 class=font-size>
The disadvantage is that it doesn't work in IE or Edge lower than 18 or in Opera mini. This particular example works in IE 18, though, as it only uses polygon().

Span doesn't fit in another span [duplicate]

This question already has answers here:
What is the difference between display: inline and display: inline-block?
(7 answers)
Closed 3 years ago.
i try to fit span in another span but for some reason it doesnt work.
I have already tried display: flex and display: flexbox.
JSFiddle
html,
body {
height: 100%;
width: 100%;
}
body {
margin: 0;
background-color: #f0f0f0;
}
#midbox {
display: block;
position: absolute;
width: 90%;
height: 85%;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
background-color: #7d7c7d;
box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.75);
}
#preview {
display: block;
position: relative;
height: 100%;
width: 35%;
background-color: #525052;
box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.75);
}
#preview p {
margin: 0;
padding-top: 3%;
font-size: 2em;
opacity: 0.7;
color: #f0f0f0;
font-family: 'Lato', sans-serif;
text-align: center;
}
#cont {
display: block;
position: relative;
height: 100%;
width: 35%;
background-color: green;
box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.75);
}
<span id="midbox">
<span id="preview">
<p>Preview</p>
</span>
<span id="cont">
<p>Why does this apper under the box and not on the left?</p>
</span>
</span>
Expectation:
Content of span with green background should be inside the lightgray box.
Output:
Content of span with green background is outside of any box.
Can you try adding float:left; to both your #preview span and #cont span. Float left forces two elements to stay on the left side.
#preview, #cont{
float:left;
}
I updated your fiddle. Try the fiddle here:
https://jsfiddle.net/edy0whkp/
Short Answer
You're setting display: block to your span elements. This turns them into block elements which start on a new line and they expand the size of their parent container. Changing the display to dispay: inline-block will cause the elements to not start a new line and to only take up as much space as they need.
https://jsfiddle.net/xypntkc0/
More details
In the JSFiddle I changed the parent element to be a div instead. Setting it to a div makes it a block component so you also don't need the display: block when it's a div. It's bad practice to place block elements inside of inline elements (you have a paragraph tag as a child tag to your span tags) So I would actually change all your span tags to divs
I also changed the position to position: relative on the parent component. You typically only want to set absolute to the children elements inside of a parent component that has position: relative. The parent is set as relative so that their absolute positioned children get positioned relative to the parent.
Even more detail
If you want to align elements next to each other inside of a container, a good tool to use is flexbox. You can set display: flex to the parent element to mark it as a flex container. Then the children will automatically be set as flex items and will render side by side and boom, you're done.
https://jsfiddle.net/vkru8wg7/
It looks like you're trying to make #preview and #cont sit side by side within #midbox. If this is the case, simply make #midbox {display: flex;}
body {
margin: 0;
background-color: #f0f0f0;
}
#midbox {
display: flex;
position: absolute;
width: 90%;
height: 85%;
top:0; right:0; bottom:0; left:0;
margin:auto;
background-color: #7d7c7d;
box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.75);
}
#preview {
display: block;
position: relative;
width: 35%;
background-color: #525052;
box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.75);
}
#preview p {
margin: 0;
padding-top: 3%;
font-size: 2em;
opacity: 0.7;
color: #f0f0f0;
font-family: 'Lato', sans-serif;
text-align: center;
}
#cont {
display: block;
position: relative;
width: 35%;
background-color: green;
box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.75);
}
<span id="midbox">
<span id="preview">
<p>Preview</p>
</span>
<span id="cont">
<p>Why does this apper under the box and not on the left?</p>
</span>
</span>
If you want to learn about flexbox there's a great article at https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Creating a “flat long shadow” for text in CSS with less CSS

Note: This question is similar to this question; however, it is different and thus is being asked as a separate question to the one just linked.
I am trying to create a flat long shadow in CSS for the text in a logo. The original way I found to do it is based on Matt Lambert's tutorial. The way Matt proposes to do it would require a lot of CSS (although, kudos to him, it does work and goodness knows I didn't figure that out). So thus that led me to ask for a way to do that with less CSS. #vals figured out how to do that with this.
Now I'm attempting to make a flat-long-shadow (does anyone have a shorter abbreviation for this? how about the acronym: "FLS?") for the text of a logo (i.e. this); however, it isn't going so well...
As you can see from this fiddle I made, I sort of combine the two techniques... but, while it's not atrocious, it doesn't work perfectly...
Here is the same fiddle in a snippet:
/* shadow color: #2d5986 */
html, body {
height: 100%;
}
body {
display: flex;
flex-flow: column wrap;
overflow: hidden;
}
div {
min-height: 128px;
min-width: 128px;
background-color: #369;
color: white;
font-size: 4em;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
span {
/* background-color: #47a; */
position: relative;
text-align: center;
text-shadow: #2d5986 1px 1px,
#2d5986 2px 2px,
#2d5986 3px 3px,
#2d5986 4px 4px,
#2d5986 5px 5px,
#2d5986 6px 6px,
#2d5986 7px 7px,
#2d5986 8px 8px,
#2d5986 9px 9px,
#2d5986 10px 10px,
#2d5986 11px 11px,
#2d5986 12px 12px,
#2d5986 13px 13px,
#2d5986 14px 14px;
}
.shadow:before, .shadow:after {
content: "";
position: absolute;
right: 0px;
bottom: 15px;
z-index: 1;
transform-origin: bottom right;
}
.shadow:before {
height: 40px; /* increased height */
width: 100%;
left: 0px;
transform: skewX(45deg);
box-shadow: 1px 40px 0px 0px #2d5986; /* 1px in x direction to avoid small gap between shadows */
}
/* .shadow:after {
width: 10px; increased width
height: 100%;
top: 25px;
transform: skewY(45deg);
box-shadow: 10px 0px #2d5986;
} */
<div>
<span class="shadow">
A
</span>
</div>
<div>
<span class="shadow">
a
</span>
<span class="shadow">
b
</span>
</div>
<div>
<span class="shadow">
A B
</span>
</div>
<div>
<span class="shadow">
A B C
</span>
</div>
The main problem is the fact that we are now working with text-shadow instead of box-shadow, and as such the :before and :after pseudo classes don't work (although I attempted to make them work by attaching them to the <span>... and then made the width: 100%).
If there was a way to set the width and height of the text-shadow itself (which is achieved on a box-shadow by using the :before and :after pseudo classes), I feel this would be a piece of cake; however, all my research has not found how to do this for a text-shadow.
Does anyone know a way to make a flat long shadow for text with minimal CSS - potentially by somehow changing the width and height of the text-shadow?
Thank you.
Though this is no css-only answer, you might give it a try.
Basically, you create the according css in the browser via a short javascript snippet. The upside is, that it makes you very flexible - changing only two parameters instead of several tens of lines of css.
function addDropShadow(element,width,color){
let css = "";
for (var i = 1;i<width;i++){
css += `${color} ${i}px ${i}px,`;
}
css += `${color} ${width}px ${width}px`;
element && (element.style.textShadow = css);
}
let element = document.querySelector(".icon");
let color = "rgb(18, 128, 106)";
addDropShadow(element,15,color);
.container { padding: 50px; background: rgb(34,45,58); } .icon { font-family: "Helvetica Neue", helvetica, arial, sans-serif; font-weight: bold; color: #fff; background-color: rgb(22, 160, 133); height: 150px;width: 150px; font-size: 75px;line-height: 150px; text-align: center; display: block; overflow: hidden; }
<div class="container"><div class="icon">YO</div></div>
I don't think there is a good CSS only approach.
The only posibility that I can think of is creating pseudos with the same text as the base, and use to reduce the amount of shadows to one third:
Notice that the pseudo itself counts as a shadow because it has the color changed to the color of the shadow
.sample {
font-size: 70px;
position: relative;
text-shadow: 1px 1px red, 2px 2px red, 3px 3px red, 4px 4px red, 5px 5px red,
6px 6px red, 7px 7px red, 8px 8px red, 9px 9px red;
}
.sample:after, .sample:before {
content: attr(data-text);
z-index: -1;
color: red;
position: absolute;
}
.sample:after {
left: 10px;
top: 10px;
}
.sample:before {
left: 20px;
top: 20px;
}
<div class="sample" data-text="Sample">Sample</div>

z-index conflict with static element

https://jsfiddle.net/0Lfzbzc5/2/
in here I am trying to make the notification box on top of the body class div but couldn't do it the logic says positioned elements should be on top of the not positioned elements but that isn't happenning
tried even making body class div relative and giving it z-index but failed too
structure of notification box is an absolute element in relative element in absolute element (for CSS animation issues)
HTML
<div class="notiIcon glyphicon glyphicon-globe">
</div>
<div class='notiAbs '>
<div class='notiContainer'>
<div class="notiBox">
<div class="notiHeader">
<span class="notiHeaderSpan">notifications</span>
</div>
<div class="notiBody">
<div class="notiElement">Collaboratively enable high-quality imperatives before ubiquitous paradigms.
</div>
<div class="notiElement">Credibly productize customized services whereas.</div>
<div class="notiElement">Efficiently embrace real-time markets without.</div>
<div class="notiElement">Synergistically simplify collaborative web services.</div>
<div class="notiElement">Intrinsicly evisculate magnetic e-services through.</div>
<div class="notiElement">Holisticly build customer directed technologies.</div>
<div class="notiElement">Phosfluorescently synthesize team driven strategic.</div>
</div>
<div class="notiFooter"><span class="notiHeaderSpan">See All</span></div>
</div>
</div>
</div>
<div class="body">aasdasdasdasdasdasdas</div>
CSS
.notiAbs{
position: absolute;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
/* overflow-y: hidden; */
height: 500px;
width: 500px;
/* overflow-x: hidden; */
overflow-y: hidden;
margin: 0 auto;
padding-left: 50px;
}
.notiContainer{
position: relative;
}
.notiIcon{
z-index: 5;
position: relative;
width:100%;
text-align: center;
font-size: 25;
cursor: pointer;
padding-top: 10px;
}
.notiIconNumber{
position: relative;
font-size: 15px;
color: white;
background-color: red;
top: -10;
left: -9;
padding: 2px;
}
.notiBox{
z-index: 4;
position: absolute;
height: 400px;
width: 400px;
display: block;
padding-top: 10px;
box-shadow: rgba(0, 0, 0, 0.298039) 0px 4px 7px;
}
.notiElement{
overflow-wrap:break-word;
font-size: 17px;
padding: 10 0px;
border-bottom-style: solid;
border-bottom-width: thin;
border-bottom-color: lightgray;
}
.notiHeader,.notiFooter{
text-align: center;
font-size: 20px;
font-weight: bold;
height: 15%;
display: table;
width: 100%;
}
.notiHeaderSpan,.notiFooterSpan{
display: table-cell;
vertical-align: middle;
}
.notiFooter{
box-shadow: 0px -4px 7px rgba(0, 0, 0, 0.1);
cursor: pointer;
}
.notiHeader{
box-shadow: 0px 4px 7px rgba(0, 0, 0, 0.1);
}
.notiBody{
padding: 20px;
overflow: auto;
height:70%;
}
.body{
}
It is on top but the background is transparent so it makes the illusion that it's not. Just set a background color as follows :
.notiBox{
z-index: 4;
position: absolute;
height: 400px;
width: 400px;
padding-top: 10px;
border-style:solid;
background:#666;
}
Check the Fiddle.
Your notification box which I believe is the element with class "notiBox" is on top. The reason why it appears not to be is because it has an inherited background-color of transparent.
If you set the background-color property to say "yellow" (for examples sake) you will see that it is on top of the element with class "body".
Does that make sense? I can explain further if you need me to.
I've updated my answer as looking at your HTML again i've realised that the element with class "notiBox" is probably the only element (and it's contents) you want to appear on top