This question already has answers here:
Hole in overlay with CSS
(6 answers)
How to show an animation that is hidden behind a colored div using a "reveal" div on the surface
(5 answers)
Closed 1 year ago.
Here's sort of what I'm going for:
I have a scanner component (plays back what the camera is seeing) but I need to wrap it somehow to create a semi-opaque overlay with a transparent rectangle directly in the center of the screen.
How can this be done?
Similar to the "border" solution, you can use an inset box-shadow, some what effectively.
.wrap {
position: relative;
}
.wrap::before {
position: absolute;
height: 100%;
width: 100%;
overflow: hidden;
box-shadow: inset 0 0 0 150px rgb(0 0 0 / 70%);
content: '';
}
body {
margin: 0;
}
<div class="wrap">
<img src="https://www.fillmurray.com/1000/1000">
</div>
You can try this workaround using clip-path.
You may adjust the dimensions of the highlight by editing the
style="--left: 30%; --top: 30%; --width: 40%; --height: 40%;"
part of the .frame element.
.frame {
position: relative;
display: inline-block;
}
.frame::after {
content: '';
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1;
clip-path: polygon(
0% 0%,
0% 100%,
var(--left) 100%,
var(--left) var(--top),
calc(var(--left) + var(--width)) var(--top),
calc(var(--left) + var(--width)) calc(var(--top) + var(--height)),
var(--left) calc(var(--top) + var(--height)),
var(--left) 100%,
100% 100%,
100% 0
);
}
<div class="frame" style="--left: 30%; --top: 30%; --width: 40%; --height: 40%;">
<img src="https://picsum.photos/id/16/640/320" />
</div>
You can use border to produce the 'overlay' portion - that way you have a true 'transparent' block that darkens everything outside it. The trick is to have the borders extend to the edges of the element (or the screen) - you can do that by specifying the border-width in viewport units, like this:
.container {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.container img{
margin: auto;
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.loupe {
width: 24rem;
height: 18rem;
border: 0 solid rgba(0,0,0,0.5);
border-width: 50vh 50vw;
position: absolute;
top: -9rem; /* Half of height */
bottom: 0;
right: 0;
left: -12rem; /* Half of width */
margin: auto;
}
/* Optional - apply a shadow effect under the loupe */
.loupe::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
box-shadow: 0 0.1rem 1.5rem rgba(0,0,0,0.25);
}
<div class="container">
<img src="https://images.unsplash.com/photo-1621135177072-57c9b6242e7a?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1534&q=80"/>
<div class="loupe">
</div>
</div>
If you need to fine-tune the position of the loupe, you can use transform: translate(); to adjust the position.
Related
When setting a background gradient to background-attachment: fixed it is suddenly cropped to 50% of the page width. It seems related to the position left: 50%. I wonder if this is a bug or if I'm using the CSS wrong here:
.container {
position: relative;
height: 80px;
margin: 10px 0
}
.container:before {
content: '';
position: absolute;
top: 0;
bottom: 0;
width: 100vw;
background: #f0f0f0;
background-image: repeating-linear-gradient(315deg,rgba(0,0,0,.03),rgba(0,0,0,.03) 10px,rgba(0,0,0,.06) 0,rgba(0,0,0,.06) 20px);
left: 50%;
transform: translate(-50%);
}
.container.fixed-bg:before {
background-attachment: fixed; /* <-- This line causes the problem. Why? */
}
<div class="container">...</div>
<div class="container fixed-bg">...</div>
I know that I can bypass the issue by removing the styles left: 50%; and transform: ... but that's not a practical solution in my case. The container has an unknown left margin and the pattern needs to reach from edge to edge.
Does that mean my CSS is wrong? What CSS would display the fixed background pattern in full width?
Update
I notice that there is a different behavior across browsers:
The bug seems to be related to transform. Use margin instead
.container {
position: relative;
height: 80px;
margin: 10px 0
}
.container:before{
content: '';
position: absolute;
top: 0;
bottom: 0;
width: 100vw;
background: #f0f0f0;
background-image: repeating-linear-gradient(315deg,rgba(0,0,0,.03),rgba(0,0,0,.03) 10px,rgba(0,0,0,.06) 0,rgba(0,0,0,.06) 20px);
left: 50%;
margin-left:-50vw;
}
.container.fixed-bg:before{
background-attachment: fixed;
}
<div class="container">...</div>
<div class="container fixed-bg">...</div>
Can someone help me regarding this http://www.alerto24.com/
Why is there a wide space to the right and the horizontal scrollbar is visible?
Both your footer and content section have a right margin of -100% which causes the scrollbar. Disable that CSS property for both elements and the scrollbar is gone.
please change below css
#content::before {
background: rgba(0, 0, 0, 0) url("../images/site-bg-b.jpg") no-repeat scroll 50% 0;
content: " ";
/*left: -100%;
position: absolute;
right: -100%;
top: 0;
bottom: 0;
z-index: -1;*/
}
#footer::before {
background: rgba(0, 0, 0, 0.2) none repeat scroll 0 0;
border-top: 1px solid #032d34;
content: " ";
/*left: -100%;
position: absolute;
right: -100%;
top: 0;
bottom: 0;
z-index: -1;*/
}
I think there is a structure problem in your #footer and #content.
For example. You put background properties to apply a 100% background in :before and a max-width: 920px combined with width: 100% in footer element, which appears like a contradiction.
I suggest you these modifications :
You remove #content:before and #footer:before properties. You can create a container div in your #content element which contains the width of the website like this :
#content .container {
width: 920px;
margin: 0 auto;
}
And you apply background properties on #content which has width: 100%;
#content {
width: 100%;
background: blue; /* you put your background properties on it */
}
Also, you do the same for footer :
#footer {
position: relative;
z-index: 1;
width: 100%;
/* max-width: 920px; remove this line */
background: blue; /* you put your background properties on it */
margin: 0 auto;
padding: 30px 0 15px;
color: #fff;
}
#footer .wrap {
position: relative;
margin: auto; /* you use this property to center this container as it is on the website */
padding: 0 0 50px;
font-size: 0;
width: 920px; /* you apply width on this container instead of the #footer container */
letter-spacing: -5px;
}
EDIT : I've made a JSFiddle to explain my thoughts
See it here
Through help on stackoverflow I've been able to generate and position a CSS triangle in the correct position on my website, I've also learnt how to color a triangle in 2 equal halves.
But I am stuck on merging the two examples together, what I've tried I don't think is worth pasting here due to the mess I've made of it.
I am trying to get a triangle that has the proportions and sits at the bottom of the div like this fiddle example and then is split in 2 colors like this fiddle example.
Where I believe I am going wrong is that in the different fiddles there are different uses of:
:before
Well..., Here is my attempt to achieve this effect (proportions + split in 2 colors):
JSFiddle Demo.
In this demo, I added the triangle to the .bottom div and positioned that to stay at the top (with a negative value).
Then added margin-top: 1%; property to move the triangle when resizing the window:
HTML
<div class="top"></div>
<div class="bottom">
<div class="triangle"></div>
</div>
CSS:
.top {
/* other styles... */
position: relative;
z-index: 2;
}
.bottom {
background: lightGreen;
height: 100px;
position: relative;
z-index: 1; /* A lower z-index value than .top */
/* Or use overflow: hidden; instead */
}
.triangle {
width: 40px;
height: 20px;
position: absolute;
left: 0;
right: 0;
top: -20px;
margin: auto;
margin-top: 1%; /* Move the triangle when resizing the window */
z-index: 1;
}
.triangle:before {
content: " ";
position: absolute;
width: 0;
height: 0;
border-style: solid;
border-width: 0 20px 20px 0;
border-color: transparent blue transparent transparent;
}
.triangle:after {
content: " ";
position: absolute;
left: 20px;
width: 0;
height: 0;
border-style: solid;
border-width: 20px 20px 0 0;
border-color: red transparent transparent transparent;
}
I want to overlay a vignette over a webpage. The vignette will be fixed to the visible part of the page (i.e. the window) and the page will scroll up and down underneath it. I figure there must be a better way to do it than the way I am trying (which isn't working).
What I have tried is to have the 4 corners of the vignette as 4 separate images, that are positioned as "fixed" and have an increased z-index. That works fine. But I want to fill in the gaps between the corner images. I have created a couple of thin slices of the appropriate area of the vignette that I was hoping to repeat between the corners. But I can't seem to arrange my divs in a way that allows me to fill in the gaps. At the moment I have 4 corner parts of the vignette, with nothing in between the corners.
Here's a part of the code where I try and organise the divs. The "left" and "right" class of divs are floated respectively:
<body onload="sizeDivs()" onresize="sizeDivs()">
<div class="left">
<div class="vignette"><img id="vignette_topleft" src="code/images/vignette_topleft.png"/></div>
<div class="vignette_side" id="vignette_left"></div>
<div class="vignette"><img id="vignette_bottomleft" src="code/images/vignette_bottomleft.png"/></div>
</div>
<div class="vignette_top-bottom" id="vignette_top"></div>
<div class="right">
<div class="vignette"><img id="vignette_topright" src="code/images/vignette_topright.png"/></div>
<div class="vignette_side" id="vignette_right"></div>
<div class="vignette"><img id="vignette_bottomright" src="code/images/vignette_bottomright.png"/></div>
</div>
The events are javascript functions which determine the size of fill-in divs required and then sets their heights.
The CSS for top, left and right fill is:
.vignette {
z-index: 5;
}
.vignette_top-bottom {
background-repeat: repeat-x;
z-index: 5;
margin: 0 auto;
}
#vignette_topleft {
position: fixed;
top: 0;
left: 0;
}
#vignette_bottomleft {
position: fixed;
bottom: 0;
left: 0;
}
#vignette_topright {
position: fixed;
top: 0;
right: 0;
}
#vignette_bottomright {
position: fixed;
bottom: 0;
right: 0;
}
#vignette_left {
background-image: url("code/images/vignette_left.png");
background-repeat: repeat-y;
position: relative;
left: 0px;
top: 0px;
z-index: 10;
}
#vignette_right {
background-image: url("code/images/vignette_rightred.png");
background-repeat: repeat-y;
position: relative;
right: 0px;
top: 0px;
z-index: 10;
}
#vignette_top {
background-image: url("code/images/vignette_top.png");
position: relative;
}
You'll see various combinations of positioning in there, but it doesn't seem to make much of a difference how I position the fill bits.
Any ideas on how I can make this work?
Don't know how good this is for performance, but: http://codepen.io/hwg/pen/onapH
html:before {
position:fixed;
width:100%;
height:100%;
content:"";
box-shadow: 0px 0px 220px black inset;
pointer-events:none;
z-index:1000;
}
No extra markup!
(This is basically a full page CSS3 box shadow)
.vignette {
position: fixed;
-moz-box-shadow: inset 0 0 10em #000;
-webkit-box-shadow: inset 0 0 10em #000;
box-shadow: inset 0 0 10em #000;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
}
I have this HTML:
<div id="graphic">lorem ipsum</div>
with this CSS:
#graphic { background-image: url(image.jpg); width: 200px; height: 100px;}
The background image I'm applying is 200x100 px, but I only want to display a cropped portion of the background image of 200x50 px.
background-clip does not appear to be the right CSS property for this. What can I use instead?
background-position should not be used, because I'm using the above CSS in a sprite context where the image part I want to show is smaller than the element on which the CSS is defined.
You can put the graphic in a pseudo-element with its own dimensional context:
#graphic {
position: relative;
width: 200px;
height: 100px;
}
#graphic::before {
position: absolute;
content: '';
z-index: -1;
width: 200px;
height: 50px;
background-image: url(image.jpg);
}
#graphic {
width: 200px;
height: 100px;
position: relative;
}
#graphic::before {
content: '';
position: absolute;
width: 200px;
height: 50px;
z-index: -1;
background-image: url(http://placehold.it/500x500/); /* Image is 500px by 500px, but only 200px by 50px is showing. */
}
<div id="graphic">lorem ipsum</div>
Browser support is good, but if you need to support IE8, use a single colon :before. IE has no support for either syntax in versions prior to that.
may be you can write like this:
#graphic {
background-image: url(image.jpg);
background-position: 0 -50px;
width: 200px;
height: 100px;
}
Another option is to use linear-gradient() to cover up the edges of your image. Note that this is a stupid solution, so I'm not going to put much effort into explaining it...
.flair {
min-width: 50px; /* width larger than sprite */
text-indent: 60px;
height: 25px;
display: inline-block;
background:
linear-gradient(#F00, #F00) 50px 0/999px 1px repeat-y,
url('https://championmains.github.io/dynamicflairs/riven/spritesheet.png') #F00;
}
.flair-classic {
background-position: 50px 0, 0 -25px;
}
.flair-r2 {
background-position: 50px 0, -50px -175px;
}
.flair-smite {
text-indent: 35px;
background-position: 25px 0, -50px -25px;
}
<img src="https://championmains.github.io/dynamicflairs/riven/spritesheet.png" alt="spritesheet" /><br />
<br />
<span class="flair flair-classic">classic sprite</span><br /><br />
<span class="flair flair-r2">r2 sprite</span><br /><br />
<span class="flair flair-smite">smite sprite</span><br /><br />
I'm using this method on this page: https://championmains.github.io/dynamicflairs/riven/ and can't use ::before or ::after elements because I'm already using them for another hack.