I’m creating a simple webpage for Halloween. I have a background JPG of a starry night sky with a moon in the center. Background 500px by 500px. Moon area would be roughly 100px by 100px center on the image. I have a gif I made of a witch that fly’s across the entire night sky of the background on hover (in front of the moon). Works fine.
I just want the hover area (mouse in/mouse out) to be the moon area itself instead of the whole night sky. The witch gif is triggered if you hover only over the moon but still fly across the whole width of the night sky background. Whenever I contain the hover area to just the moon, the gif is only visible in the moon area instead of the whole night sky.
Can you have a gif area 500px by 500px but the hover area to trigger it is only 100px by 100px center? I’ve searched the site and didn’t quite find what I was looking for. Any help is appreciated. Thanks!
This is the simple working HTML code below:
.backgrounds {
height: 500px;
width: 500px;
background-image: url('Background_moon.jpg');
}
.backgrounds:hover {
cursor: pointer;
background: url('flying_witch.gif'), url('Background_moon.jpg');
}
<div class="backgrounds"></div>
You can create a div for the moon area and another div for the witch inside the .backgrounds element. The witch element must be after the moon area element:
<div class="backgrounds">
<div class="moon-area"></div>
<div class="witch"></div>
</div>
First, let's centralize the .moon-area element.
You can centralize it in 2 different ways.
1) Flexbox: using on the parent display: flex, justify-content: center (horizontally) and aling-items: center (vertically), like this:
.backgrounds {
background-image: url('Background_moon.jpg');
height: 500px;
width: 500px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.moon-area {
width: 100px;
height: 100px;
z-index: 1;
}
2) Auto margin: using position: relative on the parent, and position: absolute on the .moon-area with some positioning (left, right, top, bottom) and margin: auto properties:
.backgrounds {
background-image: url('Background_moon.jpg');
height: 500px;
width: 500px;
position: relative;
}
.moon-area {
width: 100px;
height: 100px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
z-index: 1;
}
We have also the .witch CSS:
.witch {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
}
So, you can apply the hover effect on .moon-area element. We can use the very uself ~ selector to select the next sibling.
.moon-area:hover ~ .witch {
cursor: pointer;
background: url('flying_witch.gif'), url('Background_moon.jpg');
}
Also, don't forget to set z-index: 1 to the .moon-area element and position: relative to the .backgrounds element.
Related
I'm trying to add a stylish "wave" element to the top of a div, however with my attempts, the svg moves from its position and leaves a gap when the browser resizes.
Here's a mockup of what it should look like:
CSS:
.wave {
position: absolute;
top: -72px;
}
.container {
background: #eee;
}
.col-1 {
height: 200px;
}
.col-2 {
position: relative;
background: #fff;
height: 100px;
width: 100%;
margin-top: 100px;
}
My other attempt was using background-image: url(wave.svg); in a :after selector, but same results.
Here's a codepen:
https://codepen.io/anon/pen/LmRyLK
How can I get the wave to keep put as is when it's resizing and when it's not?
Set your SVG as a background image on the element where you have your funky purple bit, you can stack the background images on each other, like so:
.purpleElement{
background: url("/path/to/asset/image.svg") bottom center no-repeat, purple;
background-size: 100%;
/*I've set a height here to replicate content*/
height: 70vh;
width: 100%;
}
I've forked off your codepen to show what will happen
I want to align the header text (blue background) to the right/bottom corner of the header so that it is ALWAYS in that position no matter the device (responsive). So far it looks different on every device I've tested on, so I'm stumped. I've spent ALL DAY on this and gotten nowhere. Can anyone help?
Thank you!
[URL removed for privacy]
P.S. I have read CSS Positioning relative to corner of Div and tried to implement it, but am still stuck!
You can give position: relative to the parent and position: absolute; right: 0; bottom: 0; to the child element and the child will be positioned relatively to the parent (it will be at the bottom right corner). Here is an example:
.wrapper {
width: 100%;
height: 150px;
position: relative;
background-color: violet;
}
.target {
position: absolute;
width: 100px;
height: 100px;
background-color: black;
color: white;
text-align: center;
line-height: 100px;
right: 0;
bottom: 0;
}
<div class="wrapper">
<div class="target">TARGET</div>
</div>
Hope this image explains more, what I want
(The transparent part of the image should indicate it is bigger than the .content Div :-)
Is there an almost save way (preferably just CSS) to let a background image start at the center?
background-position: center top;
… would use the image's center, not the left corner.
I can't manipulate the image itself (using a transparent offset) nor use absolute values.
You won't be able to do this with a background image on the desired element without using absolute values. See this answer for an illustration of why. In a nutshell, background positioning with percentages and keyword values works much like a sliding puzzle, keeping the image strictly within the element's background positioning area. Only absolute values are exempt from this behavior.
You could cheat by making the image a background of a pseudo-element of the desired element instead, but this requires the desired element to be relatively positioned and act as a containing block for all absolutely positioned descendants, including the pseudo-element:
.content {
position: relative;
height: 200px;
border: 1px solid;
}
.content#one { width: 100px; }
.content#two { width: 200px; }
.content::before {
content: '';
position: absolute;
left: 50%;
width: 50%;
height: 100%;
background: url(http://placehold.it/150x150) no-repeat;
}
<div class="content" id="one"></div>
<div class="content" id="two"></div>
Can be done with pseudo elements
.cimg {
border: 1px solid black;
height: 400px;
position: relative;
}
.cimg::after {
content: "";
position: absolute;
left: 50%;
top: 0;
height: 100%;
width: 50%;
background-image: url("http://www.youramazingplaces.com/wp-content/uploads/2014/06/sunset-5.jpg");
background-repeat: no-repeat;
background-size: 400px;
}
<div class="cimg">
</div>
How can I use HTML and CSS to make a div with an image inside it that is clipped and masked so that it looks like the following:
I've been trying to find a way to do this for about 2 hours now and got nowhere so I was just hoping someone could point me in the right direction. To be specific here, I wish to clip the image such that the top two corners are rounded, and embed it in a div element with four rounded corners and a 1/4 bottom padding, with both elements transformed such that it appears the right edge is further away from the viewer than the left.
In order to create such an effect, where the image remains the same, but the outer shape has this perspective look, you could use something similar to the demo below.
div.inner {/*gives top section effect, also crops the image*/
position: absolute;
top: 0;
left: 0;
border-radius: 20px 20px 0 0;
height: 200px;
width: 300px;
overflow: hidden;
border: 10px solid red;
transform: skewY(5deg);
}
.inner img {/*removes transform skew from image*/
transform: skewY(-5deg);
transform-origin: top left;
height:100%;width:100%;
}
.wrap {
display: inline-block;
height: 200px;
width: 300px;
position: relative;
/*for demo only*/
margin: 100px 100px;
}
.wrap:after { /*give bottom section the effect*/
content: "";
position: absolute;
bottom: -50%;
left: 0;
height: 100%;
width: calc(100% + 20px);
transform: skewY(-10deg);
transform-origin: bottom right;
background: red;
z-index: -1;
border-radius: 20px;
}
<div class="wrap">
<div class="inner">
<img src="http://lorempixel.com/500/500" />
</div>
</div>
In order to create the effect, I have had to incorporate this wrapper div. This allows the use of a pseudo element (the :after css) to generate the lower part of the shape:
+----------------------------+
| |
| _______/ <-- curved corner
| ------/
| ------/
\-----/
/\
\_____ also curved corner
The inner div is then hence used to generate the upper part of the shape. Using the skew declaration, the shape allows the opposite of the :after element, bringing the right hand side of the red shape down wards.
The overflow:hidden ensures any part of the image that does not fit within this inner div will be cropped (the border-radius:20px 20px 0 0; ensures only the upper corners are affected).
The last point to note is the .inner img css. Since I have skewed the .inner div, it is important to then 'unskew' the image so it remains the rectangular shape. This is why there is a 'counter-skew' here (transform: skewY(-5deg);).
Here's my attempt using perspective.
Thanks to #vals for the pointing out that perspective can be used as part of the transform.
* {
box-sizing: border-box;
}
figure {
perspective: 1000px;
width: 420px;
margin: 5em auto;
height: 350px;
background: red;
text-align: center;
padding: 10px;
border-radius: 25px;
transform: perspective(1200px) rotateY(50deg);
}
img {
border-radius: 20px 20px 0 0;
}
<figure>
<img src="http://lorempixel.com/400/200/sports/1/" alt="" />
</figure>
Due to browser performance implications I can't use box-shadow CSS property because I have many similarly looking elements on my page that should have same looking style including shadow. That's the reason I would like to implement shadows using traditional PNG imagery.
Facts
My elements have predefined and more importantly fixed pixel width
They have fluid height (auto) depending on their content
They have content directly in the element and some child elements will be positioned outside their border
CSS3 can be used but performance-critical parts (gradients, shadows...) should be avoided
CSS pseudo elements can be used without limitation
Requirements
There should be no additional wrapper element added in order to have fluid shadow
Application should run smoothly on mobile browsers - shadows seem to slow down performance significantly on mobile devices since their processing power is much lower than desktop computers.
Possible direction
I thought of using :before and :after pseudos to display top-to-bottom and bottom shadows on the containing element, but these pseudos display within their parent element and positioning parent z-index higher than these children has no effect.
Visual demo of end result
This JSFiddle Demo in pure CSS3 that I would like to achieve but using PNG shadows. In reality there are numerous of these boxes so you can imagine mobile browsers are struggling with all these shadows.
Item is one such box (see blow) that needs PNG shadow. Left menu is child element positioned outside of the box.
Display in Chrome
HTML
<div class="item">
<menu>
<li>Yes</li>
<li>No</li>
<li>Maybe</li>
</menu>
<div class="content">
Some content
</div>
</div>
CSS3 LESS
.item {
position: relative;
width: 300px;
background-color: #fff;
box-shadow: 0 0 10px #ccc;
margin: 20px 20px 20px calc(20px + 3.5em);
min-height: 5em;
&:first-child {
margin-top: 0;
}
&:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 10px;
height: 5em;
background-color: #fff;
}
menu {
position: absolute;
top: 0;
left: -3.5em;
width: 3.5em;
margin: 0;
border: 0;
padding: 0;
list-style: none;
background-color: #fff;
box-shadow: 0 0 10px #ccc;
li a {
display: block;
text-align: center;
padding: 2px 0;
}
}
.content {
padding: .75em 1em;
}
}
Probably I am missing something, but looks like you want something in this way:
demo
The CSS is
.base {
width: 300px;
height: 150px;
font-size: 100px;
font-weight: bolder;
background-color: lightgreen;
position: relative;
z-index: auto;
}
.base:after {
content: '';
position: absolute;
top: 30px;
left: 30px;
background-color: green;
z-index: -1;
width: 100%;
height: 100%;
}
.child {
position: absolute;
left: 150px;
top: 50px;
border: solid 1px black;
color: red;
}
And just change the background of the :after to your image.
I have applied this solution to your fiddle.
The relevant CSS is for the before pseudo element:
.item:before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
z-index: -1;
background-image: url(http://placekitten.com/100/100);
background-repeat: no-repeat;
background-size: 100% 100%;
}
I have used a kitten picture, that is being scaled to cover all the needed size. Just change that to whatever you want.
I needed to do it that way because I had onky a pseudo element available.
The key for that to work (and where you probably had the difficulty) is to add z-index: auto to .item
Updated demo
Well, I had said that it wasn't posible, but I have find a way.
The standard technique would be to use 2 elements, just to avoid stretching the image (as you said). The problem is that we only have 1 pseudo element available.
The solution then would be to use 1 pseudo element, but with 2 backgrounds, to solve the issue.
CSS (only relevant part)
.item:before {
background-image: url(http://placekitten.com/320/10), url(http://placekitten.com/320/500);
background-repeat: no-repeat;
background-size: 100% 9px, 100% calc(100% - 9px);
background-position: left bottom, left top;
}
We will need an image (the first one) only 10 px in height, to cover the bottom shadow. And another one, with enough height to cover the maximumitem posible, and that will be used for the remaining part of the shadow. The dark part is that we need now a calc() height, with limited support. (anyway, better than border image)
demo 3