Vertically center a span in a div on hover - html

Having issues with a hover effect in a responsive Shopify site. Really has nothing to do with Shopify but rather CSS. My issue is that when I hover over the two images on the bottom of this page (http://aworldcurated.com/) the text appears center (good) on top (bad). It should be in the middle. I tried adding a vertical-align: middle; to the spans, but no luck yet. Anyone know where I should add it or do I have to rethink this for responsive?
Here's the HTML:
<div class="product span4">
<div class="image">
<div class="sample-product-wrapper">
<img src="https://cdn.shopify.com/s/files/1/0471/0045/t/1/assets/just-arrived%20Copy.jpg?9523409680747224875" title="About a World Curated" width="302" height="302"><span class="text-content"><span>About Us</span></span>
</div>
</div>
</div>
And the CSS:
span.text-content {
background: none;
color: black;
cursor: pointer;
display: table;
font-size: 30px;
height: auto;
left: 0;
position: absolute;
top: 0;
width: 100%;
opacity: 0;
text-transform: uppercase;
-webkit-transition: opacity 500ms;
-moz-transition: opacity 500ms;
-o-transition: opacity 500ms;
transition: opacity 500ms;
}
span.text-content span {
display: table-cell;
text-align: center;
vertical-align: middle;
}

If you inspect the span in your browser, you will see that it doesn't take up any space in the container. You can either change it to a div and give it a height so your vertical-align property works, or push it down within the container with css:
.sample-product-wrapper .text-content {margin-top:45%;}
Use whatever percentage feels right.

Your image has a fixed height of 302. An easy solution then is to match the line-height property of the <span> to the image's height:
{
/*...*/
line-height: 302px;
}

Here is a nice solution:
absolute horizontal vertical centering
span.text-content{
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
}

Related

Can't quite get image to scale, and use overflow:hidden to work

Here is a link to a demo
I'm not sure what I'm missing, I've done this before a few times but It's been a day of fighting this particular CSS. I want the image to enlarge, but stay within the dimensions, so a zoom effect versus any enlargement. I've attempted to move the overflow:hidden into other parent or children, but it doesn't have an effect. I've played around with the display settings as well.
Any advice? The JSfiddle link is above, and the code below. Thanks for taking a look!
#purple-square {
width: 355px;
height: 255px;
background-image: url("../img/website_cards/purple_card.png");
border-radius: 10px;
}
#migraine-dentistry {
width: 355px;
height: 255px;
background-image: url("../img/website_cards/migraine_dentistry_card.png");
border-radius: 10px;
}
/* need position: relative in shell otherwisee the elements disappear */
#shell {
margin: auto;
width: 355px;
height: 255px;
position: relative;
transform-origin: center;
transition: 0.3s ease-in-out;
}
#shell:hover {
transform: scale(1.2);
}
#container {
width: 100%;
overflow: hidden;
display: inline-block;
transition: 0.3s;
margin: 0 auto;
}
#container div {
position: absolute;
left: 0;
transition: 0.3s ease-in-out;
}
#container:hover {
transition: ease-in-out 0.3s;
}
#container div.bottom:hover {
opacity: 0;
}
and here is the HTML setup:
<body>
<div id="shell">
<div id="container">
<div id='purple-square' class="top"></div>
<div id='migraine-dentistry' class="bottom"></div>
</div>
</div>
</body>
Full working code snipped below my steps
remove unnecessary elements Removed purple square, because it's never seen in wanted animation.
Removed the part the full #container div.bottom:hover part.
Removed every style that begins with #shell in the css and later trigger the animation on #container:hover.
main issue Add an #migraine-dentistry after the #container:hover animation, so if someone hovers the container it effects the #migraine-dentistry element. (#container:hover #mi.. {trans..})
In this (#container:hov..) element remove everything and
insert transform: scale(1.2);
because we just want to scale if user is hovering.
Remove whole #container div {..} style element, because we will directly add these styles to the #migraine-dentistry element.
In #container define px values for
> width: 355px; and height: 255px;
just because we not use the #shell element anymore. Also
> set position: relative; and z-index: 2;
that the #migrain.. element is inside his parent. And
> set border-radius: 15px;
for styling. Finally
>remove the display and transition values
because they are simply not needed.
last In #migraine-de.. styles
>set width: 100%; and height: 100%;
to fit div to parent.
> remove border-radius tag
because it's set by the #container
> add transition: 0.3s ease-in-out;
to transition like you wanted.
#container {
border-radius: 15px;
width: 355px;
height: 255px;
overflow: hidden;
z-index: 2;
position: relative;
}
#container:hover #migraine-dentistry {
transform: scale(1.2);
}
#migraine-dentistry {
width: 100%;
height: 100%;
transition: 0.3s ease-in-out;
background-image: url('https://images.unsplash.com/flagged/photo-1563248101-a975e9a18cc6?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80');
}
<body>
<div id="shell">
<div id="container">
<div id='migraine-dentistry' class="bottom"></div>
</div>
</div>
</body>
I know these long nights where you just can't get it done.

Display link on top of image and lower image opacity when mouseover of centre of image only?

Is it possible to only lower opacity and display link when I hover over the centre of my image? Have gone through trial and error, adding width, height, margins all over with no success. Currently the code works fine when I mouse over the image. But I would like it to only change opacity and display the link on mouseover of the centre of the image, something like an area of 500px width x 325px height.
<div class="processor-container">
<div class="processor-image-container">
<img class="processor-image" src="images/shop/cpu.png" alt="">
<div class="processor-link-container">
<a class="processor-link" href="shopprocessors.html">Shop Processors</a>
</div>
</div>
</div>
CSS
.processor-container {
padding: 100px 0 100px 0;
}
.processor-image-container {
position: relative;
margin: 0 auto 0 auto;
}
.processor-image {
width: 100%;
height: 100%;
}
.processor-image, .processor-link-container {
transition: opacity 0.3s ease;
}
.processor-link-container {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
opacity: 0;
transition: opacity 0.3s ease;
}
.processor-link {
display: block;
font-size: 2.6em;
color: white;
text-decoration: underline #f76441;
}
.processor-image-container:hover .processor-link-container {
opacity: 1;
}
.processor-image-container:hover .processor-image {
opacity: 0.4;
}
You will have to use the onmouseover Javascript event, which provides the properties offsetX and offsetY.

position responsive fixed button to div container css

I want to position a button responsively at the right bottom corner. So far I have put the button fixed to the centered container.
The Problem
If at any time I stretch the page (up and down , or side ways up and down) it disappears/looses focus for a slight second.
Expected:
I would like this yellow button to be vissible at all times, even if the browser is stretched.
Code:
.container{
margin:0 auto;
max-width:480px;
height: 50vh;
width: 100%;
text-align:center;
background:blue;
}
.fixed_button{
position: fixed;
bottom: 10px;
width: 70px;
height: 20px;/*height: auto;*/
margin-left: 405px;
border: 0px solid #d6d6d6;
z-index: 99;
padding: 0;
text-align: center;
background: yellow;
}
.spaces{
width: 100%;
height: 500px;
border: 1px solid #000;
}
<div class="container">
<div class="spaces"></div>
<div class="spaces"></div>
<div class="spaces"></div>
<div class="spaces"></div>
<div class="spaces"></div>
<div class="fixed_button"></div>
</div>
Also if you want to see the visibility effect, just open snippet , click full page and stretch your window around.
Container:blue & fixed button:yellow.
by the way, the container has a croll to load plugin, so it grows downwards anytime the user scrolls down the page, so .container growns and the button cant be positioned absolutely.
You can align a button at the bottom of a div by using position absolute. You can try changing your css to this.
.fixed_button{
position: absolute;
bottom: 5px;
right: 5px;
width: 70px;
border: 0px solid #d6d6d6;
//wrest of your styles
}
This should have the behaviour your looking for. Hope this helps
If you want the button fixed at the lower right bottom, you can use
position: absolute instead of fixed.
If you want responsive design, then don't use margin property with PX value. try to use with the percentage (%)
Try the following code snippet,
.fixed_button{
position: absolute;
bottom: 10px;
right: 10px;
width: 70px;
height: auto;
padding: 25px;
border: none;
z-index: 99;
-webkit-transform: translate3d(0,0,0);
-webkit-transition: all .25s ease;
-moz-transition: all .25s ease;
-ms-transition: all .25s ease;
-o-transition: all .25s ease;
transition: all .25s ease;
text-align: center;
}
I hope this will help,
As per your requirement, pure CSS solution won't work. You have to use Jquery to calculate the width of the container after window resize and then calculate the right position then assign it to your fixed element.
$(window).on('resize', function(){
var conwidth = $('.container').width()/2 - 30;
$('.fixed_button').css('left','calc(50% + '+conwidth+'px)');
});
.container{
margin:0 auto;
max-width:480px;
height:600px;
text-align:center;
background:blue;
}
.fixed_button{
position: fixed;
bottom: 0px;
left: calc(50% + 210px);
width: 30px;
border-radius:50%;
height:30px;
z-index: 99;
background: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="fixed_button"></div>
</div>
So I did the calculation like get the container width and then divide it by two then minus the fixed element width. After that I applied it as left position for the fixed element.
Here is the JSFIDDLE you can play with it.

How to put text over img on hover - width and height are variable

I know how to put text on hover on an image if the height and the width is fixed. but I have a responsive slider (owl-slider) and want to add link (easy - yeah.) and a blue overlay with white text in it and a simple fading/sliding transition from the overlay.
The problem is: every item changes its height and width on resizing. I could write several media queries, but I'm quite sure there must be a simpler solution to that problem.
I have a very simple markup:
<div>
<a href="#">
<img src="http://placehold.it/360x100">
<div class="overlay">Click here for more Infomartion</div>
</a>
</div>
Normally I would go for pure css method with setting height and width from .overlay to the image size and set visibility on hover. But.. that won't work, because the width & height will differ from viewport to viewport. So, what would you suggest?
The trick involves setting position: relative to the parent container .image-container which contains the image. Using display: inline-block will force the parent container to shrink-to-fit the image.
You then apply position:absolute to the child container (overlay) .hover-text and set all the offsets (left, right, top and bottom) to zero, which will force the overlay to match the size of the image.
If you want to vertically center the text, you need to add two nested blocks.
One way of doing it is to repurpose the a element using display: table with width and height of 100%, and then apply display: table-cell to the nested div with vertical-align: middle. This will center the text vertically if so desired.
I added a transition effect to demonstrate how to set it up. You can
adjust the details as you like for duration and transition type.
Ref: http://www.w3.org/TR/css3-transitions/
You could also do a translation using a CSS transform, which is also feasible since the modern browsers support transforms (especially in 2D).
.image-container {
position: relative;
display: inline-block;
}
.image-container .hover-text {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(0, 0, 255, 0.5);
opacity: 0;
transition: opacity;
}
.hover-text a {
display: table;
height: 100%;
width: 100%;
text-decoration: none;
}
.hover-text a div {
display: table-cell;
vertical-align: middle;
text-align: center;
font-size: 3.0em;
color: white;
}
.image-container img {
vertical-align: top; /* fixes white space due to baseline alignment */
}
.image-container:hover .hover-text {
opacity: 1;
transition-duration: 1s;
transition-timing-function: linear;
}
<div class="image-container">
<img src="http://placehold.it/360x100">
<div class="hover-text">
<a href="#">
<div>Text on hover</div>
</a>
</div>
</div>
Try this, it doesn't care about the image size
.image-container{
position: relative;
display: inline-block;
}
.image-container .hover-text{
position: absolute;
top: 33%;
width: 100%;
text-align: center;
visibility: hidden;
}
.image-container:hover .hover-text{
visibility: visible;
}
/* styling */
.hover-text{
font-family: sans-serif;
color: white;
background: rgba(0,0,0,0.3);
text-shadow: 1px 1px 1px black;
padding-top: 0.5em;
padding-bottom: 0.5em;
}
.hover-text a{
color: white;
}
<div class="image-container">
<img src="http://placehold.it/360x100">
<div class="hover-text">
Text on hover Link
</div>
</div>
Skipped the transition stuff, but is this what you're requesting?
div {
position: relative;
}
img {
width: 100%;
}
.overlay {
background: blue;
color: white;
display: none;
position: absolute;
left: 0;
top: 50%;
width: 100%;
text-align: center;
}
a:hover .overlay {
display: block;
}
JSFIDDLE: http://jsfiddle.net/volzy/hLpLabaz/1/
For full size overlay do:
.overlay {
height: 100%;
top: 0;
}

Absolute position div don't overlays another's div child

<div class="wrapper">
<div class="avatar"></div>
<div class="desc an-all"></div>
</div>
<div class="wrapper">
<div class="avatar"></div>
<div class="desc an-all"></div>
</div>
.wrapper{
position: relative;
width: 250px;
height: 150px;
cursor: pointer;
}
.wrapper:hover .desc{
opacity: 1;
}
.avatar{
width: 70px;
height: 70px;
background: green;
position: relative;
z-index: 30;
}
.desc{
position: absolute;
top: 50px;
left: 0;
height: 250px;
width: 100%;
background: red;
opacity: 0;
z-index: 20;
}
.an-all{
-webkit-transition: all 0.3s linear;
-moz-transition: all 0.3s linear;
transition: all 0.3s linear;
}
I can't figure out why is this happening. I thought that a position element inside a parent with position relative only apply inside parent and outside is a different world.
Why when I hover the green box of the first wrapper div the red one don't overlay the second's wrapper div green box ? I want the red box to be under the green one when I hover
http://codepen.io/laxmana/pen/txKbF
See if you like this example:JSFiddle
It uses your same working code, but the wrapper divs are placed within a relative parent, and each are given their own z-index. This is how you can layer one on top of another. In a real world example, the divs may not be together (like a tooltip), and then you wouldn't need the additional parent. The parent is useful when the divs are together, and on the same level. Play around with the JSFiddle, and try different options with content.
In the original example, the reason the green divs were always on top, regardless of their html order, is because the red divs are absolutely positioned, and the 2 wrapper elements are on the same level within the parent.
.wrapper {
position: relative;
width: 250px;
height: 150px;
cursor: pointer;
}
.wrapper:hover .desc {
opacity: 1;
}
.relative-container {
position:relative;
}
.top {
z-index:10;
}
.bottom {
z-index:9;
}
.avatar {
width: 70px;
height: 70px;
background: green;
position: relative;
z-index: 30;
}
.desc {
position: absolute;
top: 50px;
left: 0;
height: 250px;
width: 100%;
background: red;
opacity: 0;
z-index: 20;
}
.an-all {
-webkit-transition: all 0.3s linear;
-moz-transition: all 0.3s linear;
transition: all 0.3s linear;
}
Update
Here is an example with multiple display:inline-block divs. The trick is for the z-index to work, the divs need to be siblings/on the same level as each other (this works for other elements too). The first div in the row that needs to go on top gets the highest z-index, while the last div gets the lowest z-index.
JSFiddle Example
Here is a great resource explaining the details on the z-index https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context
Note: In the second JSFiddle I used display:none on the red ".desc" dropdowns, and made them visible only when moused over by adding display:block; to ".wrapper:hover .desc". In your original code even though you don't see the red divs, when you hover over their invisible area it triggers them to show. By using display:none, they are truly not displayed in the page and therefore can't trigger the hover state. The trick is that display:block overwrites the display:none in the hover class, so they will show when the green buttons are hovered over.
This hides the red divs:
.desc {
display:none;
This shows the red divs only when the green divs are hovered over:
.wrapper:hover .desc {
display:block;
Your z-index needs to change. Right now, both red boxes have an index lower than the green, which is why it appears beneath the second green box.
Update
Based on your comment, you want to have the green box both underlay the avatar class and overlay the same class below the wrapper. Because you're using classes alone, you can't have both actions. You could space the wrappers differently so you have the description still underlay the avatar and not overlap lower elements.
CSS
.wrapper{
position: relative;
width: 250px;
height: auto; /* Set this to auto to keep elements separate from one another */
cursor: pointer;
}
.wrapper:hover .desc {
opacity: 1;
}
.avatar{
width: 70px;
height: 70px;
background: green;
position: relative;
z-index: 30;
}
.desc{
position: relative; /* Keep it inside the document flow */
top:-20px; /* sets the overlap from the avatar class */
left: 0;
height: 250px;
width: 100%;
background: red;
opacity: 0;
z-index: 20; /* Displays below the avatar */
}
.an-all{
-webkit-transition: all 0.3s linear;
-moz-transition: all 0.3s linear;
transition: all 0.3s linear;
}
Working pen