Center a Font Awesome icon over the image on hover - html

I'm trying to center a font awesome icon over an image when the mouse is hovering the image.
Here's my HTML:
<div class="profile-img-container">
<img src="http://s3.amazonaws.com/37assets/svn/765-default-avatar.png" class="img-thumbnail img-circle img-responsive" />
<i class="fa fa-upload fa-5x"></i>
</div>
And my CSS:
.profile-img-container {
position: relative;
}
.profile-img-container img:hover {
opacity: 0.5;
}
.profile-img-container img:hover + i {
display: block;
z-index: 500;
}
.profile-img-container i {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
}
However the font awesome icon is somewhy displayed all the way to the left and the icon keeps flickering when I hover the image.
Here's my JSFiddle:
http://jsfiddle.net/fns8byfj/1/

The usage here is important to consider. This is a trigger, so I would use a link inside here. I would not display:none since IOS will not work on the actions inside this when the state on the selector was display:none or visibility:hidden even if the :hover changes this state. Use opacity and position to "hide it".
VERY IMPORTANT:
A parent is not the size of the child image inside it unless that div is the child of something that constrains its width or the div is floated or inline-block. If you put this in a column inside the grid and the image is, at any viewport width, as wide as that column, then you can remove the "inline-block" on the .profile-img-container however if you use it just stand alone you have to float it or put an .inline-block on it but then you have to change the responsiveness of the image if the parent is an inline-block max-width:100% doesn't work (just like it doesn't work if inside a table-cell).
:hover is not a good idea, I would use jQuery to make this a click by toggling the parent's class.
DEMO: http://jsfiddle.net/prtkqb44/
CSS:
.profile-img-container {
position: relative;
display: inline-block; /* added */
overflow: hidden; /* added */
}
.profile-img-container img {width:100%;} /* remove if using in grid system */
.profile-img-container img:hover {
opacity: 0.5
}
.profile-img-container:hover a {
opacity: 1; /* added */
top: 0; /* added */
z-index: 500;
}
/* added */
.profile-img-container:hover a span {
top: 50%;
position: absolute;
left: 0;
right: 0;
transform: translateY(-50%);
}
/* added */
.profile-img-container a {
display: block;
position: absolute;
top: -100%;
opacity: 0;
left: 0;
bottom: 0;
right: 0;
text-align: center;
color: inherit;
}
HTML:
<div class="profile-img-container">
<img src="http://s3.amazonaws.com/37assets/svn/765-default-avatar.png" class="img-thumbnail img-circle img-responsive" />
<span class="fa fa-upload fa-5x"></span>
</div>

You can center it both horizontally and vertically using percentage widths, but this implies that you know approximately the width in percentages of the element you are trying to position, in this case the font-awesome one. Note that I aligned it approximately, positioning it to the left and top by 45%.
I've updated your code with the above-mentioned part, and by also applying the hover effect on the containing DIV such that the font-awesome icon does not flicker. It flickered because when you were hovering over it, the hover over the image was being lost.
The HTML remains, the same, only the style differs:
.profile-img-container {
position: relative;
}
.profile-img-container i {
position: absolute;
top: 45%;
left: 45%;
transform: translate(-45%, -45%);
display: none;
}
.profile-img-container:hover img {
opacity: 0.5;
}
.profile-img-container:hover i {
display: block;
z-index: 500;
}
Your updated JSFiddle.

The following solution should work, as long as you can afford to have fixed widths in the topmost container (in the example, 300px) or otherwise manage to have a line-height value which is always equal to the rendered height of the image.
The solution exploits the line-height and text-align properties to achieve vertical and horizontal positioning, respectively.
<div class="profile-img-container">
<img src="http://s3.amazonaws.com/37assets/svn/765-default-avatar.png" class="img-thumbnail img-circle img-responsive" />
<div class="profile-img-i-container">
<i class="fa fa-upload fa-5x"></i>
</div>
</div>
.profile-img-container {
height: 300px;
width: 300px;
line-height: 300px;
position:relative;
}
.profile-img-container:hover img {
opacity: 0.5;
}
.profile-img-container:not(:hover) .profile-img-i-container {
display: none;
}
.profile-img-i-container {
position: absolute;
top: 0px;
left: 0px;
display: block;
height: 100%;
width: 100%;
z-index: 500;
text-align:center;
}
.profile-img-i-container i {
display:block;
line-height: inherit;
}
Fiddle
About the flickering:
Be careful with :hover. In your example you had the following snippet:
.profile-img-container img:hover + i {
display: block;
...
}
This causes the i element to appear when you hover the image. Then the i element is placed on top of the image, so you're not longer hovering the image, but the i element. The icon hides again, and you are again hovering the image. This is what caused the flickering effect. The solution is to work with the :hover property of the topmost element.
.profile-img-container:hover img + i {
display: block;
...
}

I have changed the position of .profile-img-container to absolute and set it's width to 50% (you can adjust the width to change the image size).
.profile-img-container {
position: absolute;
width:50%;
}
because of the flickering effect, you must set your img z-index higher than the z-index of i.
.profile-img-container img:hover {
opacity: 0.5;
z-index: 501;
}
.profile-img-container img:hover + i {
display: block;
z-index: 500;
}
I have changed the position of i to absolute and centered it using margin-left and margin-top
.profile-img-container i {
display: none;
position: absolute;
margin-left:43%;
margin-top:40%;
}
And finally I changed the position of img to absolute
.profile-img-container img {
position:absolute;
}
Try this code: http://jsfiddle.net/fns8byfj/16/

Related

CSS Flex - get div into the other div/box

I am having the following Issue:
I got a Website with a quite large DIV element, in which there is a img (sullsize).
As on the main index site, I want to have the "Site Title" called Palette within the DIV, not on the outside. Whenevery I try to do it with the Flex CSS, the Image will not go to the end (fill the element).
"My Team Site"
So my current issue is, I can't get the Palette Text into the item, and also I will be listing Photos and Jobdescriptions for the individuals, each has it's own flexbox, so it will behave right.
As said, I can't get them to be within the box.
The easyest way is if you look at my (Sample) Website:
LINK (it should look like on the main site. Maybee even with
Flex, instead of old-fashioned way)
Dashed Orange: Text Box
Dashed Red: Future Team Div (1 per Person)
This is the basic HTML and a part (ONLY A PART!) of the CSS, look at the Rest on the Website:
.content_item .content_title {
position: relative;
overflow: visible;
display: inline-block;
height: 100%;
width: 45%;
float: right;
flex-grow: 1;
flex-shrink: 1;
}
.content_item h2 {
position: absolute;
bottom: 0;
right: 0;
margin: 0;
padding-left: 20px;
width: 100px;
flex-grow: 1;
flex-shrink: 1;
color: rgba(255, 255, 255, .9);
white-space: nowrap;
letter-spacing: 1px;
font-size: 5em;
-ms-transform: rotate(270deg);
-webkit-transform: rotate(270deg);
transform: rotate(270deg);
}
<body>
<div class="site_palette">
<div class="header_div">
<h1 class="header_title">Schwarz & Torf Maler AG</h1>
<h3 class="header_subtitle">Wir Malen wo andere nur zuschauen</h3>
</div>
<div class="flex_container">
<a href="index.html">
<div class="content_item shadowbox_red">
<img src="http://maler1.calmarsolutions.ch/images/center_3.jpg" />
<div class="team_section">
<div class="team_part">
<img src="">
</div>
</div>
<div class="content_title">
<h2>Palette</h2>
</div>
</div>
</a>
</div>
</div>
</body>
The flex container is .content_item.
This container has three children (flex items):
img
div.team_section
div.content_title
Since these are three in-flow flex items, they respect each other's space and don't overlap.
The text you want to layer over the image is in an absolutely-positioned h2, which is a child of relatively-positioned .content-title.
What you need to do is add position: relative to the primary container, then apply position: absolute the non-image flex items.
Add this to your code:
.site_palette .content_item {
position: relative;
}
.team_section {
position: absolute;
}
/* adjustment below may be unnecessary */
.content_item .content_title {
/* position: relative; */
position: absolute;
right: 0;
}
.site_palette .content_item {
max-width: 70vw;
position: absolute;
}
.team_section {
display: flex;
position: absolute;
}
Locate the following code in your css:
.team_section {
display: flex;
}
And change it to:
.team_section {
display: none;
}

White overlay over an image

Hi i am aware that you can add a greyscale filter on an image, but would it be possible for a white overlay using the filter setting. I have to do it through css without the need for another div, to be absolute positioned over the image, with a white background and opacity setting changed. Just a simple image within a a tag:
<a href="#">
<img src="http://placehold.it/300x200" />
</a>
css is basic
a img{
display:block;
max-width:100%;
height:auto
}
Solution 1:
You may use the :after psuedo-element. For example, add a class of white-out to your <a> element, and then use the following CSS:
a.white-out {
position: relative;
display: inline-block;
}
a.white-out:after {
position: absolute;
content: '';
display: block;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255,255,255,.5);
}
jsFiddle Demo
Solution 2:
Alternatively, you can try setting a white background on your <a> element, and reducing the opacity of the <img /> inside. For example:
a.white-out {
display: inline-block;
background: #fff;
}
a.white-out img {
opacity: 0.2;
}
jsFiddle Demo

Pure CSS: Show image2 above/over/on top image1 on hover

SOLVED FIDDLE:
I can't figure out how to display an image(two) above/over my current visible image(one) when hovered.
Html:
<img class="two" src="img/2.png" alt="bulb">
<img class="one" src="img/1.png" alt="me">
CSS:
.one {
display: block;
margin: 0 auto;
padding-top: 50px;
}
.two {
opacity: 0;
}
.one:hover .two {
opacity: 1;
}
What am I doing wrong?
Edit: If you want to show another image below the first image, than you need to change your DOM, as CSS cannot select the previous element, but it can select adjacent image, what you are using is .one:hover .two which will select an element having class .two nested under element having class .one on hover but since the elements are adjacent, you can use the selector below, but note that you need to change the element order in the DOM.
.one:hover + .two {
opacity: 1;
}
Demo
I assume Above means on hover you want to swap the image, so if that's what you want than use CSS Positioning techniques by setting your images to position: absolute; which are nested under position: relative; container.
Demo
div {
position: relative;
}
div img { /* Setting images to absolute */
position: absolute;
top: 0;
}
div img:nth-of-type(2) { /* Initially hiding image 2 */
opacity: 0;
}
div:hover img:nth-of-type(1) { /* On hover of div we hide 1st image */
opacity: 0;
}
div:hover img:nth-of-type(2) { /* On hover of div we show 2nd image */
opacity: 1;
}
You can also add transition property to smoothly swap the image on hover
Demo
div img {
position: absolute;
top: 0;
-moz-transition: all .5s;
-webkit-transition: all .5s;
transition: all .5s;
}
Try using position:absolute and wrap your images with a div
div.images{
border:solid green 4px;
height:120px;
width:120px;;
margin-top: 50px;
position:relative;
}
.images img{
position:absolute;
top:0;
left:0
}
.two {
opacity:0;
z-index:1;
}
.images:hover .two {
opacity: 10;
}
DEMO
if it does not matter which one of your images come first you can change your html like this :
<img class="one" src="img/1.png" alt="me">
<img class="two" src="img/2.png" alt="bulb">
and use this CSS:
img.one:hover + img.two {
opacity: 1;
}
because there is no backward in CSS.

how to have the same hover image for many images

I have a few pictures in a table that they work as a link and in hover a play button should appear over them.
I tried many different tricks but they all have problems which dont work properly. I decieded to share my question here to find an standard solution.
Here is what I have done so far:
img{
position: relative;
}
img:hover:before {
background:url(http://i40.tinypic.com/i3s4dc.png) no-repeat center center;
content:"";
width: 100%;
min-height: 100px;
position: absolute;
left: 0;
}
I dont know if I am in the right direction or not, but have a look at the demo http://jsfiddle.net/jmXdh/8/ and if it is wrong then please let me know any other way.
You unfortunately can't use the ::before and ::after pseudo-elements with replaced elements. The content of all replaced elements is outside the scope of CSS.
From the Generated and Replaced Content Module (WD):
Replaced elements do not have '::before' and '::after' pseudo-elements; the 'content' property in the case of replaced content replaces the entire contents of the element's box.
Here's something that might work, assuming you can add additional markup:
http://jsfiddle.net/isherwood/jmXdh/11/
a {
display: inline-block;
overflow: hidden;
position: relative;
}
a:hover .play {
background:url(http://placehold.it/80x80) no-repeat center center;
opacity: 0.8;
position: absolute;
width: 80px;
height: 80px;
left: 50%;
top: 50%;
margin-left: -40px;
margin-top: -50px;
}
<a href="/">
<div class="play"></div>
<img class="img" src="http://i42.tinypic.com/2v9zuc1.jpg" />
<br />
<b>Video test</b>
</a>
Or with a transition effect:
http://jsfiddle.net/isherwood/jmXdh/12/
.play {
opacity: 0;
transition: opacity 0.3s;
}
a:hover .play {
opacity: 0.7;
}

CSS I want a div to be on top of everything

How do I make an html div tag to be on top of everything? I tried adding z-index: 1000, but it remains the same.
In order for z-index to work, you'll need to give the element a position:absolute or a position:relative property. Once you do that, your links will function properly, though you may have to tweak your CSS a bit afterwards.
Yes, in order for the z-index to work, you'll need to give the element a position: absolute or a position: relative property... fine.
But... pay attention to parents!
The element's z-index may be limited by its parent's z-index value.
You have to go down the nodes of the elements to check if at the level of the common parent the first descendants have a defined z-index.
All other descendants can never be in the foreground if at the base there is a lower definite z-index.
In this snippet example, div1-2-1 has a z-index of 1000 but is nevertheless under the div1-1-1 which has a z-index of 3.
This is because div1-1 has a z-index greater than div1-2.
.div {
}
#div1 {
z-index: 1;
position: absolute;
width: 500px;
height: 300px;
border: 1px solid black;
}
#div1-1 {
z-index: 2;
position: absolute;
left: 230px;
width: 200px;
height: 200px;
top: 31px;
background-color: indianred;
}
#div1-1-1 {
z-index: 3;
position: absolute;
top: 50px;
width: 100px;
height: 100px;
background-color: burlywood;
}
#div1-2 {
z-index: 1;
position: absolute;
width: 200px;
height: 200px;
left: 80px;
top: 5px;
background-color: red;
}
#div1-2-1 {
z-index: 1000;
position: absolute;
left: 70px;
width: 120px;
height: 100px;
top: 10px;
color: red;
background-color: lightyellow;
}
.blink {
animation: blinker 1s linear infinite;
}
#keyframes blinker {
50% {
opacity: 0;
}
}
.rotate {
writing-mode: vertical-rl;
padding-left: 50px;
font-weight: bold;
font-size: 20px;
}
<div class="div" id="div1">div1</br>z-index: 1
<div class="div" id="div1-1">div1-1</br>z-index: 2
<div class="div" id="div1-1-1">div1-1-1</br>z-index: 3</div>
</div>
<div class="div" id="div1-2">div1-2</br>z-index: 1</br><span class='rotate blink'><=</span>
<div class="div" id="div1-2-1"><span class='blink'>z-index: 1000!!</span></br>div1-2-1</br><span class='blink'> because =></br>(same</br> parent)</span></div>
</div>
</div>
More simply :
For z-index:1000 to have an effect you need a non-static positioning scheme.
Add position:relative; to a rule selecting the element you want to be on top
You need to add position:relative; to the menu. Z-index only works when you have a non static positioning scheme.
z-index property enables you to take your control at front. the bigger number you set the upper your element you get.
position property should be relative because position of html-element should be position relatively against other controls in all dimensions.
element.style {
position:relative;
z-index:1000; //change your number as per elements lies on your page.
}
I gonna assumed you making a popup with code from WW3 school, correct?
check it css. the .modal one, there're already word z-index there. just change from 1 to 100.
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 100px; /* Location of the box */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
It seems like nesting an element inside a <dialog> element puts it on top of everything. It is placed both horizontally and vertically centered to the screen if you use showModal() but you lose the interactivity with other elements in the page.
document.querySelector("dialog").showModal();
<dialog>
<div class="element">I am on top of everything else</div>
</dialog>
<div class="backdrop">Backdrop element</div>
If you still want interactivity with the background elements, you can use the show() method. It is placed only horizontally centered to the screen.
document.querySelector("dialog").show();
<dialog>
<div class="element">I am on top of everything else</div>
</dialog>
<div class="backdrop">Backdrop element to check if I am underneath or not.</div>