Want to replicate youtube's autoplay toggle button in pure css - html

Until recently youtube used a tag named "paper-toggle-button". My script used that but since youtube removed it I've had to settle with a normal boring checkbox.
I don't just want an answer. I want to learn how it works. It bugs me that this advanced css doesn't click for me yet.
I've been trying to replicate it via tutorials that show in various ways how to make a sliding toggle button. But I'm not satisfied with the look. I want it to look as close to the youtube's toggle button as possible. At least one thing I've learned. The code below doesn't need any pictures which is good.
This requires advanced knowledge of css which I don't have.
Here's an example and it looks ugly. Because it must for instance manually put the label in the correct place. See .labelterm. I gave up when I couldn't use this tutorial code to add a checkmark.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1">
<title>Awesome checkbox</title>
<style type="text/css">
.mylabel {
position: relative;
display: block;
width: 60px;
height: 30px;
margin-bottom: 15px;
}
.mylabel input {
display: none;
}
.slidinggroove {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #ababab;
/*background: rgba(0, 0, 0, 0.1);*/
border-radius: 20px;
transition: all 0.3s ease;
}
.slidinggroove:after {
position: absolute;
content: "";
width: 28px;
height: 28px;
border-radius: 50%;
background: #fff;
/*background: rgba(255, 255, 255, 0.2);*/
top: 1px;
left: 1px;
transition: all 0.3s ease;
}
input:checked + .slidinggroove {
background: #5fcf80;
}
input:checked + .slidinggroove:after {
transform: translateX(30px);
}
.labelterm {
margin-left: 65px;
font-size: 16px;
color: #222;
font-family: "Roboto", sans-serif;
position: relative;
top: 5px;
}
</style>
</head>
<body>
<div class="mylabel">
<input type="checkbox" id="coding">
<div class="slidinggroove"></div>
<label class="mylabel" for="coding" name="skills"><p class="labelterm">Test</p></label>
</div>
</body>
</html>

Here's how I would tackle this to achieve the look of the picture shown:
.slidinggroove::before{
position: absolute;
left: 7px;
top: 50%;
transform: translateY(-7px);
width: 20px;
height: 20px;
font-family: "Font Awesome 5 Free";
font-weight: 900;
content: "\f00c";
display: block;
color: #fff;
}
You must import a library for the icon as a font, I recommend using FontAwesome as shown in the working snippet here :
.mylabel {
position: relative;
display: block;
width: 60px;
height: 30px;
margin-bottom: 15px;
}
.mylabel input {
display: none;
}
.slidinggroove {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #ababab;
/*background: rgba(0, 0, 0, 0.1);*/
border-radius: 20px;
transition: all 0.3s ease;
}
.slidinggroove:after {
position: absolute;
content: "";
width: 28px;
height: 28px;
border-radius: 50%;
background: #fff;
/*background: rgba(255, 255, 255, 0.2);*/
top: 1px;
left: 1px;
transition: all 0.3s ease;
}
.slidinggroove:before {
position: absolute;
left: 7px;
top: 50%;
transform: translateY(-7px);
width: 20px;
height: 20px;
font-family: "Font Awesome 5 Free";
font-weight: 900;
content: "\f00c";
display: block;
color: #fff;
}
input:checked+.slidinggroove {
background: #5fcf80;
}
input:checked+.slidinggroove:after {
transform: translateX(30px);
}
.labelterm {
margin-left: 65px;
font-size: 16px;
color: #222;
font-family: "Roboto", sans-serif;
position: relative;
top: 5px;
}
<html>
<head>
<meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1">
<title>Awesome checkbox</title>
</head>
<body>
<div class="mylabel">
<input type="checkbox" id="coding">
<div class="slidinggroove"></div>
<label class="mylabel" for="coding" name="skills"><p class="labelterm">Test</p></label>
</div>
</body>
</html>
The way it works is as follow, you create a pseudo-element that will have as content the unicode of the fontawesome icon. Then you have a complete control hover it (font-size, color, ...).

Appreciate your eagerness of leaning. Let’s break the problem down and tackle each of them then merge them together to have a complete solution. Apparently, we need several things:
An oval shape background for the toggle to move. Lets call it pit
A circle that can be move to left or right. Lets call it knob.
The control need to have its own state, for checked and unchecked. We can make use of an native checkbox
The color of the control will change along the state.
Animation
We start with the basic first. To draw the toggle with html:
<div class="toggle">
<input class="toggle__input" type="checkbox"> <span class="toggle__pit"> <span class="toggle__knob"></span>
</span>
</div>
the toggle serve as the container of the whole toggle. Inside there is a a native checkbox element, toggle__pit and a toggle__knob. Without css they are just white square. Lets style it according to the sample image.
.toggle__pit {
/* set the size */
width: 36px;
height: 16px;
/* set the color */
background-color: #bababa;
border: 1px solid #bababa;
/* set the oval shape, value = height /2 */
border-radius: 8px;
/* border width is part of the element size */
box-sizing: border-box;
/* display span as a inline block element */
/* span is a inline element which cant assign width and height*/
display: inline-block;
}
.toggle__knob {
/* set the size */
width: 14px;
height: 14px;
/* make it circle */
border-radius: 50%;
background-color: white;
display: inline-block;
}
.toggle .toggle__input {
/* keep the checkbox hidden */
display: none;
}
<div class="toggle">
<input class="toggle__input" type="checkbox"> <span class="toggle__pit">
<span class="toggle__knob"></span>
</span>
</div>
Now the toggle looks like the sample image, but it is in unchecked state. We need to make it interactive so it responses to user action. Since the checkbox is hidden, user cannot interactive with it. We can use <label> to associate with the input. In this way even the input is hidden we can toggle it. We need to modify the html a bit, to have the input wrap by the label.
.toggle__pit {
/* set the size */
width: 36px;
height: 16px;
/* set the color */
background-color: #bababa;
border: 1px solid #bababa;
/* set the oval shape, value = height /2 */
border-radius: 8px;
/* border width is part of the element size */
box-sizing: border-box;
/* display span as a inline block element */
/* span is a inline element which cant assign width and height*/
display: inline-block;
}
.toggle .toggle__pit::after {
/* if the checkbox is checked, move knob to right */
content: 'L';
font-family: Helvetica, Arial, Sans-Serif;
color: white;
font-size: 12px;
display: inline-block;
transform: translateX(4px) translateY(-3px) scaleX(-1) rotate(-40deg);
transform-origin: 50% 50%;
}
.toggle__knob {
/* set the size */
width: 14px;
height: 14px;
/* make it circle */
border-radius: 50%;
background-color: white;
display: inline-block;
/* for position it to left or right */
position: absolute;
}
.toggle__label {
/* act as a reference point for knob positioning */
position: relative;
line-height: 16px;
}
.toggle .toggle__input {
/* keep the checkbox hidden */
display: none;
}
.toggle .toggle__input:checked+.toggle__pit {
/* if the checkbox is checked, change pit color */
background-color: #167ac6;
border: 1px solid #167ac6;
}
.toggle .toggle__input:checked+.toggle__pit .toggle__knob {
/* if the checkbox is checked, move knob to right */
left: 21px;
}
<div class="toggle">
<label class="toggle__label"> <input class="toggle__input" type="checkbox"> <span class="toggle__pit">
<span class="toggle__knob"></span>
</span>
</label>
</div>
Finally, to smoothen the state transition, add some transition to toogle__knob and toggle__pit.
.toggle__pit {
/* set the size */
width: 36px;
height: 16px;
/* set the color */
background-color: #bababa;
border: 1px solid #bababa;
/* set the oval shape, value = height /2 */
border-radius: 8px;
/* border width is part of the element size */
box-sizing: border-box;
/* display span as a inline block element */
/* span is a inline element which cant assign width and height*/
display: inline-block;
transition: background-color 0.5s linear, border 0.5s linear;
}
.toggle .toggle__pit::after {
/* use L to mock a tick*/
content: 'L';
font-family: Helvetica, Arial, Sans-Serif;
color: white;
font-size: 12px;
/* pseudo-element is inline by defauly, which you can't apply transform*/
display: inline-block;
/* flip L horizontally and rotate it */
transform: translateX(4px) translateY(-3px) scaleX(-1) rotate(-40deg);
transform-origin: 50% 50%;
}
.toggle__knob {
/* set the size */
width: 14px;
height: 14px;
/* make it circle */
border-radius: 50%;
background-color: white;
display: inline-block;
/* for position it to left or right */
position: absolute;
left: 1px;
/* enable animation */
transition: all 0.5s linear;
}
.toggle__label {
/* act as a reference point for knob positioning */
position: relative;
line-height: 16px;
}
.toggle .toggle__input {
/* keep the checkbox hidden */
display: none;
}
.toggle .toggle__input:checked+.toggle__pit {
/* if the checkbox is checked, change pit color */
background-color: #167ac6;
border: 1px solid #167ac6;
}
.toggle .toggle__input:checked+.toggle__pit .toggle__knob {
/* if the checkbox is checked, move knob to right */
left: 21px;
}
<div class="toggle">
<label class="toggle__label"> <input class="toggle__input" type="checkbox"> <span class="toggle__pit">
<span class="toggle__knob"></span>
</span>
</label>
</div>

Related

How to strike through input text when checkbox is ticked?

Thanks to another user's question here I was able to strike through the text when the checkbox next to it is ticked, thanks to the following HTML and CSS:
<style>
/* Customize the label (the container) */
.container {
position: relative;
padding-left: 50px;
margin-bottom: 12px;
cursor: pointer;
color: #333;
font-size: 18px;
}
/* Hide the browser's default checkbox */
.container input {
display: none
}
/* Create a custom checkbox - using ::before */
.checkmark::before {
content: "";
height: 25px;
width: 25px;
background-color: #fff;
border: solid 2px #194263;
position: absolute;
left:0;
top:0;
margin-right: 10px;
}
/* Show the checkmark when checked */
.container input:checked~.checkmark:after {
display: block;
left: 9px;
top: 5px;
width: 8px;
height: 14px;
border: solid #194263;
border-width: 0 3px 3px 0;
transform: rotate(45deg);
content: "";
position: absolute;
margin-right: 10px;
}
/* strike through the text */
.container input:checked~.checkmark {
text-decoration: line-through
}
</style>
<label class="container">
<input type="checkbox">
<span class="checkmark"></span><br>
</label>
Now, I'd like to let a user add their own text, and still strike through it when the checkbox is ticked. Adding an input field within the span tag as follows does not work.
<label class="container">
<input type="checkbox">
<span class="checkmark"><input type="text" minlength="1" maxlength="100" size="60%" placeholder="Add an item"></span><br>
</label>
Why does this not work? What to do instead?
Your code has the following issue. When you write these lines of css:
.container input:checked~.checkmark {
text-decoration: line-through
}
You're not adding the text-decoration: line-through css property to the text input element you want to strike, but to the checkmark instead. Therefore, the text input element is not receiving any strike-through styles.
What I did to solve your problem was adding the styles to the text input. I did this by doing some small changes to your HTML and CSS, this is the code:
/* Customize the label (the container) */
.container {
position: relative;
padding-left: 50px;
margin-bottom: 12px;
cursor: pointer;
color: #333;
font-size: 18px;
}
/* Hide the browser's default checkbox */
.container input[type="checkbox"] {
display: none
}
/* Create a custom checkbox - using ::before */
.checkmark::before {
content: "";
height: 25px;
width: 25px;
background-color: #fff;
border: solid 2px #194263;
position: absolute;
left:0;
top:0;
margin-right: 10px;
}
/* Show the checkmark when checked */
.container input:checked~.checkmark:after {
display: block;
left: 9px;
top: 5px;
width: 8px;
height: 14px;
border: solid #194263;
border-width: 0 3px 3px 0;
transform: rotate(45deg);
content: "";
position: absolute;
margin-right: 10px;
}
/* strike through the text */
.container input:checked ~ input {
text-decoration: line-through
}
<label class="container">
<input type="checkbox">
<input type="text" minlength="1" maxlength="100" size="60%" placeholder="Add an item">
<span class="checkmark"></span>
<br>
</label>
And this is the result:

Custom Checkbox with after element - not centreing reliably

JSFiddle, won't work in Stack Snippet for some reason:
https://jsfiddle.net/m3aoswyx/2/
I have a custom checkbox, like this:
<label for="name" class="customCheckboxLabel">
<input type="checkbox" name="name" class="customCheckboxInput" />
<span>Foo</span>
</label>
With the following SCSS:
.customCheckboxLabel {
span {
font-size: 3em;
padding-bottom: 2px; //This is ignored.
}
.customCheckboxInput {
appearance: none;
-webkit-appearance: none;
-moz-appearance:none;
width: 3em;
height: 3em;
background-color: transparent;
border: 2px solid red;
border-radius: 0.5em;
transition: all 0.5s;
&:checked {
transform: rotate(45deg);
border-color: black;
&::after {
content: "\2022";
font-size: 6em;
color: #41b883;
text-align: center;
width: 100%;
height: 100%;
position: absolute;
line-height: 0.1em; //This is random
}
}
}
}
This results in a circle appearing when the box is checked, that is not quite centred within its containing square. I have been able to approximately centre it using line-height set to random values, but this value must be changed for every checkbox height/width, and after element font size. This doesn't really work for what I need. What I really want, is for the only size definition to be the font-size of the span, and the width/height of the checkbox. The after-element should simply fill the checkbox (with a small amount of padding) and be centred
Additionally, I've been trying to add a bit of padding to the bottom of the span, but this is totally ignored. I just want the span and the checkbox to be vertically aligned.
One solution for creating a centralized circle, in this case, would be to make it different using background-color, positioning, relative dimensions, auto margin and border-radius.
&::after {
content: '';
text-align: center;
width: 50%;
height: 50%;
position: absolute;
margin: auto;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: #41b883;
border-radius: 50%;
}

How to make this image lightbox work for both horizontal and vertical images?

I need to create an image lightbox. I basically started from this example from w3school, https://www.w3schools.com/howto/howto_js_lightbox.asp
However, it doesn't work for portrait oriented images. Eg. a landscape image is 1200x800 and a portrait can be 800x1200.
I need the images to resize responsive and work for both horizontal and vertical images.
It needs to work for all modern browsers, ios, android and also IE11.
you'll see I've added "max-width: 1200px;" to lightbox-content, which does the trick for horizontal images... but since a vertical image is 800 wide, it enlarges and the height exceeds.
<div class="lightbox">
<span class="close" onclick="closeLightbox()">×</span>
<div class="lightboxTitle">My Title</div>
<div class="lightbox-content">
<div class="slide"><img src="img1.jpg"></div>
<div class="slide"><img src="img2.jpg"></div>
<div class="slide"><img src="img2.jpg"></div>
<!-- Next/previous controls -->
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
</div>
/* The Modal (background) */
.lightbox {
display: none;
position: fixed;
z-index: 99999999;
padding-top: 60px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
}
/* Modal Content */
.lightbox-content {
position: relative;
margin: auto;
padding: 0;
width: 100%;
max-width: 1200px;
}
.lightboxTitle {
position: absolute;
top: 20px;
left: 25px;
font-size: 20px;
}
/* The Close Button */
.close {
color: white;
position: absolute;
top: 10px;
right: 25px;
font-size: 35px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #FF8511;
text-decoration: none;
cursor: pointer;
}
/* Hide the slides by default */
.slide {
display: none;
}
.slide img {
width: 100%;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -50px;
color: white;
font-weight: bold;
font-size: 20px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
.prev {
left: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
color: #FF8511;
}
I had the same issue in one of my past projects. I solved it with this js library https://imagesloaded.desandro.com/,
It allows you to process the images after they are loaded, and you can then assign a css class to it according to the aspect ratio.
$('#container').imagesLoaded( function() {
// images have loaded
// check image height/width > 1, portrait
// check image heidht/width <= 1, square or landscape
// assign different classes for each case to handle
});
css:
.img-container {
//do whatever you need on the container
}
// keep the image classes like this
.img-container img.portrait {
height: 100%;
width: auto;
}
.img-container img.landscape {
width: 100%;
height: auto;
}

How can i adjust the click-area around my checkbox?

im currently stuck with this formating issue in my angular application.
As you can see in the attached images, there is a problem with the clickable area around my checkboxes.
I basically want to adjust the clickable area to the size of the checkbox.
In the 2nd image I highlighted the current area with a background-color: aquamarine to make it more clear.
My SCSS code looks like this. I have a feeling, that this should be an easy task, but I'm somewhat missing something in detail.
.date-checkbox {
display: inline;
float: right;
margin-right: -24px;
margin-top: -23px;
-webkit-transform: scale(2);
}
.disable-date {
opacity: 0.5;
pointer-events: none;
}
.enum-checkbox {
display: inline;
float: right;
margin-right: -24px;
margin-top: -23px;
-webkit-transform: scale(2);
}
/* The container */
.container {
cursor: pointer;
}
/* Hide the browser's default checkbox */
.container input {
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}
/* Create a custom checkbox */
.checkmark {
position: absolute;
top: 4px;
left: 25px;
height: 15px;
width: 15px;
background-color: blue;
}
/* On mouse-over, add a grey background color */
.container:hover input ~ .checkmark {
background-color: blue;
}
/* When the checkbox is checked, add a blue background */
.container input:checked ~ .checkmark {
background-color: blue;
}
/* Create the checkmark/indicator (hidden when not checked) */
.checkmark:after {
content: "";
position: absolute;
display: none;
}
/* Show the checkmark when checked */
.container input:checked ~ .checkmark:after {
display: block;
}
/* Style the checkmark/indicator */
.container .checkmark:after {
left: 5px;
top: 2px;
width: 5px;
height: 10px;
border: solid white;
border-width: 0 3px 3px 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
My HTML code looks like this:
<div class="enum-checkbox">
<label class="container">
<input type="checkbox" (click)="IncludeExcludeProp(groupobject[g.PROPS.title], $event)"
title="Include in search" />
<span class="checkmark"></span>
</label>
</div>
Since clicking the label essentially clicks the checkbox, I would add padding or width to the label surrounding the checkbox so that it extends as far as you need your clickable area to be.
Note that, for accessibility, I've added aria-label to the checkbox. The title attribute is ignored by screen readers and the label would otherwise contain no helpful information about the checkbox.
.lbl-checkbox {
display: inline-block;
padding: 5em;
background: #eee;
}
<label class="lbl-checkbox">
<input aria-label="an appropriate label" type="checkbox">
</label>

How to show tool tip at left of text or text field

I want a tool tip in my application on mouse hover. I tried alot bt not getting any result I'm missing something in my css
Html.,
<div style="text-align: center;">
<p>
left tooltip
</p>
</div>
Someone tell the solution
Css:
body {
margin: 20px;
}
a[data-tooltip] {
position: relative;
}
a[data-tooltip]::before,
a[data-tooltip]::after {
position: absolute;
display: none;
opacity: 0.85;
}
a[data-tooltip]::before {
/*
* using data-tooltip instead of title so we
* don't have the real tooltip overlapping
*/
content: attr(data-tooltip);
background: #000;
color: #fff;
font-size: 13px;
padding: 5px;
border-radius: 5px;
/* we don't want the text to wrap */
white-space: nowrap;
text-decoration: none;
}
a[data-tooltip][data-placement="left"]::before {
top: -25%;
right: 100%;
margin-right: 10px;
}
I want a tool tip in my application on mouse hover. I tried a lot bt not getting any result
You are missing 2 elements in your CSS (see comments in the following CSS code) :
DEMO
CSS :
a[data-tooltip]:hover::before { /* <- added :hover so it displays only on hover state */
content: attr(data-tooltip);
background: #000;
color: #fff;
font-size: 13px;
padding: 5px;
border-radius: 5px;
white-space: nowrap;
text-decoration: none;
display:block; /* <-- this line */
}
Add this in your css
a[data-tooltip]:hover::before, a[data-tooltip]:hover::after {
position: absolute;
display:inline;
opacity: 0.85;
}
See working demo here : http://jsfiddle.net/Hw3k2/