Controlling hover area and CSS image sprites - css

Using a CSS image sprite, I'm creating an 'interactive' image where hovering over certain areas changes part of the image. All works fine but struggling with being able to control the area of the hover once you are over the hover area.
For example, lets say the main area is 400x400 pixels and the hover area is 100x100 from the top left corner. As you move into the hover area, the 'new' image to display is 200x200. This appears but then this 'new' 200x200 image becomes active; I can then move anywhere within this new image (to say 150x150) and the hover image is still there even though now I am out of the 100x100 original hover area. Is there any way to restrain this so that the active area is always 100x100 even with the 200x200 hovered image displayed?
My (cut-down) CSS (areaTest.css) is:
#bigArea {
width: 400px;
height: 400px;
background: url(areaImage.jpg) no-repeat;
margin: 10px auto; padding: 0;
position: relative;
}
#bigArea li {
margin: 0;
padding: 0;
list-style: none;
display: block;
position: absolute;
}
#bigArea a {
display: block;
text-indent: -9999px;
text-decoration: none;
}
#littleArea {
width: 100px;
height: 100px;
}
#littleArea a {
width: 100px;
height: 100px;
}
#littleArea a:hover {
width: 200px;
height: 200px;
background: url(areaImage.jpg) 0px -410px no-repeat;
}
and my HTML is:
<link href="areaTest.css" rel="stylesheet" type="text/css">
<div>
<ul id="bigArea">
<li id="littleArea"></li>
</ul>
</div>
Any help would be much appreciated.
Thanks, Jam

I forked Kyomu's solution and applied the opposite: http://jsfiddle.net/FEkcx/
The <a> is an empty block that is on top of a <div> that actually has the background image. The hover is triggered using #littleArea a:hover + div.

Well, I have a solution. "Cover up" the part you don't want it to trigger on (ex: with empty divs). By doing this it will no longer be hover over the object.
Example
I think there might be a better way using selectors (like +), but this works.

Related

mix-blend-mode issues in Chrome

I've been trying to use the mix-blend-mode on a page that has contains instances of css opacity transitions. What appears to be happening is that the div containing the mix-blend-mode displays as it would without the blend mode during the transition, or rather, while the animation is in progress. I've only found it to be an issue in Chrome.
In my example, while the div is transforming the blend-mode displays correctly over the image but not over the page background. Once the transition is complete it goes back to display as it should. In other words the blended div appears as solid yellow on the black background while the animation is ongoing but since it is set to darken it should be invisible over the black background. Once the animation is finished it appears as it should. It appears normal over the image.
I've tried this is Firefox and Safari and there seems to be no issue.
Pen: http://codepen.io/anon/pen/QGGVOX
Edit - I've found another instance where this occurring that doesn't involve any animation. Weirdly it happens when the position of one div is set to fixed while the other is absolute, see here: http://codepen.io/anon/pen/wooRME If the position of the div .image is changed to absolute then the blend-mode appears normal.
body {
background: #000;
}
.blend {
height: 650px;
width: 50%;
background-color: yellow;
mix-blend-mode: darken;
position: absolute;
opacity: 1;
left: 0;
top: 0px;
z-index: 100;
}
img {
position: relative;
z-index: 0;
}
So, I think I figured the problem. During the animation, it seems like the body doesn't count as an element, thus making the yellow appear at 1 opacity. I tested with other blend mode and it always appears yellow. (when set to 'difference the expected result would be white instead of yellow)
So the fix? just add a div with 100% sizes and a black background! Then, the yellow has something to blend in and doesn't show up.
Here's the code that worked in your pen:
html - added the bg div:
<div class="bg"></div>
<div class="blend"></div>
<img src="http://lorempixel.com/500/500/">
it's css:
.bg{
background: #000;
position: absolute;
width: 100%;
height: 100%;
margin: 0;
}
body {
background: #000;
width: 100%;
height: 100%;
margin: 0;
}
I also changed the body to fill the window so the margin weren't yellow too. Alternatively, the blend div could be sized in function of the body.
tagging #chrscblls since they wanted to know if you found anything.
EDIT :
For the other codepen the problem wasn't the same tho. They were trying to darken an image and a yellow rectangle onto a gray background.
If they didn't want the yellow to show on their gray background, the solution was simply to put the image inside a div and use ::after to blend in a color. Or even just make an empty div, give it the image as background and use the ::after.
this:
<div/>
with:
body {
background: #333;
}
div{
position:fixed;
width: 500px;
height: 500px;
top:50px;
left: 50px;
mix-blend-mode: darken;
background-image: url("http://lorempixel.com/500/500/");
}
div::after {
content: "";
height: 100%;
width: 100%;
background-color: yellow;
mix-blend-mode: darken;
position:absolute;
opacity: 1;
left: 0;
top: 0;
}
or this:
<div><img src="http://lorempixel.com/500/500/"></div>
without the 'background-image' in the div css.

Inside transparent arrow on the top

I would like to make a transparent arrow over an image. This triangle should be indented in a block and show the background image.
Desired output:
I used skewX() property that #web-tiki had explained here but I want it to display on the top of the border rather than on the bottom of image and have this issue:
A fiddle demo of my code is available here
Can anyone tell me why it's not working in my case?
As stated in the question, your case is a bit different from the example that was provided by web-tiki. In the example that you were referring to, the border with the transparent cut was included as the bottom border for the image whereas you need it as the top border of the plain text area.
The expected output can be achieved with the same skew technique described in that answer. However, it needs to be tweaked a bit to match your case.
First thing is, the skewed pseudo-elements (that produce the border) should be added to the container of plain text area and not the top section which holds the image. This part you have already done correctly.
Next, you need to position the border such that even with the border the height of your text container will be equal to the other two images placed by its side. For this, you need to position the elements that form the border within the plain text container (top: 0%) instead of above it (bottom: 100% in your code).
Then, if the text container has a non-transparent background, you need to clip it such that it is not present behind the elements that is creating the border effect. This can be achieved by adding a padding-top on the text container equal to the height of the border pseudo-elements and then setting background-clip: content-box to it.
Finally, you need to move the entire bottom part up by the same number of pixels as the height of the border in order for the top image to be seen through the transparent cut out area. This can be done by adding a negative margin-top to the bottom container.
Putting it altogether your code should be similar to the below snippet to achieve the effect that you need. (Note: Your fiddle has way too much code and so I have created a simpler sample for the demo).
.section {
height: 200px;
width: 500px;
background: url(http://lorempixel.com/500/200/nature/3);
}
.bottom-container {
margin-top: -15px;
height: 100px;
width: 500px;
}
.text,
.middle-image,
.right-image {
float: left;
height: 100%;
width: calc(100% / 3);
}
.middle-image {
background: url(http://lorempixel.com/200/100/nature/2);
}
.right-image {
background: url(http://lorempixel.com/250/100/nature/1);
}
.text {
position: relative;
box-sizing: border-box;
height: 100%;
padding-top: 15px;
text-align: center;
line-height: 85px;
background: #F7F7F7; /* Just for demo */
background-clip: content-box; /* needed only if your background is not transparent */
overflow: hidden;
}
.text:after,
.text:before {
position: absolute;
content: '';
top: 0px;
height: 15px;
background: rgb(215,182,115);
}
.text:before {
left: 0px;
width: 25%;
transform-origin: left bottom;
transform: skew(45deg);
}
.text:after {
right: 0px;
width: 75%;
transform-origin: right bottom;
transform: skew(-45deg);
}
<!-- prefix free library to avoid browser prefixes in CSS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<section class="section">
</section>
<div class="bottom-container">
<div class="text">Some text</div>
<div class="middle-image"></div>
<div class="right-image"></div>
</div>
Screenshot:
Note: The images that are displayed when the snippet is executed could be different from those in the screenshot because they are random placeholder images

CSS navigation with cut-out notch as marker

I know I have seen this somewhere before, but I am trying to create a black fixed navbar with a marker that is transparent cut-out triangle. I need help getting the triangle cut-out to be transparent to the background, so when you scroll the page, you can see through to the content beneath:
I have a standard list/anchor navigation with a javascript to move the .current class depending upon the page section:
<div class="navbar">
<ul>
<li class="current"><a>home</a></li>
<li><a>products</a></li>
<li><a>services</a></li>
<li><a>contact us</a></li>
</ul>
</div>
styled with the following CSS:
.navbar {
width: 100%;
position: fixed;
background: black;
float: left;
}
ul, li {
list-style: none;
margin: 0;
padding: 0;
float: left;
}
a {
padding: 10px 20px 20px;
}
.current a {
background: transparent url('../img/wedge-red.png') center bottom no-repeat;
}
The only way I can think to do it is to add extra divs on either side of the ul and assign the background to them, and then use a transparent png with a cutout as the background of the li a's.
Is there a way to do this without getting really ugly like that, and adding extra divs?
Try CSS pseudo elements!
Add 2 free DOM elements before and after an existing element in the DOM. Ideal in cases when you don't want to add stuff to your markup to satisfy styling needs.
CSS Markup
.item:before {
content:"";
display: inline-block;
width: 20px;
height: 20px;
background-color: silver;
}
.item:after {
content:"";
display: inline-block;
width: 20px;
height: 20px;
background-color: gray;
}
HTML
<div class="item">Content</div>
Check this JSFiddle for a demo.
Make sure you set content: "" and display:block in order to see them.
Here's what I ended up with -- extending the borders and cropping them with overflow: hidden; (a little hacky, but it works and doesn't add elements to the DOM):
.navbar {
width: 100%;
height: 60px;
position: fixed;
overflow: hidden;
}
ul {
border-left: solid black 2000px;
border-right: solid black 2000px;
position: absolute;
top: 0;
left: 50%;
margin-left: -2000px;
}
The above worked nicely for my purposes, and behaves in a responsive environment.
The other answer on this page, using :before and :after pseudo elements didn't work for my purposes. It ended up being too fussy, the pseudo elements wouldn't align properly, and kept wrapping to the next line when the browser window was resized. That solution as suggested works with fixed-width elements, not percentages as was specified in the original question.

Not being able to click a link next to a fixed div.

EDIT: Problem is solved.. I can't believe I didn't think about that to begin with.
Solution:
#message-box{position:fixed;bottom: 29px;left:0px;width: 400px;}
---- Original message :
Hi,
Here is the image:
http://i242.photobucket.com/albums/ff198/Warz/divchatproblemmodified.png
(it says id=footer there but its supposed to say id=footerbar. Also the bar in the very bottom (where you enter a message, with an id called "statusbar" ) should cover width: 100%; as it already does. )
I'm trying to create a bottom bar on my site with chat. The chat size should be possible to resize (change height). As you can see, I placed a div (msg-top) above the chat, which means, when chat is resized the msg-top should also be moved.
If you take a look at the following image you will see the problem. The <div id="footerbar"> has following settings and hence cover the entire area:
#footerbar {position: fixed;bottom: 0px;left: 0px;right: 0px;}
All the divs are children of #footerbar.
Because of this, if I resize the chat box to height 100% no links can be clicked. Even with small height like on the picture, all links to the right of chat box cannot be clicked...
What can I do to solve this?
Thanks!
The other divs:
/* background opacity */
#opacity-me,#msg-top,#msg-messages,#statusbar {
background: black;
color: white;
border-top: dotted 1px white;
opacity: .90;
filter: alpha(opacity="90");
z-index: 200;
overflow: hidden;
overflow-y: auto;
}
#statusbar {
position: relative;
}
#message-box{
position:relative;
width: 400px;
}
#msg-top {
overflow: hidden;
border: 0px;
border: dotted 1px white;
}
#msg-messages {
padding-left: 4px;
padding-right: 4px;
height: 100px;
border: 0px;
}
The Element is below another Element, so you're not able to klick the Link, the Link is still working... just use z-index on footerbar or try to change the footerbar position...
give the div id=footer a height, so something like:
#footerbar {position: fixed;bottom: 0px;left: 0px;right: 0px; height:30px;}
this should fix it, just adjust the height accordingly. let me know if this works.

How do you vertically center a custom image in a <li> element across browsers?

The design for the website I am working on calls for a custom image on lists instead of a bullet. Using the image is fine, but I have been having difficulties ensuring that it is centered against the text of the list item across all browsers. Does anyone know of a standard solution for this?
If you are referring to using a custom image bullet for your list this is the code you'll want to use, it will be vertically centered. I'm assuming here that the bullet image is 12px by 12px.
ul li {
background: transparent url(/link/to/custom/bullet.gif) no-repeat 0 50%;
padding-left: 18px;
}
The only problem with this is that sometimes on long multi-line list items it looks odd. In that case it might be best to assign the background position to a slight indent from the top and the left (i.e. no-repeat 0 7px).
cheers, Bruce
set a specific line-height on the li element and a vertica align on the image.. worked for me
li { height: 150px; line-height: 150px; }
li img { vertical-align: middle; }
and the HTML code
<li><img src="myimage.jpg" /></li>
if you want adapt the image to a custon size, preserving the ratio
li img { max-width: 150px; max-height: 150px; width: auto; height: auto; }
Have you tried adding the following code in your CSS file?
li
{
background-image: URL('custom.png');
background-repeat: no-repeat;
background-position: center;
}

Resources