Target upper div with lower div - javascript

I want the background of upperdiv to become red when lowerdiv has the .active class:
<div id="upperdiv">Text case</div>
<div id="lowerdiv" class="active">IMAGE CAROUSEL</div>
.active is being added by JavaScript. Example image.
I tried:
#upperdiv + #lowediv .active {
background: red;
}
but it's not working.
Is this possible with CSS or jQuery?

If I understand the question correctly you are trying to select the previous sibling. There is no way to do this using CSS. However, using JavaScript you can achieve the desired result. When you add the active class to the lower div, use your script to change the background color of the upper div.
See Is there a "previous sibling" CSS selector? for more information.

First I'd like to warn that OP doesn't ask to hack impossible CSS thing like previous sibling styling. So I'd ask people to read carefully question before downvote or abuse this answer.
There are two ways to get it with CSS, but you can use these ways for specific cases only. Common requirement is that both divs should come one by one.
First way is to swap divs using position attributes. I mean that lower div should come first in your HTML:
<div id="lowerdiv" class="active">IMAGE CAROUSEL</div>
<div id="upperdiv">Text case</div>
div {
position: absolute;
width: 100%;
height: 50px;
margin: 0;
left: 0;
background: orange;
}
#upperdiv {
margin-top: 0px;
}
#lowerdiv{
margin-top: 50px;
}
#lowerdiv.active + #upperdiv {
background: red;
}
<div id="lowerdiv" class="active">IMAGE CAROUSEL</div>
<div id="upperdiv">Text case</div>
And second way is to use ::before pseudo-element to put it under upperdiv as a background:
div {
position: relative;
width: 100%;
height: 50px;
margin: 0;
left: 0;
background: transparent;
}
#lowerdiv{
background: orange;
}
#lowerdiv.active:before {
content: " ";
display: block;
position: absolute;
height: 100%;
width: 100%;
bottom: 100%;
background: red;
z-index: -1;
}
<div id="upperdiv">Text case</div>
<div id="lowerdiv" class="active">IMAGE CAROUSEL</div>
Third way really exists but this is beyond conditions of the question.

Related

Make bar/progress chart with JS and CSS [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 12 months ago.
Improve this question
If I have data like displayed on top of the image. Is it posible to make a diagran like this (picture), with pure JS, CSS and HTML? I dont know what a diagram/chart like this is called. Any help is greatly appreciated!
The most straightforward approach is to use an absolutely positioned child in a relatively positioned parent and set its width as the progress.
function setProgress(percent) {
const range = document.querySelector('.range');
const progress = range.querySelector('.progress');
progress.style.width = `${percent}%`
}
setProgress(70);
.range {
position: relative;
height: 20px;
background-color: #ed3a23;
border: 2px solid #000;
box-sizing: border-box;
overflow: hidden;
}
.progress {
position: absolute;
left: 0;
top: 0;
width: 0;
height: 100%;
background-color: #4db24c;
border-right: 3px solid #000;
}
<div class="range">
<div class="progress"></div>
</div>
You don't need JavaScript.
Pass a CSS var() from HTML to CSS and use calc() to get the percentages
Using background linear gradient
.progress {
background: green;
height: 2em;
background: linear-gradient(to right, green calc(var(--val) * 10%), red calc(var(--val) * 10%));
background-size: 100%;
}
<div class="progress" style="--val:1"></div><br>
<div class="progress" style="--val:7"></div><br>
Using CSS pseudo element ::before
.progress {
background: red;
height: 2em;
}
.progress::before {
content: "";
display: block;
height: inherit;
background: green;
width: calc(var(--val) * 10%);
}
<div class="progress" style="--val:1"></div><br>
<div class="progress" style="--val:7"></div><br>
Here's pure HTML & CSS
.bar-wrap {
display: flex
}
.col {
display: block;
text-align:center;
width: var(--size)
}
.bar {
height: 50px;
width: 100%;
border: 3px solid #000;
background: var(--background)
}
.cgreen {
color: green
}
.cred {
color: red
}
<div class="bar-wrap">
<div class="col cgreen" style="--size:70%;">
<h3 class="heading">Correct</h3>
<div class="bar" style="--background:green"></div>
<p class="label">70%</p>
</div>
<div class="col cred" style="--size:30%;">
<h3 class="heading">Wrong</h3>
<div class="bar" style="--background:red"></div>
<p class="label">30%</p>
</div>
</div>
To meet accessibility and semantic code standards, I'd recommend having a look into the HTML <meter> element (official specification with all the attributes). Or you just have a look on HTML5 doctor to get a more compact/short conclusion.
However, keep in mind that according to caniuse.com, legacy browsers like Edge 12 and others don't support this HTML tag. So if you want to support these older browsers, that are listed there as non-supporting, you would need to come up with a fallback solution.
Rough code example for a fallback solution
<div class="meter-wrapper">
<div class="meter" style="width: 70%;">
<!-- `hidden` attribute to hide the text content but keeping the element accessible for screen readers. -->
<p class="meter__text-fallback meter__text-fallback--correct"><strong>70%</strong><span hidden>of given answers are correct.</span></p>
</div>
<p class="meter__text-fallback meter__text-fallback--incorrect"><strong>30%</strong><span hidden>of given answers are incorrect.</span></p>
</div>
and style it something like this:
/* CSS */
.meter-wrapper {
background-color: pink;
height: 40px;
position: relative;
}
.meter {
display: inline-block;
background-color: MediumAquamarine;
height: 100%;
position: relative;
}
.meter__text-fallback {
position: absolute;
margin: 0;
bottom: -25px;
}
/* This class block is not utterly necessary, since the default value for `left` is already `0`. Just in case you want to have different values. */
.meter__text-fallback--correct {
left: 0;
}
.meter__text-fallback--incorrect {
right: 0;
}
See this code example in action
Link to codepen
Important notes to this code example
I would recommend to change your layout from having the percentage of correct and incorrect answers outside the meter bars to avoid a case, where you would have a slimmer bar than the width of the typography overlapping it.
Setting the values for the style="width: 70%" attributes would need to be controlled via JS.
It is also arguable to style HTML elements with inline styles, like I did in this example. On the other hand creating a 100+ different CSS classes for such a case, might be overkill. Styling via data attributes is also not fully supported. So I'll leave this decision up to you.

Could background-color have different z-index than img?

I need to one image overlap an another. But the second image have background color and I need the first image between the second and second's background-color. It is possible? Already tried to made a new "div class" instead of style="background-color". Now i am stuck with this:
.mainRunner {
position: relative;
}
.firstimage {
position: relative;
z-index: 2;
}
.secondimage {
position: relative;
z-index: 3;
top: -75px;
}
.background {
position: relative;
z-index: 1
}
<div class="firstimage" style="max-width: 1170px;"><img src="" alt="" title="" style="width: 100%;" max-width="1168" height="399" caption="false" /></div>
<div class="background" style="background-color: #f2e5df;">
<div class="secondimage">
<img src="" alt="" title="" />
</div></div>
You can't give certain properties of an element different z-index values. However for certain elements like a div you can use ::before and ::after pseudo elements. And you can set a z-index on those, effectively creating three layers. More information here.
In this case you can create a div with the middle img inside. Then add a ::before and ::after to that div. Giving one a background color and a z-index of -1. And the other a background image and a z-index of 1.
In the example below I also added some margin and a border around the inital div so you can better see what is going on.
.image {
margin: 20px 0 0 20px;
position: relative;
border: 3px solid coral;
width: 200px;
height: 300px;
}
.image::before,
.image::after {
content: '';
display: block;
width: 200px;
height: 300px;
position: absolute;
}
.image::before {
z-index: -1;
background: cornflowerblue;
top: 20px;
left: 20px;
}
.image::after {
z-index: 1;
background: url("https://www.fillmurray.com/200/300");
top: -20px;
left: -20px;
}
<div class="image"><img src="https://www.fillmurray.com/200/300" /></div>
If I understand right what you're trying to achieve, you probably should be placing the images within background div and placing the second image with position: absolute:
<style>
.mainRunner {
position: relative;
}
.firstimage {
position: relative;
z-index: 2;
}
.secondimage {
position: absolute;
z-index: 3;
top: 20px; /* use top and left values to place the image exactly where you want it over the first image */
left: 20px
}
.background {
position: relative;
z-index: 1;
background-color: #f2e5df;
}
</style>
<div class="mainRunner">
<div class="background">
<img src="image1.png" class="firstimage" />
<img src="image2.png" class="secondimage " />
</div>
</div>
It sets the background color as the back-most element, then on top of it the secondimage and the firstimage.
Thank everyone for their ideas. In the end the solution was simple. In the style was the double definition of second image. And the first of them was just partly commented. So my first post working right like this:
.secondimage img{
max-width: 100%;
height: auto;
position: relative;
top: -75px;
margin: 5px;
margin-bottom: 10px;
}
Now just need to find out how to close this question...
Thank you :)
The answer is simply no... there is no way to address a z-index to specifically a background of an element, z-index and all the other CSS properties work on the entire element, not on only its background.
You're going to have to find another way to do this, have you thought of using a div with not content, and the same size of the image, and then just setting a background color to that specific div?

Dynamic placeholder height

So I have a list with a position: fixed button in the bottom of the viewport. Because this button is position: fixed the last element of the list and part of the second last appear beneath the button, so the user can't see them properly.
What I tried so far:
adding a padding-bottom to the container with the height of the button. Issue with this approach: in different languages the height of the button is different, so it's good in only a couple of scenarios.
making the button position: sticky instead of fixed. Issue with this approach: the list is in a overflow-y: scroll container, so this approach does not work in iOS. Again, only good in a couple of scenarios.
adding a div after the list and controlling its height with javascript. Issue with this approach: does the job, but it's not very elegant.
Does anyone know of a better approach other than my third one? When I started with this I thought I might have to use JS for it, but position: sticky gave me hope that it would be possible with only CSS.
Since your list is fixed, this is an example of what I do for buttons on the bottom of my screen. Although it would be nice if you showed an example of your problem, cause it's hard to tell.
Obviously, you'll have to edit the text's positioning if you wanted, but the principle is what matters, and everything is responsive. Each individual <li> element is 10% high and 20% wide no matter the size of the screen.
CSS:
<style>
ul { position: fixed; width: 100%; height: 10%; bottom: 0%; left: 0%; background-color: deepskyblue; list-style-type: none; margin: 0; }
li { position: absolute; }
.a { width: 20%; height: 100%; background-color: red; left: 0%; }
.b { width: 20%; height: 100%; background-color: orange; left: 20%; }
.c { width: 20%; height: 100%; background-color: yellow; left: 40%; }
</style>
HTML:
<ul>
<li class="a">AAA</li>
<li class="b">BBB</li>
<li class="c">CCC</li>
</ul>

How to add button inside textarea using Javascript?

My client wants me to create a textarea inside where there has to be a button like the below picture:
Into the above pictue please follow into the right side of the picture where you can see blue color braces which is the button.
This has to be work like this 2nd picture on-click (like drop down):
Into the 2nd pictue we can see that upon clicking on the braces button the list has opened and clicking on an option from the list is writing on the Textarea. But this whole thing should work in client side i.e. using Javascript or Jquery in which I'm quite new at. So, I could not start on this. I need your wise suggestion on the above regarding how may I achieve the following meanwhile I'm also doing my research if I get to know anything then I will update my question or answer my question for other. Thanks in advance.
To achieve this you can place both the textarea and button within the same div which has position: relative set on it. You can then make the button position: absolute and put it in the top right. Something like this:
.textarea-container {
position: relative;
}
.textarea-container textarea {
width: 100%;
height: 100%;
box-sizing: border-box;
}
.textarea-container button {
position: absolute;
top: 0;
right: 0;
}
<div class="textarea-container">
<textarea name="foo">Some content here...</textarea>
<button>Menu</button>
</div>
I'll leave the styling for you to finalise as required.
Here's a version more or less as you asked, however, due to the fact that the container-div for the menu will have to be placed outside the textarea, there isn't really a way for it to dynamically fit to the textarea using only CSS - so for that you will have to use JavaScript.
* {
box-sizing: border-box;
}
#textareamenu_content ul,#textareamenu {
display: none;
}
#textarea_container {
position: relative;
display: inline-block;
}
#textarea_container label {
background: blue;
color: white;
padding: .2em;
position: absolute;
top: 0;
right: 0;
padding: .2em;
}
#textareamenu:checked ~ #textareamenu_content {
position: absolute;
top: 0;
right: 0;
overflow-y: scroll;
max-height: 15em;
min-height: 12em;
min-width: 10em;
border-left: 1.4em solid blue;
z-index: 99;
}
#textareamenu:checked ~ #textareamenu_content ul {
display: block;
}
textarea {
min-height: 15em;
min-width: 40em;
}
#textareamenu:checked ~ label {
position: absolute;
right: 8.6em;
top: 0;
width: 1.4em;
z-index: 100;
}
<div id="textarea_container">
<textarea name="text"></textarea>
<input type="checkbox" id="textareamenu">
<label for="textareamenu">{}</label>
<div id="textareamenu_content">
<ul>
<li>First_Name</li>
<li>Last_Name</li>
</ul>
</div>
</div>

Why isn't overlay working on all images?

I'm coding an image overlay w/ jQuery, and I got it working (somewhat). If you hover over the first image, it successfully appears; however, if you hover over the second one, it doesn't even work. I don't even know what the problem is! I think it has to do with unique IDs or whatever. I tried classes, and it didn't work.
Here is the fiddle :: http://jsfiddle.net/PFWcz/7/
$(document).ready(function () {
$('.overlay-link').mouseover(function () {
$(this).find('.overlay').fadeIn(200);
}).mouseleave(function () {
$(this).find('.overlay').fadeOut(200);
});
});
There are a few issues. As esqew pointed out, you're using the same IDs, which must be unique.
Addressing that, you'll still see the "same" overlay in your fiddle (http://jsfiddle.net/PFWcz/7/), but it's actually not - you're just now seeing a positioning issue.
Take a look at this fiddle:
http://jsfiddle.net/PFWcz/10/
You'll notice that when you hover over the first image, the red overlay is "1", and when you hover over the second image, the overlay is "2".
Previously (with the "helloooooo" text), the red overlays appeared the same (because of the content and positioning)...
Address the ID and position issues, and it should work.
Here's a fiddle demonstrating fixed position and ID:
http://jsfiddle.net/PFWcz/16/
The main changes is giving the container (<div>) positioning:
div {
float: left;
margin: 30px;
position: relative;
}
Also, I removed offsets (left, top) and floats, applying those to the parent container. A quick, simple fix.
You need to make your overlay-link elements your containers from which child elements inherit positions.
<a class="overlay-link">
<img src="https://d13yacurqjgara.cloudfront.net/users/67256/screenshots/1191507/shooot.png"/>
<span class="overlay"><i>hellllllllooooooo</i></span>
</a>
Your overlay-link class needs to have position: relative and will define the position and size of it and its children:
.overlay-link {
position: relative;
display: block;
width: 292px;
height: 219px;
margin: 30px;
}
Any child inside needs to have position: absolute and its width and height set to 100% of the container:
img {
position: absolute;
border-radius: 2px;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.overlay {
background-color: rgba(223, 71, 71,0.70);
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
border-radius: 2px;
display: none;
text-align:center;
}
Now when you hover over an element, it will create the overlay over that element and not the other one as you were experiencing earlier.
Jsfiddle: http://jsfiddle.net/PFWcz/14/
You're using the same id, which must be unique. Use the class attribute.
As some of the answered already said there is issue with the id's, I don't want to repeat. Since you have a multiple place where you want to show some text on rollover, using class would be a better solution/way to go ahead with.
Here is the change I did in the fiddle:
.overlay-link { /*This class is added. Since an absolute positioned element places itself relative to its parent who is either a relative positioned element or an absolute positioned element. I made the parent of the .overlay div relative.*/
position: relative;
background-color: #ff0;
}
.overlay {
position: absolute;
background-color: rgba(223, 71, 71,0.70);
left: -322px; /*Positioning the .overlay element based on its parents left*/
width: 292px;
height: 219px;
border-radius: 2px;
top: 30px;
display: none;
text-align:center;
}
.overlay i { /*There is no .shot element in the DOM. I replaced it by .overlay*/
background-color: #df4747;
border-radius: 999px;
padding: 10px;
width: 60px;
height: 60px;
color: #fff;
font-size: 30px;
top: 80px;
left: 116px;
position: absolute;
display: block;
}
This is based on my understanding. Let me know if it works.
Here, this is what you want
Fiddle: http://jsfiddle.net/D33Yk/
$(window).on('load',function () {
$('.overlay-link').mouseover(function(){
var overlay = $(this).children('.overlay');
var img = $(this).children('img');
$(overlay).css('left',$(img).offset().left);
$(overlay).css('top',$(img).offset().top);
$(overlay).css('width',$(img).width());
$(overlay).css('height',$(img).height());
$(overlay).fadeIn(200);
}).mouseleave(function(){
$(this).children('.overlay').fadeOut(200);
});
});
Because you had the overlay positioned absolutely in CSS, both overlays always covered the first image. I now set the left, top, width and height in JS, so the overlays cover their respective image.
I also changed this in CSS:
.overlay {
display: none;
position: absolute;
background-color: rgba(223, 71, 71,0.70);
border-radius: 2px;
text-align:center;
}
removed the top, left, width, height
...and this in HTML (I changed both, but I only show one since they are identical):
<div>
<a class="overlay-link">
<img src="https://d13yacurqjgara.cloudfront.net/users/67256/screenshots/1191507/shooot.png"/>
<span class="overlay"><i>hellllllllooooooo</i></span>
</a>
</div>
changed all the id's to classes, and removed id where it was not necessary

Categories