Custom CSS image hover-states - html

I've run in to a bit of a problem. I have a menu list where I custom made some image hover states for list items. This worked perfectly fine until I needed to change the menu items (list item text length, etc). I have to go back and re-make all of the images each time something changes.
Here are some images of what I'm trying to accomplish:
Basically the hover adds a red background and a duplicate of that red region rotated ~2 degrees and is lighter colored. Would it be possible to do this via CSS with :after and transform: rotate()? If not, what would be a nice way of accomplishing this effect for varying word lengths?
Thanks ahead of time!
Tre

This can easily be done with transform as you say. You'll need to have two elements in each button though, one for the text and one for the skewed background:
<div class="menu-button">
<div class="text">Screenings</div>
<div class="hover-bg"></div>
</div>
And style the .hover-bg class something like this:
#menu .menu-button:hover .hover-bg
{
z-index: 1;
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-color: rgba(220, 50, 50, 0.4);
transform: rotate(2deg) scale(1.05, 1);
transform-origin: center right;
}​
Here's an example on JSFiddle
Here's an example where I had some fun with transitions. Due to lazyness I only bothered to make it work in Webkit, meaning Chrome and Webkit.
Note that for cross-browser compatibility you'll need the vendor specific property prefixes (-webkit-, -moz-, etc)

this can be done in pure CSS (not even 3).
On hover have a tilted background image, position it a few pixel to the left and top and add background color.
Because of the background color, you will see only a part of the image:
<div class="text">Screenings</div>
.text {
color: #000;
margin-left: 5px;/*to make room for the hover image */
padding: 4px;
}
.text:hover {
background: #900 url(tiltedimage.png) no-repeat -5px -5px;
color: #fff;
}
This will point you to the solution.

Related

Is it possible to not trigger :hover on ::before or ::after?

I'm trying to make a custom tooltip implementation in CSS, which is working pretty decently, but I'm running into a problem. Currently, hovering over the tooltip still keeps the tooltip opened, even though I'm not hovering over the original element itself.
Of course I've tried something like ::before:hover {display:none;}, but that doesn't work because pseudo-elements don't get pseudo-classes applied to them.
My next thought was to simply make the tooltip not "take up" any space. Using negative margin-bottom allows other stuff to take up space in an element as if the element is not there. However, the :hover pseudo-class apparently still applies then.
Here's a demo of what I'd like to do. I'd like to have the tooltip of the following demo not persist any hovering state. Note that moving the tooltip-text higher above the element is not a working solution, because moving the cursor upwards faster than a snail's pace will cause some pixels to be skipped, which means the tooltip 'catches' the cursor and persists the :hover on the element.
[data-tooltip] {
position: relative;
cursor: default;
}
[data-tooltip]:hover::before {
content: attr(data-tooltip);
position: absolute;
top: -2px;
transform: translateY(-100%);
background: white;
border: 1px solid black;
}
<p>Spacer text</p>
<div data-tooltip="Example tooltip">Hover over me for a tooltip text</div>
As you can see, if you move your cursor over the div, the tooltip will appear, and if you slowly move your cursor up, the tooltip will disappear. If you move your cursor upwards slightly faster, however, it'll skip the 1-pixel gap, and keep the cursor hovering over the div.
Now I'm looking for some styles to apply to [data-tooltip]::before so that the cursor's hover events are not triggered on it (or at least, not at the location you see the tooltip; if I can hide it somewhere at [-1000, -1000] that's fine as well)
So basically, my question is, is it possible to apply css to an element so that :hover does not apply to (part of) an element? I'd love to hear ideas or suggestions.
Not sure if that's what you're looking for, but regarding the first question (red div, blue on hover), you could shorten the divs height and use border-bottom for making up for the lost height:
div {
width: 100px;
height: 50px; /* instead of 100px */
background: red;
margin-bottom: -50px;
position: relative;
z-index: 1;
border-bottom: 50px solid red; /* adds 50px to divs apparent height, but ignored at hover */
}
After looking around the internet for a while I finally found a solution that works flawlessly. I didn't really know about this before, but apparently there's a pointer-events style that does exactly what I want. Its accepted values outside of SVG are auto and none, but luckily the latter prevents all hover-events from triggering on the ::before pseudo-element.
Here's a demo:
[data-tooltip] {
position: relative;
cursor: default;
}
[data-tooltip]:hover::before {
/*** this style prevents persistence of the tooltip when hovering over it ***/
pointer-events: none;
/* the rest is just the styles used in the question */
content: attr(data-tooltip);
position: absolute;
top: 0; /* changed from -2px to 0 so the effect is more clearly shown */
transform: translateY(-100%);
background: white;
border: 1px solid black;
}
<p>Spacer text</p>
<div data-tooltip="Example tooltip">Hover over me for a tooltip text</div>

Inconsistent border widths on pseudo-elements because of translate3d -- but why?

(I've tried searching for this but can't seem to describe it correctly--if this answer exits, please point me in the right direction!)
I'm playing around with some css rules. I wanted to make a specific, secondary 2px-wide border on a pseudo-element appear around nav anchors in the header, which open a modal and blur an absolutely-positioned background image div #bg, which sits as such:
<body>
<div id="#bg"></div>
<header id="global-header">
<nav>...</nav>
</header>
</body>
Since I wanted to transition the blur effect, I added translate3d(0,0,0) to #bg, which smoothed the fps by galvanizing the GPU for hardware accelerated processing of CSS. It worked! ...Until I noticed that the vertical (left & right) borders for the links had inconsistent widths across the nav. They were each set at 2px, but every other one looked 1.5(??)px wide. It took me a minute to narrow down why, which ultimately was because of the translate3d transformation. I took screenshots, but I centered and moved the pseudo-elements with border-left: 2px below the header (the effect persisted), and I removed the background image itself so the effect would be easier to see. Here they are:
Inconsistent 2px calculation (with translate3d(0,0,0) on #bg)
Consistent widths (without translate3d transform on #bg)
And for reference, here's the code for the left-bordered pseudo-elements:
#global-header nav ul li a:before {
content: '';
position: absolute;
display: block;
top: 100%;
left: 50%;
height: 100%;
width: 0;
border-left: 2px solid gray;
background-color: transparent;
}
I know that translate3d creates as well as solves a possible host of issues from my searches--but why is this happening? Does it have anything to do with "subpixel calculations"? And why would these calculations render inconsistently throughout the page with hardware acceleration, on something I would assume is hard to mess up?
Edit: So, even without translate3d, the problem-lines flicker to a smaller width when the blur transitions (seen in the code from screenshots) are triggered, and I can reproduce the original issue without translate3d if I add backface-visibility: hidden to the pseudo-element itself. This could hint at general pixel rounding issues, with specific properties as triggers only being a symptom.
After further fiddling, answering my own question: This is not caused caused by hardware acceleration, which was my revised suspicion. Though the use of these effects showcased the problem in my particular case, I was able to recreate a version of my issue without them.
By removing transform3d from the #bg element:
#bg {
.
.
.
/* transform: translate3d(0,0,0); */
}
And, without the backface-visibility property as well, I added some width to the pseudo-element in order to see what these borders would normally look like:
#global-header nav ul li a:before {
content: '';
position: absolute;
display: block;
/* top: 100%; */
/* left: 50%; */
height: 72px;
width: 1px;
border: 2px solid black;
/* backface-visibility: hidden; */
/* border-left: 2px solid black; */
background-color: transparent;
/* transition: height .2s ease; */
}
Duh: I should have expected the result, since earlier I had tried to use the element itself (by making it 1-2px wide and coloring it) instead of border-left, which at the time seemed to fix the issue. Of course, when I did it this time using the above css, the base problem reappeared.
Though I still don't know why the aforementioned properties showcased the problem with border-left as well, addressing this might be too sporadic/situation-dependent to field here, and likely still has more to do with browser rendering than anything else.
Anyway, my question was why transform3d caused this effect, and the answer is, at least in this case, it didn't--it just made it more obvious.

CSS: round corners + opacity = image disappears in Firefox 19

I want to add rounded corners to my images using CSS and also change the opacity on mouseover because this is cute. There's a bug: after mouseover, the image disappears.
The CSS is pretty simple:
.article img {
margin-bottom: 5px;
-moz-border-radius: 15px; /* for Firefox */
-webkit-border-radius: 15px; /* for Webkit-Browsers */
border-radius: 15px; /* regular */
}
.article:hover .img {
opacity: 0.8;
}
html also just for a test (this is first image that I have googled):
<li class="article">
<div class="img">
<a href="#">
<img src="http://i.telegraph.co.uk/multimedia/archive/02371/karen-ann-jones_2371086k.jpg" alt="Url">
</a>
</div>
</li>
You can see it on jsfiddle: http://jsfiddle.net/9DjLT/3/
Browser: ff19
I encountered this problem recently while trying to implement block-level links on my website, and I solved it by adding the following rule to the un-hovered img declaration:
border: 0.001em solid transparent;
A hack, to be sure, but it seems to work.
I think you have problem in css because of li:hover its taking 100% width. So till your mouse cursor on li your image effect by opacity. Just try below change in CSS
.img a:hover{
opacity: 0.8;
}
FWIW, I hit a similar problem in Chrome 38. In my case, I had a div with a border-radius value, and an image element with a transparency value, and the transparent image was hidden. To fix this, I added a non-1 opacity to the parent element (with the border-radius). Something like this:
.round_box {
border-radius: 5px;
opacity: 0.999999;
}
.transparent {
opacity: 0.6;
}
<div class="round_box">
<div class="transparent">
</div>
... Adding opacity: 0.999999; to the parent element made the transparent element display properly. I should note that I also have a lot of other interesting styles going on - drop shadows, column layout - but, maybe a similar hack will work for others.

How to create button backgrounds with css

I read once how to create cross-browser rounded buttons with shadow using images, I lost my bookmarks unfortunately that's why I ask does anybody remember the technique.
There is left side picture i.e
And then very wide body image which ends up with right curved border/shadow like this :
So at the end you end up with one button which can be used with multiple sizes? I was googling this, but it seems noways everyone use css without images.
Does anybody knows how this technique is called or can refer me to the link? or give me code example, I'd appreciate any of those
When using an image for the start and one for end of the button, these technique is called "sliding doors" and there are myriads of search results with any search engine…
For an introduction read the A List Apart article: http://www.alistapart.com/articles/slidingdoors
But as Neurofluxation asked you in the comment above: Why the hell would you do that years after we have multiple other methods of styling a button in CSS? The A List Apart article for example is from 2003 - which is an age in Internet terms.
This technique is a variation of the "Sliding Doors" technique:
http://www.alistapart.com/articles/slidingdoors/
http://css-tricks.com/snippets/css/perfect-css-sprite-sliding-doors-button/
http://azadcreative.com/2009/03/bulletproof-css-sliding-doors/
Basically you use markup like this:
<button><span>Text</span></button>
Then style the span with the edge image to the side, overlapping the main background image of the parent element. Something like this:
button {
background:url(main-image.png) top right no-repeat;
border:0;
padding:0;
width:80px; /* with only 1 "door", you might need to set a width */
/* other resets may be necessary */
}
span {
background:url(left-door.png) left top no-repeat;
}
button, span {
height:37px; /* height of your sprite */
display:block;
}​
Demo: http://jsfiddle.net/Kqs3m/
Your results may vary depending on your sprites and the natural width of the content.
Here's the technique which I think you are looking for (using the same images you attached):
HTML:
​<a href="#" class="button">
<span>Small</span>
</a>
<a href="#" class="button">
<span>Large button</span>
</a>​​​​​​​​​​​​
CSS:
​.button {
background: url('http://i.stack.imgur.com/htUHL.png') no-repeat left top;
padding-left: 9px;
height: 37px;
display: inline-block;
text-decoration: none;
color: #555;
text-shadow: 0 1px 1px #FFF;
font-family: sans-serif;
font-size: 0.8em;
}
.button span {
background: url('http://i.stack.imgur.com/ID6nO.png') no-repeat right top;
display: inline-block;
height: 37px;
padding: 5px 12px 5px 3px;
}
.button:hover span {
​color: #333;
}​
Link to the demo: http://jsfiddle.net/v284q/
Using CSS properties instead of images can make your applications faster.
In this case you could just use: Border-Radius, Box-Shadow combined with a gradient background.
Here you can find a good Gradient Editor:
http://www.colorzilla.com/gradient-editor/
How to use Border-radius and Box-shadow:
http://www.css3.info/preview/rounded-border/
http://www.css3.info/preview/box-shadow/

Background fill shape with text on top using CSS

Right now we have a web page with a bunch of link sections on one page. Each section has a header like so:
This header background is actually two images. The first is just a rectangle and the second has the slanted side on it. As I was looking at this solution, I was wondering if I could solve this with CSS instead of images. While I am not a CSS guru, I did look at a number of examples and was able to get something similar working. However, when I attempt to put text on top of the background, it ends up above the color instead of inside it. The CSS I have also has a fixed size, which is less than idea. I would rather specify a percentage of the available area and have it fill in the color.
Here is the code I've been working with:
<STYLE type="text/css">
.mini_banner
{
display:inline;
border-bottom:30px solid blue;
border-left:0px solid transparent;
border-right:30px solid transparent;
}
</STYLE>
I wanted to apply this to a cell in a table. I also don't want to break compatibility with modern browsers. My "customers" (mostly internal people) are going to be primarily on IE8 or later but I don't want to limit myself if I can help it.
So first, is this possible? Second, how would I accomplish this? And third, is there a way to make it relative in scale instead of fixed?
I would say that you'll have less headaches all the way around if you revert to using a single background image - in this case, a white image with the notch cut out (a PNG-24 with alpha transparency). Make it bigger than you think you need by about 200%, then do something like this:
.minibanner {
background: blue url(..images/notch.png) no-repeat middle right;
font-size: 1.5em;
}
The reason is that relying on border sizes may result in some whackiness across browsers, and it will definitely look weird if any element runs to two lines.
If you make the notch image 200-300% larger, but vertically align it in the middle of the background, and you do increase the font-size, the box will grow, but your white notch will grow right along with it.
UPDATE:
The only other way I can see pulling this off is to add a non-semantic element, such as a or something similar, after your text:
<div>
<p>Hello text</p>
<span></span>
</div>
Then in your CSS:
p {
background: blue;
color: white;
float: left;
padding: 0 20px;
height: 50px;
margin:0;
line-height: 50px;
}
span {
width: 0;
height: 0;
border-top: 50px solid transparent;
border-bottom: 0px solid transparent;
display: inline-block;
border-left: 50px solid blue;
}
See this JSFiddle.
The shape is based on this tutorial on CSS triangles. Now, I've only tried this on a webkit based browser, and it works. You will have to adjust the heights every time you want to change font size, so that is a drawback.
I made it work without an extra span: jsFiddle
.mini_banner
{
width:18em; height:1.5em;
color:white; font-weight:bold; padding-left:0.5em;
margin-bottom:.5em;
}
.mini_banner:before {
display:inline-block; content:''; overflow:hidden;
width:17em; height:0;
margin-bottom:-1.5em; margin-left:-.5em;
border-bottom:1.5em solid blue;
border-right:1.5em solid transparent;
}
Tested in FF, Safari, Opera and IE. (Works in IE8, but not in IE7)