Fade switch between divs with radio button - html

I got two DIVs that I switch visibility with, via two radio buttons.
I cant figure out how to use css transition to fade the content in and out when switching DIV. For example, have the div fade out to the left, while the other fades in from the right.
Second issue is, I tried to set the div to position:absolute, but the content below the two divs would then be hidden, i need the content below my two DIVS that I hide/show, to always be below. So i guess position absolute is a no go.
.div_one,
.div_two{
display:none !important;
}
#radio_one:checked ~ .div_one,
#radio_two:checked ~ .div_two{
display:block !important;
}
.div_one{
background-color:grey;
}
.div_two{
background-color:orange;
}
#below{
background-color:pink;
}
<input type="radio" name="tabs" id="radio_one" checked="checked"/>
<label for="radio_one" >01</label>
<input type="radio" name="tabs" id="radio_two" />
<label for="radio_two" class="">02</label>
<div class="div_one">
div one
</div>
<div class="div_two">
div two<br/><br/>
</div>
<div id="below">i need to be below the above block, regardless of their height.</div>
thanks in advance!

What you usually do in case you want to have an animation when one div slides to the side and another one slides in, is put them both in a parent div (usually referred to as the track) which is twice the width of its parent, and then use transform: translateX() to shift its location. It's also important to give the track overflow: hidden;. Now you don't need to give the slides an absolute position.
Regarding the track height, I added a JS snippet that would change the height according to the item displayed.
Example:
const track = document.getElementById('track');
const slides = document.querySelectorAll('#track > .slide');
const buttons = document.querySelectorAll('.radio_button');
buttons.forEach((button, idx) => {
button.addEventListener('click', () => {
let height = slides[idx].offsetHeight;
track.style.height = height + 'px';
});
});
* {
overflow: hidden;
}
#track {
width: 200%;
transition: all 0.3s ease;
overflow: hidden;
height: 1em;
}
.slide {
width: 50%;
display: inline-block;
float: left;
}
#radio_one:checked~#track {
transform: translateX(0%);
}
#radio_two:checked~#track {
transform: translateX(-50%);
}
#div_one {
background-color: grey;
}
#div_two {
background-color: orange;
}
#below {
background-color: pink;
}
<input type="radio" name="tabs" class="radio_button" id="radio_one" checked="checked" />
<label for="radio_one">01</label>
<input type="radio" name="tabs" class="radio_button" id="radio_two" />
<label for="radio_two" class="">02</label>
<div id="track">
<div class="slide" id="div_one">
div one
</div>
<div class="slide" id="div_two">
div two
<br/>
<br/>
</div>
</div>
<div id="below">i need to be below the above block, regardless of their height.</div>

Related

How do I highlight proper border boxes applying focus on stacked input fields?

I have an application with "stacked" input fields like so:
As you can see from the image, when a field is receiving focus, I only want the borders of that particular input element to be highlighted. I also want to avoid a particularly thick border by having both a top and bottom border that corresponds to the same middle lines.
Here is a Fiddle: https://jsfiddle.net/3nL426uy/
Creating the stacked input fields and applying borders is not a problem. I simply remove the bottom border on all the input fields and on the last field, I apply a bottom border.
The issue comes in when I want to apply the focus styles. As it stands currently, simply applying a different border color (used red in the example to clearly show the contrast) results in a red bottom border and a gray top border of the input field below it. Now, I may be able to use an Id selector on that particular field and apply a full border, however, how do I remove the top border of the input field below it?
const inputWrappers = document.querySelectorAll(".input-wrapper")
const wrappers = [...inputWrappers]
wrappers.forEach(wrapper => {
wrapper.addEventListener('focusin', (event) => {
event.target.classList.add('selected');
});
wrapper.addEventListener('focusout', (event) => {
event.target.classList.remove('selected');
});
})
.wrapper {
display: flex;
flex-direction: column;
}
.item {
width: 300px;
height: 30px;
padding: 5px 15px;
border: 1px solid gray;
border-radius: 0;
border-bottom: 0;
}
/* Remove the default input focus-visible outline */
.item:focus-visible {
outline: 0;
}
.input-wrapper:last-child .item {
border-bottom: 1px solid gray;
}
.selected {
border: 1px solid red;
}
<div class="container">
<div class="input-wrapper" >
<input class="item" placeholder="Enter item..." />
</div>
<div class="input-wrapper">
<input class="item" placeholder="Enter item..." />
</div>
<div class="input-wrapper">
<input class="item" placeholder="Enter item..." />
</div>
<div class="input-wrapper">
<input class="item" placeholder="Enter item..." />
</div>
</div>
I'm not sure why you've used any JavaScript here? You can just set a new focus style in the :focus-visible CSS rule, you don't need to add and remove a class when the inputs receive and lose keyboard focus.
To collapse the margins, I'd recommend applying margin-top: -1px; to each of the siblings with borders. Then, to make sure the current one has its borders on top, you can give it a z-index above its siblings. I've also added a couple of lines here to ensure that z-index won't escape the .wrapper element by creating its own stacking context.
.wrapper {
display: flex;
flex-direction: column;
/* Create a new stacking context to contain z-index */
isolation: isolate;
transform: scale(1);
}
.item {
width: 300px;
height: 30px;
padding: 5px 15px;
border: 1px solid gray;
border-radius: 0;
}
/* Remove the default input focus-visible outline */
.item:focus-visible {
outline: 0;
border-color: red;
/* Setting a z-index on the focused element ensures its borders are on top */
position: relative;
z-index: 1;
}
.input-wrapper {
/* A negative top margin lets the borders collapse */
margin-top: -1px;
}
.container {
/* Offset the negative top margin of the items */
margin-top: 1px;
}
<div class="container">
<div class="input-wrapper">
<input class="item" placeholder="Enter item..." />
</div>
<div class="input-wrapper">
<input class="item" placeholder="Enter item..." />
</div>
<div class="input-wrapper">
<input class="item" placeholder="Enter item..." />
</div>
<div class="input-wrapper">
<input class="item" placeholder="Enter item..." />
</div>
</div>
you can add 'selected' class to the div element;
wrappers.forEach(wrapper => {
wrapper.addEventListener('focusin', (event) => {
event.target.parentNode.classList.add('selected');
});
wrapper.addEventListener('focusout', (event) => {
event.target.parentNode.classList.remove('selected');
});
})
and then use sibling selector x + y to select below div, remove the top boarder.
.selected .item{
border: 1px solid red;
}
/* remove below div top border */
.selected+.input-wrapper .item{
border-top: 0;
}
.input-wrapper:last-child.selected .item{
border-bottom: 1px solid red;
}
here is the whole example
https://jsfiddle.net/2tuzi/koqrcxaw/

How do I apply a style to a div but not the ones it contains [duplicate]

This question already has answers here:
How to blur background image of div, without blurring the remaining site or the content of the div
(2 answers)
Closed 1 year ago.
I have a form and some text inside a div that drops down from the top when you hover around it, what I want to do is make it so that when it drops, it makes everything behind it blurry and a bit darker, I've managed to do the darker part with
background-color: rgba(0,0,0,0.05)
but now I don't know how to make it blurry without making the form and text blurry as well.
(I want to make the nameInsert id div have the blurry background)
This is my html:
<div id="nameInsert" class="nameInsert">
<div id="nameList" class="nameList">
<div id="boyNameList" class="boyNameList"></div>
<div id="girlNameList" class="girlNameList"></div>
</div>
<div id="addNames" style="display: table-row;">
<!-- DIVS WITH STYLES USED TO PLACE THEM SIDE BY SIDE -->
<div class="boyForm">
<form onsubmit="addBoyName(); return false">
<label for="boyName"></label>
<input type="text" name="boyName" id="boyName" placeholder="add guy" required>
</form>
</div>
and this is my css:
.nameInsert{
background-color: black;
background-color: rgba(0, 0, 0, 0.05);
}
.nameList{
margin-left: 3vw;
margin-right: 3vw;
}
.boyNameList{
width: 100%;
display: table-cell;
font-family: 'mesloBold';
}
thanks :)
your HTML had not div close now I've done you can use blow my code I hope you wanted this style
.nameInsert {
width: 100px;
height: 100px;
background-color: black;
filter: blur(5px);
opacity: 0.5;
}
.nameList {
margin-left: 3vw;
margin-right: 3vw;
}
.boyNameList {
width: 100%;
display: table-cell;
font-family: 'mesloBold';
}
<div id="nameInsert" class="nameInsert">
<div id="nameList" class="nameList">
<div id="boyNameList" class="boyNameList"></div>
<div id="girlNameList" class="girlNameList"></div>
</div>
</div>
<div id="addNames" style="display: table-row;">
<!-- DIVS WITH STYLES USED TO PLACE THEM SIDE BY SIDE -->
<div class="boyForm">
<form onsubmit="addBoyName(); return false">
<label for="boyName"></label>
<input type="text" name="boyName" id="boyName" placeholder="add guy" required>
</form>
</div>

CSS Same Height for Tabbed Sections

Please note the following HTML for a Tabbed display (for an option page):
I would like to maintain the same height as tab1 for tab2 and tab3
<article>
<nav> <!-- content --> </nav>
<section id="tab1"> <!-- content --> </section>
<section id="tab2"><iframe src=""></iframe></section>
<section id="tab3"><iframe src=""></iframe></section>
</article>
tab1 always loads first with display: block; and both tab2 & tab3
have display: none;
tab1 has variable content, so it is not practical to set a fixed height or min-height
Setting display: flex; on article interferes with nav
Setting display: flex; also interferes with display: none;
nav can not be moved to outside article
Both tab2 & tab3 display with shorter height which results in unsightly resizing of the overall box
N.B. The HTML is used in a Firefox/Chrome Extension's Options page, and NOT a web page. Since Chrome uses Panels and Firefox uses Options page, Pixel based solutions might not work as expected. There might also be Firefox/Chrome specific solutions.
To have dynamic equal height elements without script, you could use CSS Flexbox.
Here I added a couple of input's and label's to do the actual tabbing, and an extra div as a wrapper for the section's.
By setting overflow: hidden on the article, give the div the size times amount of section's, one can simply slide it back and forth, sideways, to achieve your requirements.
Fiddle demo
Here done as a Stack snippet with a twist, animated the slide and, as commented, with 4 sections
article {
overflow: hidden;
}
article > input {
display: none;
}
article nav {
width: 100%;
background: lightgreen;
}
article nav label {
display: inline-block;
padding: 3px 10px;
}
article > div {
display: flex;
width: 400%;
transition: transform 1s; /* added to animate the slide */
}
article section {
width: 100%;
padding: 3px 10px;
box-sizing: border-box;
background: lightblue;
}
article input[id="tab1"]:checked ~ div {
transform: translateX(0);
}
article input[id="tab2"]:checked ~ div {
transform: translateX(-25%);
}
article input[id="tab3"]:checked ~ div {
transform: translateX(-50%);
}
article input[id="tab4"]:checked ~ div {
transform: translateX(-75%);
}
<article>
<!-- added inputs and labels for this demo -->
<input type="radio" name="radiotabs" id="tab1" checked>
<input type="radio" name="radiotabs" id="tab2">
<input type="radio" name="radiotabs" id="tab3">
<input type="radio" name="radiotabs" id="tab4">
<nav>
<label for="tab1">Tab 1</label>
<label for="tab2">Tab 2</label>
<label for="tab3">Tab 3</label>
<label for="tab4">Tab 4</label>
</nav>
<!-- this extra wapper is needed to solve this without script -->
<div>
<section id="stab1">
Section 1
</section>
<section id="stab2">
Section 2
<br>this has more content
<br>this has more content
<br>this has more content
</section>
<section id="stab3">
Section 3
</section>
<section id="stab4">
Section 4
</section>
</div>
</article>
You could do it easily with a bit of jquery like this:
$(document).ready(function() {
$(window).resize(function() {
$(".div1").height("auto");
$(".div2").height("auto");
$(".div3").height("auto");
var height = Math.max($(".div1").outerHeight(), $(".div2").outerHeight(), $(".div3").outerHeight());
$(".div1").height(height);
$(".div2").height(height);
$(".div3").height(height);
}).resize();
});
The variable height will be highest height of any of the 3 elements and then you apply it to all 3.
FIDDLE
I added the "resize" function to make it work if user resizes the window as the height may change while doing it.

Radio Button Animation not working when adding Div

I am trying to style a group of radio buttons and also have the animation work. You will see if I delete the <div> with class="group55" from the code, then the animation works just fine. When I add that element back in, it seems like the CSS I have is not being recognized any longer. What am I doing wrong? The ultimate goal would be to have the "group55" <div> surround the group of radio buttons and still have the animation keep working.
.toggle1:checked ~ .panel1 {
left: 0px;
}
.panel1 {
transition:all 500ms ease;
width: 300px;
height: 100px;
border: 1px solid black;
position: absolute;
left: -300px;
}
<div class="group55">
<input type="radio" class="toggle1" id="toggle1" name="group" checked/>
<input type="radio" class="toggle2" id="toggle2" name="group" />
<div class="panel1">
panels 1
</div>
(Also available at jsFiddle.)
This not work because you need to put the panel as sibling of the input, to make the sibling selector (~) work.
Fix HTML:
<div class="group55">
<input type="radio" class="toggle1" id="toggle1" name="group" checked />
<input type="radio" class="toggle2" id="toggle2" name="group" />
<div class="panel1">
panels 1
</div>
</div>
Check: https://jsfiddle.net/lmgonzalves/85f57nd8/1/
If you try to add the "group55" surround the group of radio buttons,your animation will not work.Click here to see you code again the code that you wish to do
Because the class ".toggle1:checked ~ .panel1" will only work when the ".toggle1" is checked and both ".toggle1" class and ".panel1" class must have inside the "group55" like this.....
<div class="group55">
<input type="radio" class="toggle1" id="toggle1" name="group" checked />
<input type="radio" class="toggle2" id="toggle2" name="group" />
<div class="panel1">
panels 1
</div>
</div>
Click here to see the answer with another way
Something i also did was setting the left property of your panel 1 class to 4px and it worked, because in css properties like left and right work in opposite way so when you said left -300px it's actually the left but normally it ought to go right. Check http://jsfiddle.net/85f57nd8/4/
.toggle1:checked ~ .panel1 {
left: 0px;
}
.panel1 {
transition:all 500ms ease;
width: 300px;
height: 100px;
border: 1px solid black;
position: absolute;
left: 4px;
}

Centering radio buttons (flexbox?)

I'm trying to horizontally and vertically center some radio buttons:
http://jsfiddle.net/yxxd0cht/
I was thinking of using a flexbox or something like that, but I couldn't get it to work.
The CSS:
.costs
{
font-family: Arial, sans-serif;
background-color:#FFBC02;
color:white;
padding: 5px 12px;
margin-left:5px;
font-size: 1.05em;
}
input[type=radio]
{
display:none;
}
The HTML:
<div id="green">
<fieldset id="costs">
<legend>Costs: </legend>
<input id="free" name="costs" type="radio" value="free">
<label class="costs" for="free">Free</label>
<input id="chargeable" name="costs" type="radio" value="chargeable">
<label class="costs" for="chargeable">Chargeable</label>
<input id="mixed" name="costs" type="radio" value="mixed" checked>
<label class="costs" for="mixed">Mixed</label>
</fieldset>
</div>
If you're open to using flexbox, and you're using HTML5 syntax, I assume your browser requirements would allow you to use another strategy as well. This is my favorite way of precisely centering an element of unknown dimensions inside a container of unknown dimensions.
Note that I cleaned up the markup as well--since you're not using any JavaScript that requires you to precisely identify items by their class or ID, the only ID that you really care about is that of the #green div. The remaining elements can be easily addressed by using element-level selectors, which helps you avoid over-specifying styles and makes long-term maintenance easier.
#green {
background-color: green;
height: 200px;
/* Make this the positioning parent for fieldset */
position: relative;
}
#green label {
font-family: Arial, sans-serif;
background-color: #FFBC02;
color: white;
padding: 5px 12px;
margin-left: 5px;
font-size: 1.05em;
}
#green input[type=radio] {
display: none;
}
#green input[type=radio]:checked + label {
background-color: lightgreen;
}
#green fieldset {
/* Border added for visualization */
border: 1px solid red;
/* Position absolute will position relative to first
non-static ancestor (in this case, #green) */
position: absolute;
/* Positions fieldset's top/left corner exactly in the
center of #green */
top: 50%;
left: 50%;
/* Translate's percentages are based on dimensions of
the element, not the width of the container, like
CSS % units. */
transform: translate(-50%, -50%);
}
<!-- Removed unnecessary classes & IDs throughout.
The elements are easily addressible in CSS styles using
#green as the parent. -->
<div id="green">
<fieldset>
<legend>Costs:</legend>
<input id="free" name="costs" type="radio" value="free">
<label for="free">Free</label>
<input id="chargeable" name="costs" type="radio" value="chargeable">
<label for="chargeable">Chargeable</label>
<input id="mixed" name="costs" type="radio" value="mixed" checked>
<label for="mixed">Mixed</label>
</fieldset>
</div>