Multiple dots for input html - css

I have a React component that encapsulates the input html tag. The default behaviour for input tag is if the characters are more than what the input can display, we can scroll to left and right with invisible scroll (e.g. I type John Smitheens for size 11).
I want to make the display change to John Smith... if the input is unfocused (not clicked).
I don't know the size or number of characters I want to limit beforehand because the React component is used in a lot of places and the size differs based on parent component (width: 100%). Is there a way to get the input size or know when the characters exceed the input width? Thank you
<!DOCTYPE html>
<html>
<body>
<input placeholder="Search User" type="text" size="11">
</body>
</html>

Try this in your stylesheet :)
Add it to your input css.
text-overflow: ellipsis;
Similar case here:
how to add three dots to text when overflow in html?
More on the topic:
https://developer.mozilla.org/en-US/docs/Web/CSS/text-overflow

Just add text-overflow: ellipsis; to the input
input {
text-overflow: ellipsis;
}
<!DOCTYPE html>
<html>
<body>
<input placeholder="Search User" type="text" size="11">
</body>
</html>

Related

Baseline Alignment of Input and Labels in CSS Grid

I'm trying to build a form using a CSS grid layout. Labels appear in the left column and inputs in the right. The align-items property is set to baseline. In Chrome, the text of the labels and inputs are vertically aligned on their baseline. But in Firefox v94, the labels sit higher than the text in the inputs.
Here's a minimal reproducible example of the problem:
<!DOCTYPE html>
<html>
<head>
<style>
.login-grid {
display: grid;
grid-template-columns: auto 1fr;
grid-gap: 10px 2px;
align-items: baseline;
}
label, input {
font-size: 3em;
}
</style>
</head>
<body>
<div class="login-grid">
<label>username</label>
<input type="text">
</div>
</body>
</html>
This example is live on Codepen.
When I wrap the inputs up in a div, the text does align across columns. I'd prefer not to do that because the nesting affects sizing.
I've examined many of the other posts on alignment issues, but I've not found one relevant to CSS grid.
Firstly if you want to have a design as close as possible between different browsers I would recommend using a normalize css or a reset css.
Then working with font rendering is always a difficulty since the implementation of css property always differ a bit between browsers.
As you can see in the images below with a normalize and the same CSS code there is still differences between Chrome and Firefox :
Chrome add "gaps"
But as an alternative you can with a normalize CSS and align-items: center get an identical result between Chrome and Firefox:

How to resize a text field in Chrome?

I need to resize a text field in google Chrome. I want to be able to drag the end of the textfield horizontally & vertically.
This is what I have tried so far. I'm able to see the resize icon at the corner of the text field, but not able to move it either ways. I have used style="resize:horizontal;" Could some tell me where I am going wrong...
Thanks
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Text Feilds</title>
<script type="text/javascript">
</script>
</head>
<body>
<table>
<tr>
<td>
<input type="text" id="txt1" style="resize:horizontal;" />
<input type="text" id="txt2" style="resize:both;" />
<input type="text" id="txt3" style="resize:vertical;"/>
</td>
</tr>
</table>
</body>
</html>
By the specifications, you could make any element (including an <input type=text> element) resizeable by setting the overflow property to any value other than visible, in addition to setting the resize property.
In practice, even browsers that support the resize property at all may have restrictions in its applicability. Chrome does not make an <input type=text> element resizeable if you do the above. This is probably a bug, since it is clearly trying to do that: a resize handle appears. Safari, on the other hand, makes it resizeable even if you just set resize, without setting overflow.
There’s a workaround that seems to work on Chrome, though it’s kludgy and not robust-looking. Put the input element inside a div, and make the div resizeable and set the input width near 100%. Not quite 100%, since this would mess things up (no room for the resize handle). Something like this:
<div style="resize: horizontal; width: 15em;
overflow: auto; border: solid gray 1px">
<input style="width: 96%; border: none; resize: none">
</div>
Use a textarea element instead.
Example here
resize is a not style property of html input type text. So, that means you are trying to assign a wrong attibute to the text input tag.
Check this link for more details. From the link
Applies To
elements with 'overflow' other than visible
Use textarea as explaind in other answer.

Inconsistent CSS behavior: 'display' and 'float' -- need advice

I'm in the midst of the HTML5/CSS/JavaScript learning curve and have hit a wall.
My goal is to create a form. In the process of executing this seemingly simple task, I've created a confusing monstrosity that displays perfectly in Firefox and IE, but appears as a jumbled mess in Chrome and Safari. I've written some sample code that illustrates my problem. Consider this three line form that has two text fields for username and password, and a checkbox to indicate whether or not the theme from 'Sanford and Son' should play during the user's session.
<!DOCTYPE HTML>
<html>
<head>
<style>
form label{
float: left;
clear: left;
text-align: right;
margin-right: 10px;
width: 110px;
}
form input{
display: block;
margin-bottom: 5px;
padding: 0px .2em;
outline: none;
}
</style>
</head>
<body>
<form id="loginPopup">
<fieldset>
<label for="username">Username:</label>
<input type="text" id="username" name="username"/>
<label for="password">Password:</label>
<input type="password" id="password" name="password"/>
<label for="sanford">Sanford Theme:</label>
<input type="checkbox" id="sanford" name="sanford"/>
</fieldset>
</form>
</body>
</html>
Try viewing it in IE or Firefox and everything looks perfect. Now try viewing it in Chrome or Safari. The 'sanford' checkbox appears underneath its label. Not good. The checkbox is obviously supposed to appear to the right of the label. What's even more perplexing is that if I replace the checkbox with some other input (e.g. text, radio, etc.), everything appears properly in all browsers. This problem seems limited to the checkbox.
I can't wrap my head around what's going on here. The 'Sanford' label is floated to the left so presumably the checkbox should flow to the immediate right of that label -- and in fact that's exactly what happens in Firefox/IE… so why not in Chrome/Safari?
Any help would be greatly appreciated.
EDIT: I posted the code to the Fiddle site as requested: http://jsfiddle.net/ChadDecker/FyNZw/
Float is tricky. If one element is floated, the others have to be floated or it will be all screwed up. So you must float every element and adjust with padding/margin as necessary. What you may want to try also is using:
position: absolute;
and also using z-index which tells the page what items to display over top of the other:
z-index: 0;
EDIT
Your form on JSFiddle: It's all designed wrong in my opinion. You shouldn't be using form.input because since the checkbox field is considered a form of input, hence <input then it gets the properties from form.input style. I made a simple class to show you called box:
http://jsfiddle.net/FyNZw/2/

width:auto for <input> fields

Newbie CSS question. I thought width:auto for a display:block element meant 'fill available space'. However for an <input> element this doesn't seem to be the case. For example:
<body>
<form style='background:red'>
<input type='text' style='background:green; display:block; width:auto'>
</form>
</body>
Two questions then:
Is there a definition of exactly what width:auto does mean? The CSS spec seems vague to me, but maybe I missed the relevant section.
Is there a way to achieve my expected behavior for a input field - ie. fill available space like other block level elements do?
Thanks!
An <input>'s width is generated from its size attribute. The default size is what's driving the auto width.
You could try width:100% as illustrated in my example below.
Doesn't fill width:
<form action='' method='post' style='width:200px;background:khaki'>
<input style='width:auto' />
</form>
Fills width:
<form action='' method='post' style='width:200px;background:khaki'>
<input style='width:100%' />
</form>
Smaller size, smaller width:
<form action='' method='post' style='width:200px;background:khaki'>
<input size='5' />
</form>
UPDATE
Here's the best I could do after a few minutes. It's 1px off in FF, Chrome, and Safari, and perfect in IE. (The problem is #^&* IE applies borders differently than everyone else so it's not consistent.)
<div style='padding:30px;width:200px;background:red'>
<form action='' method='post' style='width:200px;background:blue;padding:3px'>
<input size='' style='width:100%;margin:-3px;border:2px inset #eee' />
<br /><br />
<input size='' style='width:100%' />
</form>
</div>
"Is there a definition of exactly what width:auto does mean? The CSS
spec seems vague to me, but maybe I missed the relevant section."
No one actually answered the above part of the original poster's question.
Here's the answer:
http://www.456bereastreet.com/archive/201112/the_difference_between_widthauto_and_width100/
As long as the value of width is auto, the element can have horizontal
margin, padding and border without becoming wider than its container...
On the other hand, if you specify width:100%, the element’s total
width will be 100% of its containing block plus any horizontal margin,
padding and border... This may be what you want, but most likely it isn’t.
To visualise the difference I made an example:
http://www.456bereastreet.com/lab/width-auto/
ORIGINAL answer using Angular: Because input's width is controlled by it's size attribute, this is how I initialize an input width according to its content:
<input type="text" class="form-list-item-name" [size]="myInput.value.length" #myInput>
UPDATE for JavaScript (10/01/2022): My original answer was from the time I was studying Angular. If you need pure, Vanilla JavaScript the solution is even simpler:
<input type="text" oninput="this.size = this.value.length">
Or add an "input" event listener to your input html element and run a code like this:
const myInput = document.querySelector('input');
myInput.addEventListener('input', this.typing);
(...)
typing(e) {
e.target.setAttribute('size', e.target.value.length);
}
Obs: Depending on the browser, input may restore to its default size of something between 150px and 250px if/when size gets the 0 value. In this case, just add +1 to value.length:
<input type="text" oninput="this.size = this.value.length + 1">
OR:
typing(e) {
e.target.setAttribute('size', e.target.value.length + 1);
}
As stated in the other answer, width: auto doesn't work due to the width being generated by the input's size attribute, which cannot be set to "auto" or anything similar.
There are a few workarounds you can use to cause it to play nicely with the box model, but nothing fantastic as far as I know.
First you can set the padding in the field using percentages, making sure that the width adds up to 100%, e.g.:
input {
width: 98%;
padding: 1%;
}
Another thing you might try is using absolute positioning, with left and right set to 0. Using this markup:
<fieldset>
<input type="text" />
</fieldset>
And this CSS:
fieldset {
position: relative;
}
input {
position: absolute;
left: 0;
right: 0;
}
This absolute positioning will cause the input to fill the parent fieldset horizontally, regardless of the input's padding or margin. However a huge downside of this is that you now have to deal with the height of the fieldset, which will be 0 unless you set it. If your inputs are all the same height this will work for you, simply set the fieldset's height to whatever the input's height should be.
Other than this there are some JS solutions, but I don't like applying basic styling with JS.
It may not be exactly what you want, but my workaround is to apply the autowidth styling to a wrapper div - then set your input to 100%.
If you're willing to include a little JavaScript to solve this, you can get exact sizing. This doesn't rely on approximating width with size or ems, doesn't rely on any hardcoded element widths, and works for e.g., type="number", which don't accept a size attribute.
The trick is to get your input sized exactly like a span with the same content, by actually having an invisible span with the same content.
Put your input inside a div along with a span that mirrors the input's value. Give both the input and the span the same styling, give the input 100% width, then hide the span and absolute-position the input to sit on top of the span.
This way, the container (and thus the input) are automatically sized by the visual appearance of the content of the invisible span.
https://codepen.io/spiffytech/pen/abwWRqo
<div id="relative-parent">
<span id="size-calibration"></span>
<input id="autosized-input" />
</div>
<style>
#relative-parent {
position: relative;
/* Have some width if the input is empty */
min-width: 1em;
/* Adjust size to match the span */
width: min-content;
}
#size-calibration {
visibility: hidden;
/* Prevent the span from wrapping the text when input value has multiple words, or collapsing multiple spaces into one */
white-space: pre;
}
#autosized-input {
position: absolute;
left: 0;
width: 100%;
}
#size-calibration, #autosized-input {
/* Normalize styles that the browser sets differently between spans and inputs.
Ideally, use a "CSS reset" here. */
font-family: "Arial";
padding: 0;
/* Demonstrate that this works for input with custom styles */
font-size: 24px;
}
</style>
<script>
function updateSize() {
const span = document.getElementById('size-calibration');
const input = document.getElementById('autosized-input')
span.innerText = input.value;
}
document.addEventListener('DOMContentLoaded', () => {
const input = document.getElementById('autosized-input');
input.oninput = updateSize;
// Provide some initial content
input.value = "I'm sized exactly right!"
updateSize();
})
</script>
After tried methods all above and failed, I workaround by modifying   width property in style by unit em:
tgt.style.width = `${(tgt.value.length + 1) / 2}em`
The only option I can think of is using width:100%. If you want to have a padding on the input field too, than just place a container label around it, move the formatting to that label instead, while also specify the padding to the label. Input fields are rigid.
Answer 1 - "response" gave a nice answer/link for it. To put it in short, "auto" is the default, so it is like removing any changes in the width of an element
Answer 2 - use width: 100% instead. It will fill the 100% of the parent container, in this case, the "form".
Using JQuery
$(document).on('input', '.input-fit-width', (e) => {
$(e.currentTarget).attr('size',e.currentTarget.value.length);
})
Nowdays, flex or grid makes it much easier , it overrides default style/behaviors of https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input#size which has a default value set at 20 see : https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input#size
Giving you 2 plain CSS options without requiring JavaScript nor setting width to 100% and deal with box-sizing.
flex/flex-grow
<form style='background:red;display:flex;'>
<input type='text' style='background:green; flex-grow:1'>
</form>
grid
<form style='background:red;display:grid;'>
<input type='text' style='background:green;'>
</form>
Jquery way of adjusting size of input automatically.
In general:
$('#my_input_id').width( ($('#my_input_id').val().length) + "ch" );
On text input:
$(document).on("input", '#my_input_id', function () {
$(this).width( ($(this).val().length) + "ch" );
});
I think the simplest solution is to set parent element's width:
form{
width: 100%!important;
}

CSS column header with img - how to dock img/div to the right?

I have an HTML table that I use as column headers to a grid view. Clicking on a column header triggers javascript that makes the grid view sort, and an icon showing that the column is sorted shows up next to the column text, similar to below:
|---------------------------------------------------------------------------------|
| <span> Column 1 </span> <div class="sortImgSprite" /> | <span> Column 2 </span> |
|---------------------------------------------------------------------------------|
The table has table-layout: fixed, and the span for text has overflow: hidden, text-overflow: ellipsis, white-space: nowrap.
When the text is very long, I do get the ellipsis effect that I want, but the sort icon sprite (div with width and background set) gets clipped off the right side of the table cell. Any suggestions how to make sure the sort icon gets precedence for space over the ellipsizing text via CSS? If a column is "sorted", I want the sort img to always be there and have the text ellipsize instead of the text pushing the img out of the visible space of the cell:
I'm not sure what floats you're adding to the image, but have you tried floating to the right and adding a right-margin of about 5 px? That would push it inside.
Why wouldn't you just add the "sortImgSprite" class to the <span> tag instead? Since you're doing the sorting via JavaScript anyway, you must have a handle to the table column?
When the user sorts on a column, add the "sortImgSprite" class to the left or right (maybe add a little padding if required) and remove it when that column is no longer sorted.
...or have I missed something?
Ah. I had missed something. Thought the text that was overflowing was in rows below the column headers, not in the headers themselves.
Ok, so what if you were to add the class to the table header? Your <th> tag (if that's what you use) could have the image aligned to the right of the cell and then your <span> tag could inherit that class and add the other formatting (such as the text-overflow, etc)?
Again, you may need padding on the right of your span so that the table header cell's background image can be seen clearly behind any text.
Thanks for the recommendations! Here's what I ended up doing to get what I wanted via CSS:
<html>
<head>
<style type="text/css">
table
{
table-layout:fixed;
width: 300px;
}
div.foo
{
float:right;
width:25px;
height:1.2em;
background-color:green;
}
.bar
{
margin-right:30px;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}
</style>
</head>
<body>
<table border="1">
<tr>
<td>
<div class="foo"></div>
<div class="bar" title="This is some text. This is some text. This is some text. This is some text.">This is some text. This is some text. This is some text.</div>
</td>
</tr>
</table>
</body>
</html>

Resources