How to make hovering a button changes background of a different element - javascript

Website in Question
What I want to happen is that when someone hovers one of the 3 buttons "Signature Events" "Weddings" "Le Coq d'Or" the background and content of the div above it change. The div above it is static, it's not a slider. Just a styled HTML block.
I've just started getting into JS within the last week or so, and this seems like it could be done with JS switch, but I'm not sure. I don't even know what to search to get info on this.
Thank you!

You can use a data attribute with the target class and a little bit jQuery Code.
$('button').hover(
function() {
$('header').addClass($(this).attr("data-class")).text($(this).attr("data-title"));
}, function() {
$('header').removeClass($(this).attr("data-class")).text($('header').attr("data-title"));
}
);
header{
background-image: url('http://lorempixel.com/200/600/');
background-size: cover;
height: 180px;
width: 500px;
display: flex;
justify-content: center;
align-items: center;
}
header.backgroundOne{
background-image: url('http://lorempixel.com/200/600/');
}
header.backgroundTwo{
background-image: url('http://lorempixel.com/200/600/');
}
header.backgroundThree{
background-image: url('http://lorempixel.com/200/600/');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header data-title="Header Image">
Header Image
</header>
<button data-class="backgroundOne" data-title="Title One">
Change Header 1
</button>
<button data-class="backgroundTwo" data-title="Title Two">
Change Header 2
</button>
<button data-class="backgroundThree" data-title="Title Three">
Change Header 3
</button>
So if you hover a button, the data-class attribute value from this button is added as a class to your header element. If you stop hovering, the class is removed again so that the default image is shown.

For such questions, I always feel the need to provide a css-only answer since I think nowadays far too much JavaScript (especially JQuery) is used to perform tasks which can be done with pure CSS. Mostly but not always CSS is more performant because it must not be executed and gets cached.
Please see the snippet below. It uses flexbox and the order css rule, which both have a fairly good browser support (unless you must support cripple browsers like older internet explorer versions).
.wrapper {
display: flex;
flex-flow: row wrap;
}
button {
flex: 0 0 auto;
height: 20px;
margin: 0 18px;
}
.wrapper > div {
display: none;
width: 100%;
height: 100px;
margin: 36px 0 18px 0;
order: -3; /* place the divs before the buttons */
}
#content-0 {
display: block;
background: cyan;
}
#content-1 {
background: hotpink;
}
#content-2 {
background: red;
}
#content-3 {
background: blue;
}
#btn-1:hover ~ #content-1,
#btn-2:hover ~ #content-2,
#btn-3:hover ~ #content-3 {
display: block;
}
#btn-1:hover ~ #content-0,
#btn-2:hover ~ #content-0,
#btn-3:hover ~ #content-0 {
display: none;
}
<div class="wrapper">
<button id="btn-1">Button 1</button>
<button id="btn-2">Button 2</button>
<button id="btn-3">Button 3</button>
<div id="content-0">
Sed ut perspiciatis unde omnis iste natus error sit voluptatem
</div>
<div id="content-1">
A wonderful serenity has taken possession of my entire soul, like
</div>
<div id="content-2">
One morning, when Gregor Samsa woke from troubled dreams, he
</div>
<div id="content-3">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. A
</div>
</div>
(Clearly, the divs can be filled and styled as you like)

Related

how to fix the photo that doesn't scale correctly in this react component

the photo should be positioned to the right and become smaller than the parent element, this is a react component and the photo should be placed responsively.
.image {
position: absolute;
border-radius: 1rem;
left:0px;
height: auto;
width: 100%;
}
the html of the photo container:
<div className={styles.container}>
<div className={styles.title}>{title}</div>
<div className={styles.about}>{about}</div>
<img src={image} alt={title} className={styles.image} />
</div>
.container {
width: auto;
#include flex(column, center, flex-start);
padding: 3rem 10rem;
background: #2697fe;
border-radius: 1rem;
margin: 1rem;
position: relative;}
.image {
border-radius: 1rem;
height: auto;
right: 20vw;
max-width: 80%;
}
it gives this result and I need help with the position of the photo again:
the photo in the small size screen(the border is no longer rounded):
I think your HTML document structure is like this:
<div className="section1">
<div className="text">
<h1>Lorem ipsum dolor sit amet</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</p>
</div>
<img className="image" src="https://picsum.photos/200" alt="img" />
</div>
Using the Position property may not give you an appropriate layout every time in such designs.
You can make use of the CSS Flex Box to arrange the items inside the "section1" like this:
.section1 {
background: lightblue;
border-radius: 2rem;
margin: 2rem;
padding: 2rem;
display: flex;
justify-content: space-around;
}
.image {
border-radius: 1rem;
right: 20vw;
height: auto;
max-width: 80%;
object-fit: contain;
}
/* rsponsive design --- small screen size */
#media screen and (max-width: 640px) {
.section1 {
flex-direction: column;
}
.image {
border-radius: 1rem;
right: 0;
height: auto;
max-width: 100%;
object-fit: contain;
margin-top: 1rem;
}
}
This will give you a layout like this:
small screen size
large screen size
hope this answers your question :)
make sure to give the parent div that holds the image a width and height.
Then make sure that the image has a max-width: 100% and a max-height: 100% Don't work with width and height with images as that can lead to horrible responsive issue's.
Hope this helped, if theres something I can do better to bring more clarity let me know.
You need to add more flexbox structure around your HTML/JSX elements to get the image to sit to the right of the text. If you want to have the image sit inline with the text, the flex-box direction should be row (which is the default).
i.e.,
// jsx
<div className={styles.container}>
<div className={styles.innerContainer}>
<div> <-- Extra surrounding divs keeps flex children elements grouped correctly.
<div className={styles.title}>{title}</div>
<div className={styles.about}>{about}</div>
</div>
<div>
<img src={image} alt={title} className={styles.image} />
</div>
</div>
</div>
// styles
.container {
width: auto;
#include flex(column, center, flex-start);
padding: 3rem 10rem;
background: #2697fe;
border-radius: 1rem;
margin: 1rem;
position: relative;
}
.inner-container {
display: flex; <-- puts image inline. (direction "row" by default)
}
.image {
width: 100%;
}
Depending on how much you want the image to sit to the right, you may need to modify the container and inner-container styles.

How do I use jQuery toggle class to add class or remove element?

I'm not sure why my code is not responding, everything looks correct to me. I'm new to using jQuery and trying to use toggleClass to have card info displayed when the card on my page is clicked. Initially, I'd like it to be hidden but able to be toggled on and off.
$(document).ready(function() {
$('.card').click(function() {
$(this).toggleClass('inner-card.active');
});
});
.card {
display: flex;
flex-direction: column;
justify-content: end;
width: 350px;
height: 180px;
background: lightgreen;
border: 2px solid black;
margin-left: 8px;
margin-bottom: 8px;
cursor: pointer;
}
.inner-card .active {
display: none;
}
.inner-card {
display: flex;
flex-direction: column;
justify-content: end;
background: rgba(255, 165, 0, 0.5)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card">
<div class="inner-card">
<h5>Title</h5>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Sunt, libero?</p>
Link goes here
<div class="img-div">
<img src="../static/img/search.png" class="card-img" alt="">
</div>
</div>
</div>
It should go from this
To this
I believe there are several problems. First of all, I believe you want to write the display:none CSS logic this way:
.inner-card.active{
display: none;
}
This means that the inner card will be hidden if it also has the active class.
Secondly, I believe you need to rewrite the script this way:
$(document).ready( function(){
$('.card').click( function() {
$(this).find(".inner-card").toggleClass('active');
});
});
When you use the toggleClass you need to use just the name of the class, not the selector (-> no dot). Also, from the CSS, it looks like you need to find the inner card element first.
Fiddle link
You probably want something like this:
$(document).ready(function() {
$('.card').click(function() {
$(this).find(".inner-card").toggleClass('hidden');
});
});
.card {
display: flex;
flex-direction: column;
justify-content: end;
width: 350px;
height: 180px;
background: lightgreen;
border: 2px solid black;
margin-left: 8px;
margin-bottom: 8px;
cursor: pointer;
}
.hidden {
display: none !important;
}
.inner-card {
display: flex;
flex-direction: column;
justify-content: end;
background: rgba(255, 165, 0, 0.5)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card">
<div class="inner-card hidden">
<h5>Title</h5>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Sunt, libero?</p>
Link goes here
<div class="img-div">
<img src="../static/img/search.png" class="card-img" alt="magnify lens">
</div>
</div>
</div>

How can I open the A TAB at 768px?

I apologize first, my English is not very good, but I will try to describe my problem.
I'm implementing an RWD effect, and this is it!
When the screen is below 768px, I want to wrap an A tag around the demo block to make the whole block clickable, but when the screen resolution is above 768px, I want to add an A tag to cover the demo block.
I have tried using display:none in the initial a tag;
.demo{
background-color: #ccc;
padding:20px;
}
a{
text-decoration:none;
color:#222;
}
.link{
display: none;
}
#media(max-width:768px){
.link{
display: block;
}
}
<a class="link" href="#">
<div class="demo">
<h1><object>我是標題</object></h1>
<p>
<object>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ab voluptatum v</object>
</p>
</div>
</a>
However, this will cause the whole picture to disappear at the beginning, which is not the effect I want. I would like to ask you how to write this better?
.demo{
background-color: #ccc;
padding:20px;
}
a{
text-decoration:none;
color:#222;
}
.link{
display: none;
}
#media(max-width:768px){
.link{
display: block;
}
}
<a class="link" href="#">
<div class="demo">
<h1><object>我是標題</object></h1>
<p>
<object>9999999999999999</object>
</p>
</div>
</a>
This is only a workaround
Do not use display: none;.
Instead write:
...
.link{
display: block;
cursor: default;
}
#media(max-width:768px){
.link{
cursor: pointer;
}
}
This will make the mouse cursor appear normal in desktop and appear clickable on mobile.
In reality you can still click, but 99+% of visitors will not realize or attempt to check.
See: https://developer.mozilla.org/de/docs/Web/CSS/cursor

Why does this focus event break html style when pressing tab?

I am encountering a bizarre behavior. I have simple blocks that contains a hidden overflow. A hoover event is triggered to display the hidden overflow. the hidden part has position absolute.
HTML:
<div class='container'>
<div class="edito">
<img src="https://via.placeholder.com/273x211" />
<div class="inner">
<p>Lorem ipsum dolores</p>
See more
</div>
</div>
<div class="edito">
<img src="https://via.placeholder.com/273x211" />
<div class="inner">
<p>Lorem ipsum dolores</p>
See more
</div>
</div>
<div class="edito">
<img src="https://via.placeholder.com/273x211" />
<div class="inner">
<p>Lorem ipsum dolores</p>
See more
</div>
</div>
</div>
CSS:
.edito {
width: 273px;
height: 211px;
position: relative;
border: 2px solid;
overflow:hidden;
}
.edito .inner {
position: absolute;
left: 0;
width: 100%;
height: 195px;
transition: top 0.8s ease;
top: calc(100% - 50px);
}
.edito:hover .inner {
background-color: purple;
top: calc(100% - 150px);
}
.container {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-around;
}
img {
position:relative;
}
Now when someone (with accessibility issue for e.g) tries to press tab to navigate between these blocks, the style is broken.
You can see this here:
jsfiddle.net/0ubqwfxc
Try to press tab to navigate to the third block; the style of first ones is broken.
Why this happens and how to fix it?
Thank you
It breaks because when the user clicks tab it selects the link and the link automatically goes up. To stop them from focusing on a link with tab simply add the attribute tabindex="-1" to your <a> tag like this See more Working example: https://codepen.io/Ajjarindahouse/pen/qBbjERM
I managed to solve this by handling selector focus-within like this:
.edito:focus-within .inner {
top: calc(100% - 195px);
transition: top 0s ease;
}
Can be tested here: http://jsfiddle.net/tzfoc0sr/

Make div expand to take all the available space [duplicate]

This question already has answers here:
Make a div fill the height of the remaining screen space
(41 answers)
Closed 5 years ago.
I want a desktop-like full-page width layout.
Some menu at the top (uknown height, depending on the content),
and div underneath that takes ALL the available space in viewport.
div {
padding: 0px
}
html,
body {
height: 100%;
padding: 0px;
margin: 0px;
}
.outer {
background: olive;
height: 100%;
}
.menu {
background: orange;
}
.should_fill_available_space {
background: brown;
}
<div class="outer">
<div class="menu">
Lorem Ipsum Lorem Ipsum Lorem Ipsum
</div>
<div id="this" class="should_fill_available_space">
Brown color should go all the way down
</div>
</div>
I've got a codepen for this case:
https://codepen.io/marek-zganiacz/pen/NvEaxr
I want should_fill_available_space go all way down, as in the case where menu would have height:10% and should_fill_available_space have 'height:90%`.
The easiest way to achieve this is using flexbox.
You assign display: flex to the parent container. in your case this is outer .outer.
a flexbox works in a single direction. So you can look at them like a column (vertical) or row(horizontal). The default setting is that it spreads the children elements out over a row. But we want to create a column. Therefore we have to change the flex-direction on .outer to flex-direction: column.
Now we need to specify how we want the flexbox to divide the amount of space available in the .outer. Normal behaviour is that the flexbox gives its children their normal width/height. But by assigning flex:1 to .should_fill_available_space, this element will get all the extra available space. What the flexbox basically says is that we want the computer to use all 1/1 = 100% (used flex value divided by the total flex value of all children) available room to apply to .should_fill_available_space, while keeping minimal space for the .menu width. Technically flex: is a shorthand for some other properties, but that doesn't really matter for this question.
Here is your JS-Fiddle: https://jsfiddle.net/cryh53L7/
html
<div class="outer">
<div class="menu">
Lorem Ipsum
Lorem Ipsum
Lorem Ipsum
</div>
<div id="this" class="should_fill_available_space">
Brown color should go all the way down
</div>
</div>
css
div{
padding: 0px
}
html, body{
height: 100%;
padding: 0px;
margin: 0px;
}
.outer {
display: flex;
flex-direction: column;
background: olive;
height: 100%;
}
.menu{
background: orange;
}
.should_fill_available_space{
flex: 1;
background: brown;
}
Try this!
I used a table display, I hope it is okay for you :)
HTML:
<div class="outer">
<div class="menu">
Lorem Ipsum
Lorem Ipsum
Lorem IpsumLorem Ipsum
Lorem Ipsum
Lorem IpsumLorem Ipsum
Lorem Ipsum
Lorem IpsumLorem Ipsum
Lorem Ipsum
Lorem IpsumLorem Ipsum
Lorem Ipsum
Lorem IpsumLorem Ipsum
Lorem Ipsum
Lorem IpsumLorem Ipsum
</div>
<div id="this" class="should_fill_available_space">
Brown color should go all the way down
</div>
CSS:
div{
padding: 0px
}
html, body{
height: 100%;
padding: 0px;
margin: 0px;
}
.outer {
background: olive;
height: 100%;
display:table;
width:100%;
}
.menu{
background: orange;
display:table-row;
}
.should_fill_available_space{
background: brown;
display:table-row;
}
div+ div{
height:100%;
}
You can achieve this with flexbox in CSS3 (https://css-tricks.com/snippets/css/a-guide-to-flexbox/).
Update your CSS like this to see it working:
.outer {
background: olive;
height: 100%;
display: flex;
flex-direction: column;
}
.should_fill_available_space{
background: brown;
flex-grow: 2;
}
This is where the world of web document standards meets viewport based desktop application emulation. You need containers to be positioned absolute. Within these containers you will be able to setup relative position elements or use elements that will use the html flow.
There are numerous APIs out there which will do just that under the covers and they will invariably rely on javascript calculations to place elements according to their dimensions after being attached to the DOM.
Here is a simple example based on your code:
div{
padding: 0px
}
html, body{
height: 100%;
padding: 0px;
margin: 0px;
}
.outer {
background: olive;
height: 100%;
width:100%
position:absolute;
}
.menu{
background: orange;
}
.should_fill_available_space{
background: brown;
position:absolute;
bottom:0px;
width:100vw;
}
<div class="outer">
<div id="menu" class="menu">
Lorem Ipsum
Lorem Ipsum
Lorem Ipsum
</div>
<div id="this" class="should_fill_available_space">
Brown color should go all the way down
</div>
</div>
As I mentioned, you can use javascript to retrieve the dimension of the menu and than apply that to your layout.
window.addEventListener("load", function load(event){
var menu = document.getElementById("menu");
var main = document.getElementById("this");
var menuHeight = menu.offsetHeight;
main.style.top = menuHeight + "px";
},false);
And here is the codepen.

Categories

Resources