how to make a outlined input with floating label with custom css? - css

I want to make an input with the floating label. Exactly like the material-ui for react.
Material UI Code :
<TextField
id="outlined-basic"
label="E-Mail"
variant="outlined"
placeholder="Enter E-Mail"
/>
Link for seeing output for the above code : Code
What I want is, the label must be inside the input field. When the user is clicking the input field, the label should float and the placeholder should be shown. If the user doesn't enter anything and if the focus changes, again the placeholder must be hidden and the label must comeback to initial position
What I have tried so far is :
.container {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.material-textfield {
position: relative;
}
label {
position: absolute;
font-size: 1rem;
left: 0;
top: 50%;
transform: translateY(-50%);
background-color: white;
color: gray;
padding: 0 0.3rem;
margin: 0 0.5rem;
transition: 0.1s ease-out;
transform-origin: left top;
pointer-events: none;
}
input {
font-size: 1rem;
outline: none;
border: 1px solid gray;
border-radius: 5px;
padding: 1rem 0.7rem;
color: gray;
transition: 0.1s ease-out;
}
input:focus {
border-color: #6200ee;
}
input:focus + label {
color: #6200ee;
top: 0;
transform: translateY(-10%) scale(0.9) !important;
}
input:not(:placeholder-shown) + label {
top: 0;
transform: translateY(-50%) scale(0.9) !important;
}
input:empty + label {
transform: translateY(75%);
font-weight: bold;
}
input:empty:not(:placeholder-shown) + label {
top: 0;
transform: translateY(-50%) scale(0.9) !important;
}
input:empty::-webkit-input-placeholder {
opacity: 0;
}
<div class="container">
<div class="material-textfield">
<input placeholder="placeholder" type="text" />
<label> label</label>
</div>
</div>

You were mostly there with your code. The most important thing to note, :empty means nothing for inputs. It will always be applied because inputs can't have children.
Though the :placeholder-shown is pretty much the main workaround to styling an empty input.
I removed most of the :empty styles and replaced some with :placeholder-shown.
The other thing I did was I set up the focus and not-empty transitions to be the same.
input:not(:focus)::placeholder {
opacity: 0;
}
This makes it so the placeholder is hidden only when it's not focused.
Here's the full results:
.container {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.material-textfield {
position: relative;
}
label {
position: absolute;
font-size: 1rem;
left: 0;
top: 50%;
transform: translateY(-50%);
background-color: white;
color: gray;
padding: 0 0.3rem;
margin: 0 0.5rem;
transition: 0.1s ease-out;
transform-origin: left top;
pointer-events: none;
}
input {
font-size: 1rem;
outline: none;
border: 1px solid gray;
border-radius: 5px;
padding: 1rem 0.7rem;
color: gray;
transition: 0.1s ease-out;
}
input:focus {
border-color: #6200ee;
}
input:focus+label {
color: #6200ee;
top: 0;
transform: translateY(-50%) scale(0.9) !important;
}
input:not(:placeholder-shown)+label {
top: 0;
transform: translateY(-50%) scale(0.9) !important;
}
input:not(:focus)::placeholder {
opacity: 0;
}
}
<div class="container">
<div class="material-textfield">
<input placeholder="placeholder" type="text" />
<label> label</label>
</div>
</div>
That all being said, there are some accessibility issues with the Material Design shrink labels. So, just make sure you are aware of potential issues.
https://www.matsuko.ca/blog/stop-using-material-design-text-fields/

Related

Getting SVG plus symbol to appear to the right of tab, not the right of the containing div

So I've got a problem where I've got two tabs (https://codepen.io/databell/pen/LYjxvyx) where the first tab opens up content and the second opens up a modal.
Now to be clear, those functions work. That's not the issue. So for those purposes, I deleted those out of my example. Focusing on CSS here.
My problem is I want plus + symbols to appear to the right side of each tab (really a div) and instead one tab has the symbol to the far right of the container, even though the tab is set to width 100%. So I'm stumped as to what the problem is.
This is meant to go into a Shopify store using the Dawn theme, so I'm using their elements here to create this interface.
Here's the code.
<div id="info-additions" class="product__accordion accordion info-additions-content" >
<details>
<summary>
<div class="summary__title info-additions-tab g-flex">
<h2 class="h4 accordion__title t-body benefits">
Tab One
<span></span>
</h2>
</div>
<div class="summary__title info-additions-tab g-flex">
<modal-opener class="product-popup-modal__opener no-js-hidden" data-modal="#PopupModal-ingr">
<button id="ProductPopup-ingr" class="summary__title t-body ingredients" type="button" aria-haspopup="dialog" data-additions-tab="ingredients">
<h2 class="h4 accordion__title">
Tab Two
<span></span>
</h2>
</button>
</modal-opener>
</div>
</summary>
<div class="accordion__content rte">
<p>Content</p>
</div>
</details>
</div>
CSS:
body {
font-size: 1.6rem;
}
*, ::before, ::after {
box-sizing: inherit;
}
.h0, .h1, .h2, .h3, .h4, .h5, h1, h2, h3, h4, h5 {
letter-spacing: .06rem;
line-height: 1.3;
}
.h4, h4 {
font-size: 1.6rem;
}
.grid {
list-style: none;
}
.g-flex {
display: flex;
display: -webkit-flex;
flex-wrap: wrap;
-webkit-flex-wrap: wrap;
}
.accordion summary {
cursor: pointer;
display: flex;
position: relative;
list-style: none;
line-height: 1;
padding: 1.5rem 0;
}
.accordion__title {
display: inline-block;
max-width: calc(100% - 6rem);
min-height: 1.6rem;
margin: 0;
word-break: break-word;
}
details > * {
box-sizing: border-box;
}
.accordion__title {
word-break: break-word;
}
.accordion .summary__title {
display: flex;
flex: 1;
}
#info-additions {
clear: both;
height: auto;
margin: 15px 0 0;
border-top: 2px solid;
border-bottom: 2px solid;
width: 100%;
}
.info-additions-content {
position: relative;
height: 0;
transition: .6s var(--a-cubic-1);
}
.info-additions-tab {
justify-content: space-between;
}
.info-additions-tab span {
display: block;
position: absolute;
width: 18px;
height: 18px;
top: 13px;
right: 2rem;
}
.info-additions-tab button {
position: relative;
padding: 16px 0!important;
line-height: 1;
font-weight: 500;
text-align: left;
}
.info-additions-tab button.benefits {
width: 50%;
}
.info-additions-tab .product-popup-modal__opener {
width: 100% !important;
}
.info-additions-tab button.ingredients {
width: 100%;
}
.info-additions-tab span {
display: block;
position: absolute;
width: 18px;
height: 18px;
top: 13px;
right: 2rem;
}
.info-additions-tab span:before,
.info-additions-tab span:after {
content: '';
display: block;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%) rotate(90deg);
transform: translate(-50%, -50%) rotate(90deg);
width: 2px;
height: 18px;
background-color: black;
transition: 0.3s;
}
.info-additions-tab button:not(.active) span:after {
-webkit-transform: translate(-50%, -50%) rotate(180deg);
transform: translate(-50%, -50%) rotate(180deg);
}
.info-additions-content {
position: relative;
height: 0;
transition: 0.6s var(--a-cubic-1);
}
.info-additions-content [data-additions-content] {
position: absolute;
width: 100%;
top: 0;
left: 0;
padding: 5px 0 20px;
opacity: 0;
pointer-events: none;
transition: 0.3s 0s;
}
.info-additions-content [data-additions-content].active {
opacity: 1;
pointer-events: auto;
transition-delay: 0.4s;
}
#info-additions button {
padding: 0;
background: transparent;
color: inherit;
cursor: pointer;
border: 0;
border-radius: 0;
outline: none;
-webkit-appearance: none;
-moz-appearance: none;
-o-appearance: none;
appearance: none;
transition: 0.2s;
}
if you want an absolute element like + to stay in the parent element you have to set the position of the parent to "relative".
you have two problems. summary__title doesn't have a position so + doesn't stay in it .
for the second tab, your modal button has a relative position that makes the + stay inside of it instead of the summary__title.
.accordion .summary__title {
...
position: relative; // add position
}
#info-additions button {
...
position: unset; // unset the position of the button
}

Floating labels - label above input field

I'm working on an existing form, where I want to introduce floating labels.
A lot of the solutions I have seen on stack overflow are great, but require the label tag, to sit directly underneath the <input> tag. For example here.
On the form I'm working on though, my label tag, sits above the <input> tag. And the input tag, sits in a seperate div. (I am not allowed to move these tags around - please don't ask, restriction of the application!).
Is there anyway, I can achieve floating CSS labels, with this structure?
.test-field {
clear: both;
margin-bottom: 20px;
position: relative;
}
.test-field__input {
font-size: 0.875em;
line-height: 1;
-moz-appearance: none;
-webkit-appearance: none;
background-color: #f5f5f5;
border: 2px solid #eee;
border-radius: 4px;
color: grey;
height: calc((40 / 14) * 1em);
line-height: 1;
outline: 0;
padding: 0 8px;
vertical-align: top;
width: 100%;
}
/* // FOCUS */
.test-field__input:focus,
.test-field__input ~ input:checked:focus {
border-color: #5d7199;
}
/* // DISABLED */
.test-field--disabled .test-field__input {
background-color: #e8e8e3;
cursor: not-allowed;
}
.test-field--disabled .test-field__flag, .test-field--disabled .test-field__label {
color: #d0d0cb;
}
/* // ERROR */
.test-field--error .test-field__input, .test-field--error .test-field__selection .atc-field__input {
border-color: #ff4436;
color: #ff4436;
}
/* // FLOATING LABEL */
.test-field--floating .test-field-input {
position: relative;
margin-bottom: 1.5rem;
}
.test-field__label {
position: absolute;
top: 0;
padding: 7px 0 0 13px;
transition: all 200ms;
opacity: 0.5;
}
.test-field__input:focus + .test-field__label,
.test-field--floating .test-field__input:valid + .test-field__label {
font-size: 75%;
transform: translate3d(0, -100%, 0);
opacity: 1;
}
<div class="test-field test-field--floating">
<label for="a" class="test-field__label">Input label</label>
<input class="test-field__input" id="b" type="text" value="" required>
</div>
This seemed to be a good way to replicate floating labels, with a similar DOM structure:
const floatField = document.querySelectorAll('.ej-form-field-input-textbox');
const floatContainer = document.querySelectorAll('.ej-form-field');
for (let i = 0; i < floatField.length; i++) {
floatField[i].addEventListener('focus', () => {
floatContainer[i].classList.add('active');
});
};
for (let i = 0; i < floatField.length; i++) {
floatField[i].addEventListener('blur', () => {
floatContainer[i].classList.remove('active');
});
};
.ej-form-field {
border: solid 1px #ccc;
padding: 0 8px;
position: relative;
}
.ej-form-field input {
border: 1px solid red;
font-size: 16px;
outline: 0;
height: 30px;
/* padding: 16px 0 10px; */
}
label {
font-size: 16px;
position: absolute;
transform-origin: top left;
transform: translate(0, 16px) scale(1);
transition: all .1s ease-in-out;
height: 40px;
}
.ej-form-field.active label {
transform: translate(0, -6px) scale(.95);
color: red;
margin-left: 10px;
background-color: #fff;
border: 1px solid green;
height: 20px;
}
<div id="floatContainer" class="ej-form-field">
<label for="floatField">First name</label>
<div>
<input id="floatField" class="ej-form-field-input-textbox" type="text">
</div>
</div>
<div id="floatContainer" class="ej-form-field">
<label for="floatField">Last name</label>
<div>
<input id="floatField" class="ej-form-field-input-textbox" type="text">
</div>
</div>

display text on toggle button

I have a simple checkbox toggle that change the background color when clicked or checked, that indicates active or not. My problem is I don't know how to put label on that button.
something like this.
I'm not sure if that possible.
I hope you understand me.
Thanks
CODEPEN
body{
background-color: #ddd;
}
.toggle {
-webkit-appearance: none;
appearance: none;
width: 65.57px;
padding: 10px;
height: 26.32px;
display: inline-block;
position: relative;
border-radius: 13px;
overflow: hidden;
line-height: 16px;
text-align: center;
font-size: 12px;
outline: none;
border: none;
cursor: pointer;
background: #E1F6FF;
transition: background-color ease 0.3s;
}
.toggle:before {
content: "text text";
display: block;
position: absolute;
z-index: 2;
width: 24px;
height: 24px;
background: #fff;
left: 0;
top: 0;
border-radius: 50%;
padding-top: 5px;
text-indent: -30px;
word-spacing: 37px;
color: #4D5585;
text-shadow: -1px -1px rgba(0,0,0,0.15);
white-space: nowrap;
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
transition: all cubic-bezier(0.3, 1.5, 0.7, 1) 0.3s;
}
.toggle:checked {
background: #dadce8;
}
.toggle:checked:before {
left: 40px;
}
.center{
text-align: center;
}
<div class="center">
<input class="toggle" type="checkbox" />
</center>
To achive desire result after edit, we are going to build something new.
HTML
<div class="switch">
<input type="checkbox" name="switch" class="switch-checkbox" id="myswitch" checked>
<label class="switch-labels" for="myswitch">
<span class="switch-text"></span>
<span class="switch-dot"></span>
</label>
</div>
We will use a main div with class switch to build our switch. This will hold 2 things
The input so we can target it state and use both for styles and what i suppose future js styles
A label that will hold 2 things
2.1 The on and off text as before and after of a span
2.2 The white dot that slides on each state
CSS is commented on the snippet
Hope this is what you were looking for. Happy to explain or help in a better solution if needed.
body {
background-color: #ddd;
}
/*Style main div and remove default checkbox*/
.switch {
position: relative;
width: 75px;
margin: 0 auto;
}
.switch-checkbox {
display: none;
}
/*Style words and oval switch */
.switch-labels {
display: block;
overflow: hidden;
cursor: pointer;
border-radius: 20px;
}
.switch-text {
display: block;
width: 200%;
margin-left: -100%;
transition: margin 0.3s ease-in 0s;
}
.switch-text:before,
.switch-text:after {
float: left;
width: 50%;
line-height: 30px;
color: white;
box-sizing: border-box;
}
.switch-text:before {
content: "ON";
padding-left: 10px;
background-color: #E1F6FF;
color: #000000;
}
.switch-text:after {
content: "OFF";
padding-right: 10px;
background-color: #4D5585;
color: #FFFFFF;
text-align: right;
}
/*Style center dot*/
.switch-dot {
width: 30px;
height: 30px;
background: #FFFFFF;
position: absolute;
top: 0;
bottom: 0;
right: 41px;
margin-right: 5px;
border-radius: 20px;
transition: all 0.3s ease-in 0s;
}
.switch-dot:after{
content: "";
position: absolute;
width: 20px;
height: 20px;
background-size: cover;
background-image: url('http://www.free-icons-download.net/images/multiply-icon-27981.png');
margin: 5px 0 0 5px;
}
/*State changer*/
.switch-checkbox:checked+.switch-labels .switch-text {
margin-left: 0;
}
.switch-checkbox:checked+.switch-labels .switch-dot {
right: 0px;
margin-right: 0px;
}
<div class="switch">
<input type="checkbox" name="switch" class="switch-checkbox" id="myswitch" checked>
<label class="switch-labels" for="myswitch">
<span class="switch-text"></span>
<span class="switch-dot"></span>
</label>
</div>
Change the text in content for toggle.before to
content: "hide show";
Well, just want to add labels?
use below inside .toggle:before
content: "Hide Show";
instead
content: "text text";
Thanks. Ask for more queries.
If you want to put the text on the white circle means , you can add this one in css
.toggle:before{
text-overflow: ellipsis;
overflow: hidden;
}
I am not sure if I understand your question right way. Do you mean add a lebal to toggle this checkbox?
body{
background-color: #ddd;
}
.toggle {
-webkit-appearance: none;
appearance: none;
width: 65.57px;
padding: 10px;
height: 26.32px;
display: inline-block;
position: relative;
border-radius: 13px;
overflow: hidden;
line-height: 16px;
text-align: center;
font-size: 12px;
outline: none;
border: none;
cursor: pointer;
background: #E1F6FF;
transition: background-color ease 0.3s;
}
.toggle:before {
content: "text text";
display: block;
position: absolute;
z-index: 2;
width: 24px;
height: 24px;
background: #fff;
left: 0;
top: 0;
border-radius: 50%;
padding-top: 5px;
text-indent: -30px;
word-spacing: 37px;
color: #4D5585;
text-shadow: -1px -1px rgba(0,0,0,0.15);
white-space: nowrap;
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
transition: all cubic-bezier(0.3, 1.5, 0.7, 1) 0.3s;
}
.toggle:checked {
background: #dadce8;
}
.toggle:checked:before {
left: 40px;
}
.center{
text-align: center;
}
<div class="center">
<input id="sample" class="toggle" type="checkbox" />
<label for="sample">This is a sample</label>
</center>

Placeholder position when input has text

How to do placeholder styling when Input Text are focus, the placeholder are still visible and the font-size become smaller. For example like this:
I only need webkit support. Does webkit support such thing?
.input {
width: 200px;
height: 35px;
outline:0;
padding:0 10px;
}
.label { position: absolute;
pointer-events: none;
left: 20px;
top: 18px;
transition: 0.2s ease all;
}
input:focus ~ .label,
input:not(:focus):valid ~ .label{
top: 10px;
bottom: 5px;
left: 20px;
font-size: 12px;
}
<div>
<input type="text" class="input" required/>
<span class="label">Company Name</span>
</div>
You need to use a label element and modify it accordingly. Try this:
function fillClass() {
if ($(this).val() != '')
$(this).parent().addClass('input--filled');
else
$(this).parent().removeClass('input--filled');
}
$(".sign-in-input").focusout(fillClass);
.sign-in-input-ctr {
width: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: 25px;
position: relative;
margin-top: 50px;
}
.sign-in-input {
width: 100%;
border: 2px solid transparent;
-webkit-transition: all 0.3s;
transition: all 0.3s;
height: 38px;
background-color: #fff;
outline: none;
border: 1px solid rgba(73, 73, 73, 0.2);
border-radius: 2px;
padding-left: 10px;
}
.sign-in-input:focus,
.input--filled .sign-in-input {
background-color: transparent;
border: 1px solid #a09e9e;
}
.sign-in-label {
width: 100%;
font-size: 12px;
position: absolute;
top: -18px;
pointer-events: none;
overflow: hidden;
padding: 0 15px;
left: 0;
-webkit-transform: translate3d(0, 30px, 0);
transform: translate3d(0, 30px, 0);
-webkit-transition: -webkit-transform 0.3s;
transition: transform 0.3s;
}
.sign-in-input:focus+.sign-in-label,
.input--filled .sign-in-label {
-webkit-transform: translate3d(-15px, 0, 0);
transform: translate3d(-15px, 0, 0);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sign-in-input-ctr">
<input class="sign-in-input" type="text" name="email">
<label class="sign-in-label" for="signin-email"><span class="input-label-content">Email</span>
</label>
</div>
//------ contact us dropdown list
$(document).ready(function(){
$( ".form-group .form-control" ).focus(function() {
$(this).parent().addClass('inputFous');
}).blur(function() {
if($.trim($(this).val()) == '')
{
$(this).parent().removeClass('inputFous');
}
});
});
I think there is no webkit support for this, please check this code which will help you:- Jsfiddle

How to get text to appear cleanly after widening div through transition in CSS?

Here you can see my issue. I assume it has to do with the block and inline-block. I want to cleanly make the text appear when hovering over the area. Preferably all in CSS. If anyone can point me in the right direction, that'd be amazing. Thank you!
HTML
<div class="contact-icon icongrow" id="github">
<span class="fa fa-github icon"></span>
<span class="contact-icon-text">#username</span>
</div>
CSS
#github {
border-radius: 15px 10px;
padding: 8px 5px 5px 8px;
background: #000000;
color: #FFFFFF;
}
.icon {
float:none;
}
.icongrow {
font-size:24px;
width: 24px;
transition:width 1s;
display: block;
}
.icongrow:hover {
font-size: 28px;
width: 300px;
}
.icongrow:hover .contact-icon-text {
display: inline-block;
}
.contact-icon-text {
display: none;
}
https://jsfiddle.net/sfpfka64/
Add white-space: nowrap to .icongrow
.icongrow {
font-size:24px;
width: 24px;
transition:width 1s;
display: block;
white-space: nowrap;
}
and add an opacity transition to contact-icon-text :
.icongrow:hover .contact-icon-text {
opacity: 1;
}
.contact-icon-text {
opacity: 0;
display:inline-block;
transition: all 0.5s;
}
Also make the font-size on hover same as the initial font-size to provide more smoothness :
.icongrow:hover {
font-size: 24px;
width: 300px;
}
Snippet
#github {
border-radius: 15px 10px;
padding: 8px 5px 5px 8px;
background: #000000;
color: #FFFFFF;
}
.icon {
float:none;
}
.icongrow {
font-size:24px;
width: 24px;
transition:width 1s;
display: block;
white-space: nowrap;
}
.icongrow:hover {
font-size: 24px;
width: 300px;
}
.icongrow:hover .contact-icon-text {
opacity: 1;
}
.contact-icon-text {
opacity: 0;
display:inline-block;
transition: all 0.5s;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"/>
<div class="contact-icon-container">
<div class="contact-icon icongrow" id="github">
<span class="fa fa-github icon"></span>
<span class="contact-icon-text">#username</span>
</div>
</div>
Just add the following rules to the .icongrow
white-space: nowrap;
overflow: hidden;
Working fiddle: https://jsfiddle.net/yvqga0ja/
An easy way would be to put your "contact-icon-text" as a position absolute, so that he would always be placed at the right place.
Demo
.contact-icon-container{
position:relative;
}
.contact-icon-text {
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 10px;
opacity: 0;
}
.icongrow:hover .contact-icon-text {
opacity: 1;
transition: .3s ease-in;
You can add transition-delay in order to make your text appear a bit later, but you get the way I would do it :)

Resources