Transition using radio-buttons - css

I found this tutorial, which introduces a transition that I need for my for my page to slide it down with a single click using radio buttons.
The idea is, that my page's width and height are 100% and each click moves the page "off the canvas" using translateY (found at tyyli.css line 663) just like in the tutorial provided.
After all efforts I can't get it work if I put the first radio button inside st-scroll div. I have to put it directly under site-wrapper to get it work but now is looks horrible, because it wont move along with the page and just hides under st-scroll. Also the dot putted outside st-scroll DIV causes the whole page to be 100px lower than it thould be.
This is the top radio button.
<input type="radio" name="radio-set" id="st-control-1"/>
Try to move this code from the first <secton> to just under site-wrapper like this
<div class="menu">
</div>
/*TRY TO PUT IT JUST BELOW THIS LINE AND SEE THE PROBLEM*/
<input type="radio" name="radio-set" id="st-control-1"/>
<div class="st-scroll">
and you will see the problem. My idea is, that this has something to do with the Z-index, but i might be wrong. I want to place both buttons inside st-scroll.
My site is www.kasperikoski.fi

You can use labels to control radio buttons, so you can put the labels wherever you want and have more control over styling them, as well as hide the radios. However, the radios must be siblings of the element you want to control or one of its ancestors if you want to use the ~ or + combinators.
DEMO
.st-scroll {
padding: 1em;
background-color: tomato;
transition: transform 500ms ease;
}
input[name="radio-set"] {
display: none;
}
label {
display: block;
margin-bottom: 0.5em;
padding: 1em;
background-color: lightgray;
border: solid 1px gray;
border-radius: 0.5em;
}
input[type="radio"] + label {
display: inline-block;
}
#st-control-1 ~ .st-scroll {
transform: translateY(100%);
}
#st-control-1:checked ~ .st-scroll {
transform: translateY(0);
}
<input type="radio" id="st-control-1" name="radio-set" checked="checked" />
<div class="st-scroll">
<label for="st-control-1">I'm a label in .st-scroll but am linked to #st-control-1 so I can control my parent</label>
<input type="radio" id="st-control-2" name="radio-set" />
<label for="st-control-2">I'm a label linked to the other radio</label>
</div>

The reason that the links only work outside the div is because the effect is driven by the CSS: #st-control-#:checked ~ .st-scroll which means it looks for a sibling DOM element with .st-scroll class. You need to either have it on the outside of the scroll element or rely on javascript to trigger the same transforms by adding/removing certain classes.
I could see it being done various ways, although the fastest (me being lazy and all) would be something like:
In html:
<input type="radio" name="radio-set" id="st-control-1" value="scroll-1">
... further down
<input type="radio" name="radio-set" id="st-control-2" value="scroll-2">
In a script including jquery to save time...:
$(document).ready(function(){
var scroll = $('.st-scroll');
$('input[name="radio-set"]').click(function() {
var which = $(this).attr('value');
var prev = scroll.data('current');
if(prev) scroll.removeClass(prev);
scroll.addClass(which)
.data('current',which);
});
});
And finally the css:
.scroll-1 {
transform: translateY(-100%);
}
.scroll-2 {
transform: translateY(0);
}

Related

CSS change label background of another element, when radio button is checked

I want to change the background color of the label class 'label-status', depending on if the radio button is set to agree or disagree.
<div class="testclass">
<label class="label-status">Status</label>
<label class="radio-inline" style="display:inline-block;"><input type="radio" name="status" disabled="">Agree</label>
<label class="radio-inline" style="display:inline-block;"><input type="radio" name="status" checked="" disabled="">Disagree</label>
</div>
Since it's not my website, but some custom user CSS I want to inject to make it more usable, I cannot make any changes to the actual html.
Thanks for your answers in advance.
You can take advantage of the order property (Flexbox or Grid) together with the for attribute to link the label with the related input element:
.testclass {display: flex} /* displays flex-items (children) inline; can also use the "inline-flex" which only takes the content's width */
.label-status {order: -1} /* puts it back to the desired place (above other siblings); the initial value is set to 0 */
.testclass > input:first-of-type:checked ~ .label-status {background: green}
.testclass > input:last-of-type:checked ~ .label-status {background: red}
<div class="testclass">
<input type="radio" name="status" id="agree">
<label for="agree">Agree</label>
<input type="radio" name="status" id="disagree" checked>
<label for="disagree">Disagree</label>
<label class="label-status">Status</label> <!-- needs to be placed below other siblings in order to take advantage of the "~" selector -->
</div>
Then you can use the general sibling combinator ~ to target the .label-status with e.g. :first-of-type & :last-of-type selectors set on the input elements, of course in conjunction with the :checked pseudo-class selector.
You could use JS, like so:
$(document).ready(function() {
$(".label-status").on("click",function() {
if($(this).find('input[type="radio"]').is(':checked')) {
$('.radio-inline').removeClass('sel_bk_color');
$(this).addClass('sel_bk_color');
}
});
});
Here is an example of this kind of thing in action: https://jsfiddle.net/tr9Lyxz3/1/
By default your inputs are disabled. you have to first remove disable property and then add onclick attributes to run a function which will change background color.
document.getElementsByName('status')[0].removeAttribute("disabled")
document.getElementsByName('status')[1].removeAttribute("disabled")
document.getElementsByClassName('radio-inline')[0].setAttribute("onclick","myFunction()")
document.getElementsByClassName('radio-inline')[1].setAttribute("onclick","myFunction()")
function myFunction(){
if (document.getElementsByName('status')[1].checked) {
document.getElementsByClassName("label-status")[0].classList.remove("myclass2")
document.getElementsByClassName("label-status")[0].classList.add("myclass1");
}
else if (document.getElementsByName('status')[0].checked) {
document.getElementsByClassName("label-status")[0].classList.remove("myclass1")
document.getElementsByClassName("label-status")[0].classList.add("myclass2");
}
}
you have to define your css for myclass1 and myclass2 as per your background color requirement.
this is not possible using pure css as you cant read values dynamically using css. so if you can use js then this will solve your problem without editing html.
Some pure CSS solutions seem to miss the you are not allowed to change the HTML.
Are you allowed to use javascript?
Here is some javascript without JQuery:
var updateLabel = function(e) {
var label = document.getElementsByClassName("label-status")[0];
if (e.target !== e.currentTarget && event.target.type === "radio") {
if(e.target.labels[0].innerText === "Agree") {
label.style.background = "green"
} else {
label.style.background = "red";
}
}
e.stopPropagation();
}
var wrapperElement = document.getElementsByClassName("testclass")[0];
wrapperElement.addEventListener("click", updateLabel, false);
https://codepen.io/anon/pen/MXWJXK
You do have to remove the disabled attribute from your radio buttons. With javascript you can use element.removeAttribute("disabled").
https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute
.buttons {
display: flex
align-item: center;
}
.condition {
padding-right: 50px;
}
.status {
order: -1;
padding: 5px;
border: 2px solid #000;
color: #fff;
}
.buttons > input:first-of-type:checked ~ .status {
background: green;
}
.buttons > input:last-of-type:checked ~ .status {
background: red;
}
<div class="buttons">
<input type="radio" name="status" id="agree">
<label for="agree" class="condition">Agree</label>
<input type="radio" name="status" id="disagree" checked>
<label for="disagree" class="condition">Disagree</label>
<label class="status">Status</label>
</div>

CSS highlight label BEFORE an invalid input

Ciao, I have this element here:
<div class="uk-form-row">
<div class="md-input-wrapper md-input-filled md-input-focus">
<label>Label</label>
<input type="text" class="md-input">
<span class="md-input-bar"></span>
</div>
</div>
This is from a material design theme (Altair Admin v2) so the element once the page is loaded does this:
As you can see the label is moving around (but maybe is not a big deal).
With other elements, if they are empty (invalid) I can underline them or change their color using css:
input:invalid::-webkit-input-placeholder{
color: #e53935 !important;
}
But being this a label BEFORE the input I don't know how I can select it with CSS. How do I turn the LABEL into a different color if the input is invalid?
There is a simpler way to get this done. The :valid and :invalid pseudo-classes will automatically bubble up to a parent <fieldset>. Here is the reference.
You can take advantage of this fact to style your label like so:
<fieldset>
<label>Label</label>
<input type="text" />
</fieldset>
Then in your CSS
fieldset:invalid > label:first-of-type {
color: #e53935 !important;
}
So if your input is :invalid it will invalidate your fieldset, which you can then reference to style your label.
Look at CSS code (simplified to illustrate my point):
.md-input-wrapper {
position: relative;
}
.md-input-wrapper > label {
position: absolute;
top: 16px;
left: 4px;
right: 0;
}
Label is positioned absolutely relative to wrapper, so you can put label element after input element in HTML:
<div class="md-input-wrapper">
<input type="text" class="md-input">
<span class="md-input-bar"></span>
<label>Label</label>
</div>
After that, you can use General sibling combinator to select label of invalid input:
input:invalid ~ label {
color: red;
}

CSS/SASS previous child selection

I'm trying to make a span background change colors when I focus on an input field. The HTML is as follows:
<div class='parentDiv'>
<span class='spanClass'>Some text</span>
<input class='inputClass' type='text' />
</div>
The closest I could come to something that does this is using the + adjacent sibling selector and doing something like this:
input:focus + span {
background-color: red;
}
But it doesn't quite work because span must come after input. Is there some way for me to make the span background change colors when I focus the input field?
Normally, you would need JS to do that. Here's an example using JS that keeps styling in your CSS:
(function() {
var spanEl = document.querySelector('.parentDiv > .spanClass');
var inputEl = document.querySelector('.parentDiv > .inputClass');
// Add "highlighted" class to "spanClass" element on focus event
inputEl.addEventListener('focus', function() {
spanEl.classList.add('highlighted');
});
// Remove "highlighted" class from "spanClass" element on blur event (un-focus)
inputEl.addEventListener('blur', function() {
spanEl.classList.remove('highlighted');
});
})();
.spanClass.highlighted {
background-color: red;
}
<div class="parentDiv">
<span class="spanClass">Some text</span>
<input class="inputClass" type="text" />
</div>
In your example, though, you could simply float the one element to the left and change the order in the HTML.
.parentDiv { overflow: hidden; }
.spanClass { float: left; }
.inputClass:focus + .spanClass {
background-color: red;
}
<div class="parentDiv">
<input class="inputClass" type="text" />
<span class="spanClass">Some text</span>
</div>
Something to note for the future, though:
The :has() "relational pseudo-class" seems to be in the works for "CSS4". You can also track it here: http://caniuse.com/#feat=css-has
This means that you will (hopefully) be able to do this eventually:
.spanClass:has(+ .inputClass) {
background-color: red;
}

Input button using css after element

I've created a sliding button with css using the :after element.
The problem I'm having is that my "input" buttons don't seem to use the :after element and they don't slide like my normal buttons.
<input type="submit" value="<?php echo $button_login; ?>" class="btn btn-primary" />
Is there any way that I can use the :after element on this or is there any possible workaround?
edit: To add a little more info here is the css for the button.
.btn-cart {
color: #3498db;
}
.btn-cart:hover,
.btn-cart:focus,
.btn-cart:active {
background: none;
border-color: transparent;
}
.btn-cart:hover:after,
.btn-cart:focus:after,
.btn-cart:active:after {
width: 100%;
}
.btn-cart:after {
background: #3498db;
}
input.btn-cart:hover,
button.btn-cart:hover,
input.btn-cart:focus,
button.btn-cart:focus,
input.btn-cart:active,
button.btn-cart:active {
background: #3498db;
}
I have tried the ::after but that doesn't work :(
The button does not slide on any browser because the :after element isn't working on any input buttons.
Any help will be much appreciated :)
Thanks,
Richard
I found a solution myself. This works for my input buttons, I changed "input" to "button" in my original code and added the word "login". See working code below,
<p><button type="submit" value="<?php echo $button_login; ?>" class="btn btn-primary">Login</button></p>

Blur effect on the entire webpage

I want that the unregistered users on my website, see the entire website's pages with a blur effect.
How can I create this blur effect with css ?
Try this...
body {
filter:blur(3px);
}
You'll need to add -moz-, -webkit- prefixes (or use something like PrefixFree)
Here's some results, if by blur you mean fuzziness:
This guy uses image shifting and opacity techniques in combo, I know your users are looking at a blurred website, but if there's no easy solution then perhaps taking a snapshot of your rego page and overlaying the image then it might do:
http://web.archive.org/web/20120211000759/http://simurai.com/post/716453142/css3-image-blur
If you wanted to attempt duplicating your rego page, given that it may be a) disabled and b) minimal, then perhaps you could even have a bash at using the above image technique and applying it to node sets, offsetting the copies with CSS positioning and opacity - idk if zoom might help you too there. Even if your page was minimal enough, this would obviously require Javascript to duplicate the nodes, unless your backend can do this node duplication. Just an idea, really. Here's a really awful, very quick example:
http://jsfiddle.net/9qnsz/2/
This SO posts outlines some of the limitations and difficulties with gaussian blur when not done with image, and has some interesting links:
Gaussian Blur onHover Using jQuery
EDIT: As requested, the contents of the jsfiddle:
<div class="container">
<div class="overlay">
<p>Please register etc etc...</p>
</div>
<form action="javascript:;" class="form0">
<input type="text" value="Username" />
<input type="text" value="Password" />
<button>Submit</button>
</form>
<form action="javascript:;" class="form1">
<input type="text" value="Username" />
<input type="text" value="Password" />
<button>Submit</button>
</form>
<form action="javascript:;" class="form2">
<input type="text" value="Username" />
<input type="text" value="Password" />
<button>Submit</button>
</form>
<form action="javascript:;" class="form3">
<input type="text" value="Username" />
<input type="text" value="Password" />
<button>Submit</button>
</form>
<form action="javascript:;" class="form4">
<input type="text" value="Username" />
<input type="text" value="Password" />
<button>Submit</button>
</form>
</div>​
.container {
width:500px;
height:500px;
position:relative;
border:1px solid #CCC;
}
form {
position:absolute;
left:10px;
top:10px;
}
form.form0 {
left:11px;
top:11px;
opacity:0.1;
}
form.form1 {
left:8px;
top:8px;
opacity:0.1;
zoom:1.02;
}
form.form2 {
left:11px;
top:11px;
opacity:0.1;
zoom:1.01;
}
form.form3 {
left:9px;
top:9px;
opacity:0.2;
}
form.form4 {
left:11px;
top:11px;
opacity:0.1;
}
.overlay {
width:250px;
height:250px;
margin-top:50px;
margin-left:auto;
margin-right:auto;
border:1px solid #666;
}
Edit (2015): The filter css property is forming tantalisingly complete coverage. This lets you write rules like body { filter: blur(10px); }, which blurs the entire page.
From what I can tell, there's no cross-browser way of blurring an element, even in this "modern age" of html5, css3, etc...
There is a blur filter for IE (and only IE). An svg blur filter can also be applied to an html element but from what I can tell, it only works in Firefox.
If you're happy for browser-specific hacks, go ahead, but if you need the effect to work on all browsers you're outta luck.
If you just want to blur text, you can use a clever text-shadow trick:
.blurry {
color: transparent;
text-shadow: 0 0 3px black; /* set to colour you want */
}
There are also ways to blur images, either by overlaying transparent, shifted copies of the image, or by processing the data with javascript.
Perhaps you can cobble together these techniques, and it will achieve what you want.
But the broad answer, regrettably, for the moment is: there is no easy, holistic way to blur stuff in HTML.
(I thought we were living in the future, man? What gives?!)
Addendum: Hope is in sight. At the time of writing, some webkit nightly ("bleeding edge") builds are implementing some of the new css filter specification. That demo doesn't work on any webkit browser I have installed, so it's still far from mainstream yet.
You can add a fixed div set to 100% width and height to your body. That will fill the screen and you can put either a semi-transparent background on it or use CSS3 to create the effect you are looking for.
Create a new div tag with id="body_bag" and put your rest of the site edits within that div and use following css to give the blur effect.
#body_bag {
position: absolute;
width: 100%;
top: 0;
left: 0;
background: #000;
opacity: 0.5;
filter: alpha(opacity = 50); /* required for opacity to work in IE */
}

Resources