I want to create a div where one of the children is visible and one is out of the div, I've been using overflow:hidden for this, however whatever i try i can't seem to get this to work, I've tried positioning one absolute and that works, but as soon as I extend the div to reveal the extention it will overlap it obviously. Any help would be great, here are some pictures of the main concept.
Before Being Clicked
After Being Clicked
note: I am using react js to develop this, if you could make a codepen or something in vanilla javscript just as a concept of the main functionality and then I will convert it to react.
Thanks in advance :)
Here is one way:
.expandable {
position: relative;
}
.expandable>div {
width: 200px;
transition: all 1s;
overflow: hidden;
background-image: url('https://via.placeholder.com/200');
background-repeat: no-repeat;
min-height: 200px;
border: 1px solid black;
}
.expandable>div>img {
position: absolute;
width: 200px;
}
.expandable>input { display: none; }
.expandable>label {
position: absolute;
top: 90px;
left: 210px;
transition: all 1s;
background-image: url('https://img.icons8.com/flat_round/64/000000/arrow--v1.png');
width: 20px;
height: 20px;
background-size: cover;
background-repeat: no-repeat;
transform: rotate(0deg);
}
.expandable>input:checked+label {
left: 410px;
transform: rotate(180deg);
}
.expandable>input:checked~div {
width: 400px;
}
.expandable>div>div {
width: 200px;
padding-left: 200px;
}
<div class="expandable">
<input type=checkbox id='ex1'>
<label for='ex1'></label>
<div>
<div>
<!-- right side content -->
<h1>Stuff here</h1>
<p>lorem ipsum</p>
</div>
</div>
</div>
This uses the label as the button. When clicked, it triggers the input to be checked/unchecked. We then use the status of the checkbox to change our CSS, and we use transitions so that it is smooth, works across all modern browsers, and is very battery efficient for mobile devices.
Related
I'm building a memory cards game with HTMl, CSS and JS to practice.
This is what I've done so far: https://spomin.krix12.repl.co/
As you can see, the image of the question mark and the image of the flipped card is streched a little bit.
This is the CSS code for it:
.memory-game {
width: 640px;
height: 640px;
margin: auto;
display: flex;
flex-wrap: wrap;
perspective: 1000px;
}
.memory-card {
width: calc(25% - 10px);
height: calc(33.333% - 10px);
margin: 1px;
position: relative;
transform: scale(1);
transform-style: preserve-3d;
transition: transform .5s;
box-shadow: 1px 1px 1px rgba(0,0,0,.3);
}
memory-card is inside memory-game. How can I fix the streched images? Is there a problem in html(I can provide you the code if needed) or css or should I crop the images itself to some ratio?
I would appreciate your help.
1. First solution:
The first column is using div tag in change of img, which could be a non-feasible solution accesibility-wise. This is how I've done it:
<div class="back-face" style="
height: 100%;
background-image: url('slike/emoji-ji/zaprto.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
"></div>
2. Second solution:
Using flex! (as Hades mentioned below)
Put the img inside a div, then make that div a display: flex;, and turn its content to align-items: center;. The image, in turn, needs a few properties to know how to render width and height, which you can adjust to your needs.
<div class="back-face" style="display: flex;align-items: center;">
<img src="slike/emoji-ji/zaprto.png" alt="zaprto" style="
width: 100%;
height: 50%; // or auto
">
</div>
3. Third and best solution:
Let's use what we learned so far, and change a lot of code around! If you want all of them to look like the third one, here's the steps:
Change the CSS:
.memory-card {
width: calc(25% - 10px);
height: auto;
margin: 1px;
position: relative;
transform: scale(1);
transform-style: preserve-3d;
transition: transform .5s;
box-shadow: 1px 1px 1px rgb(0 0 0 / 30%);
/* add the following lines which used to be in img */
border-radius: 5px;
background: #1C7CCC;
display: flex;
align-items: center;
}
.front-face, .back-face {
/* a few things removed */
width: 100%;
position: absolute;
backface-visibility: hidden;
}
.front-face {
transform: rotateY(180deg);
/* add the following line to keep consistency */
padding: 20px;
}
And resulting html will look like:
<div class="memory-card" data-framework="gospod" style="order: 4;">
<img class="front-face" src="slike/emoji-ji/gospod.png" alt="vesel">
<img class="back-face" src="slike/emoji-ji/zaprto.png" alt="zaprto">
</div>
Barely any minor changes!
Final Thoughts
Remember, using inline style within your html is an antipattern! Make sure to refactor the code provided into your own css classes.
You can keep the images from stretching by only specifying a specific width or height (but not both).
You might want to wrap the images in a div that sizes to the size of the parrent and centers the image within it (For instance by using a flexbox with justify-content: center; and align-items: center;)
I'm trying to make something where I need to duplicate all the entries (multiple times) and then later I would like to make it spin and land on a colour slowly, etc. I'm now just getting stuck at duplicating the colours, how can I make it so the new colours are overflowing, without doubling the width?
I want it so that the colours go out of the wrapper div. Now they are just distributing themselves.
Any ideas?
$(document).on("click", ".duplicate", function() {
var $wrapper = $('.wrapper .inner');
$wrapper.find('.color').each(function() {
$wrapper.append($(this).clone());
});
});
.wrapper {
width: 75%;
margin: 12px auto;
height: 26px;
border-radius: 6px;
overflow: hidden;
position: relative;
}
.wrapper .inner {
width: 100%;
height: 100%;
position: absolute;
display: flex;
}
.wrapper .color {
width: 100%;
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="inner">
<div class="color" style="background:red;width:231%"></div>
<div class="color" style="background:purple;width:111%"></div>
<div class="color" style="background:orange;width:91%"></div>
</div>
</div>
<button class='duplicate'>
Duplicate
</button>
In order to have two items in the same position in document flow you need to wrap them in a parent with position:relative and give one of them position:absolute; top:0;left:0. Also note that if your element doesn't have any content, you might need to define it's height and width. To make it same size as parent, you can give it top:0;bottom:0;left:0;right:0;.
Here's a demo started from your fiddle. You might want to inspect DOM after you press "Duplicate". I made it revert to original, so you can do it multiple times.
But do note your question is currently unclear. I'm afraid you lost me at "to make it spin and land on a colour slowly". It's truly poetic, but won't get you very far on SO...
I guess you are simply over complicating this. All what you need is a reapeated linear-gradient like this:
.wrapper {
width: 75%;
margin: 12px auto;
position: relative;
}
.wrapper .inner {
width: 100%;
height: 25px;
display: flex;
border-radius: 6px;
overflow: hidden;
}
.wrapper .color {
width: 100%;
height: 100%;
}
.new {
margin-top:5px;
height:25px;
border-radius: 6px;
background-image:linear-gradient(to right,red,red 54%,purple 54%, purple 80%,orange 0);
background-size:100% 100%;
animation:change 5s linear infinite alternate;
}
#keyframes change {
from {
background-position:0 0;
}
to {
background-position:-1000px 0;
}
}
<div class="wrapper">
<div class="inner">
<div class="color" style="background:red;width:231%"></div>
<div class="color" style="background:purple;width:111%"></div>
<div class="color" style="background:orange;width:91%"></div>
</div>
<div class="new"></div>
</div>
I am trying to animate a div upwards when a user hovers on the div.
I am able to animate the div making it bigger, however the animation happens downwards. I am trying to keep the bottom of the div remain in the same place, and have a smooth animating increasing the size of the div upwards.
See jsfiddle here which demonstrates what my code is currently doing.
Please see code below:
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
}
.content:hover {
height: 110%;
}
<div class="box">
<div class="content">TEST</div>
</div>
You can do this using transform:scaleY() and set the transform-origin to bottom. I also put a margin-top:100px to see the effect better. Also you can use transition to make the scale smoother
You also need to scale back the text.
See here: jsfiddle
You need to scale the text back to it's original state in the same time that you scale the div. so if you scale the div 2 times. You need to scale back the text with 1/2 , same if you scale 3 times...scale back with 1/3
In this case you enlarge .content by 1.5 so you need to scale down the text inside by 1/1.5 = 0.66
Code:
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
margin-top: 300px;
transition:0.3s;
}
.content:hover p {
transform: scaleY(0.66)
}
.content:hover {
transform: scaleY(1.5);
transform-origin: bottom;
}
<div class="box">
<div class="content">
<p>
TEST
</p>
</div>
</div>
Try it like this (I have no other idea...): You can give to the class "box" a bigger height (I put a red border around, so you can see it) than the class "content". After that, you can use flexbox, to put the class "content" on the bottom. After that, you can do it with hover to change your heigth upwards and fill it. With transition you can make a nice animation. I hope this is good enough. Perhaps there is also a way with jQUery at the moment I havn't got an idea. Let me know, if this helps you (I'm not sure if I understanded the question well) - Cheers. (Important: This heights and so on are just random values for testing)
.box {
display: flex;
justify-content: flex-end;
flex-direction: column;
height: 100px;
border: 1px solid red;
}
.content {
background-color: #e3e4e6;
height: 50px;
width: 100%;
text-align: center;
-webkit-transition: height 1s;
/* Safari */
transition: height 1s;
}
.content:hover {
height: 100%;
}
<div class="box">
<div class="content">TEST</div>
</div>
If you just want to use css, just use:
.content:hover {
margin-top: -50px;
height: 110%;
}
See jsFiddle
since there isn't any space at top to expand, you may give an extra margin initially and remove it on hover like this JsFiddle -
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
margin-top:25px;
}
.content:hover {
height: 110%;
margin-top:0;
}
Set top property with the value of height - 100 * -1
https://jsfiddle.net/x3cL1cpt/7/
.content:hover {
height: 110%;
top: -10%;
position: relative;
}
Why position relative? It's because I move the box, but without modifying the space that the box occuped. If you need to modify that space, change top with margin-top.
Replace this CSS with your current, needed to add transition:
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
transition: 1s all ease;
}
.content:hover {
transform: scaleY(1.2);
transform-origin: bottom right;
}
I want to recreate an effect I saw on airforce.com . It's right below the hero, I poked around a bit and can't seen to find out what they did.
It looks like it was developed using knockout but I would like to recreate it using jQuery and Css.
If you know what the effect is called or know of a library that can achieve this, PLEASE let me know thanks!
https://www.airforce.com/
I created a simple mockup of the effect using css only. View fiddle
https://jsfiddle.net/rob_primacy/p6ee9d71/2/
<div class="image-block">
<div class="image"></div>
</div>
.image-block {
position: relative;
width: 300px;
left: 200px;
}
.image {
display: block;
position: absolute;
left: 0;
right: 0;
overflow: hidden;
transition: all ease .3s;
height: 600px;
background: url("http://www.difrusciaphotography.com/wp-content/uploads /2015/08/Place-to-unwind_Lake-Kananaskis-Alberta-Canada.jpg") #000 no-repeat center center;}
.image-block:hover .image {
left: -40px;
right: -40px;
transition: all ease .3s;
}
Relative newbie here. I have two different mouseover/hover functions I can get to work just fine: one, an inline mouseover that 'darkens' an image/box by making it lose opacity; and the second, text that appears over this image/box on hover (jumping up from a hidden position).
The problem is, I want to get them working together without this text losing opacity, which it does when part of the same div class as the image/box. But when I try two separate div classes and position them on top of each other (using z-index), whichever one I put on top seems to block the other one. Is there any way to have it so the image/box loses opacity, but the text that appears doesn't, all in the same mouseover/hover action?
These are the relevant bits in my stylesheet, mostly covering the text part:
.rightbox {
background: rgb(140, 183, 98);
width: 290px;
height: 160px;
margin-bottom: 18px;
padding: 2px;}
.rightboxtext {
display: table-cell;
height: 160px;
width: 290px;
vertical-align: bottom;
text-align: center;
font-weight: bold;
font-size: 20px;
color: #8CB762;
}
.rightboxtext span {
display: block;
height: 0px;
overflow: hidden;
}
.rightboxtext:hover span {
height: 80px;
}
This is the inline stuff that I used where everything, including text, gets the opacity treatment. (In this case the image is attached to the rightboxtext div class, but I also tried it attached to the rightbox div class.)
<div class="rightbox"
onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"
onmouseover="this.style.opacity=0.6;this.filters.alpha.opacity=60">
<div class="rightboxtext"
style="background-image: url(image.jpg); height: 160px; width: 290px;">
<span>Hello text.</span></div>
</div>
Otherwise I achieved this mangled bit of code, where one seems to block the other:
<div class="rightboxcontainer">
<div class="rightboxtext"
style="position: absolute; z-index: 100; height: 160px; width: 290px;">
<span>Hello text.</span></div>
<div class="rightbox"
style="position: absolute; z-index: 50; height: 160px; width: 290px;"
onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"
onmouseover="this.style.opacity=0.6;this.filters.alpha.opacity=60"><img
src="image.jpg">
</div>
</div>
With this extra bit in the stylesheet:
.rightboxcontainer { width: 290px; height: 160px; margin-bottom: 18px;}
Thanks in advance!
As a commenter pointed out above, you can do this entirely with CSS:
<style>
* {
padding: 0;
margin: 0;
}
.box {
width: 250px;
height: 250px;
overflow: hidden;
}
.box img {
width: 250px;
height: 250px;
}
.box .message {
background: rgba(0, 0, 0, 0.5);
opacity: 0;
width: 250px;
height: 250px;
position: relative;
top: -256px;
color: #fff;
font-size: 32px;
line-height: 250px;
text-align: center;
font-weight: bold;
font-family: arial;
}
.box .message:hover {
opacity: 1;
}
</style>
<div class="box">
<img src="http://www2.le.ac.uk/departments/geology/people/clark-n/personal/copy_of_images/Satellite-map-of-Antarctica/image">
<div class="message">Antarctica</div>
</div>
.message is positioned on top of the container, .box. When you hover over .message, it fades in from 0 opacity. Its background is semi-opaque (using RGBA, where the fourth value is the opacity), so it dims the image. You could make the image the background-image of the .box if you wanted to.
http://jsfiddle.net/dgGG3/4/
Fist of all, try to avoid inline event handling as you can achieve the desired result with css :hover.
The problem as you can see here http://jsfiddle.net/UjY5Q/ is with opacity on a parent element all child elements also get that opacity.
.rightbox:hover {
opacity:0.5;
}
You can cheat on that one by setting positions to the elements and overlap one to the other one. That's kind a tricky and may also need browser support.
so the easyest way to get what you want is on :hover show a transparent background image example here: http://jsfiddle.net/UjY5Q/1/
I would say that's the way to go