A searchbox using select and input for older browsers(no flexbox) - css

I want to create a search box, by using a select and an input.
I have 2 issues:
I want the search input to fill all the remaining space(see the grey background);
Select and input to be connected, no space between them(because of DOM space)
Because I need to work older IE, I can't use flexbox or grid; I tried also float.
Looking for a solution where select and input width is flexible, not fixed;
I tried a trick, (in comments, width: 1%) that sometimes works, but not with select;
.searchbox {
display: table;
width: 500px;
background-color: grey;
}
select, .form-group{
display:table-cell;
margin:0;
}
/*select {
width:1%;
space:nowrap;
}*/
<div class="searchbox">
<select>
<option>Abras</option>
<option>Brat</option>
</select>
<div class="form-group">
<input placeholder="Search" name="q""/>
<span>icon_placeholder</span>
</div>
</div>

According to this float: will not work in IE9, but if you use -ms- it should work in IE10 +. I was reading around and although the website I listed said it's not supported in IE9 im finding articles of people being able to use it. Let me know if you have any issues with the following code.
img {
width: 100%;
height: 100%;
}
.wrapper {
overflow: hidden;
width: 100%;
max-width: 500px;
}
.left {
float: left;
-ms-float: left;
overflow: hidden;
}
.options {
width: 75px;
}
.search {
width: calc(100% - 110px);
}
.image {
width: 35px;
height: 35px;
}
.style {
padding: 8px;
margin: 0;
}
.full {
width: calc(100% - 25px);
}
<div class="wrapper">
<div class="left options">
<select class="left style">
<option>Abras</option>
<option>Brat</option>
</select>
</div>
<div class="left search">
<input class="style full" placeholder="Search" name="q" />
</div>
<div class="left image">
<img src="https://seeklogo.com/images/C/company-leaf-and-flames-logo-2ECEE07FDD-seeklogo.com.png" alt="img" />
</div>
</div>

Changing the display for the select to display: inline-block; aligns everything to the left.
This won't center align the fields vertically if you choose to change the height later, but I think it solves your problem.
select, .form-group {
display: inline-block;
margin: 0;
}

You can float the select and then turn the .form-group div into a block formatting context, doing this will make it respect the floats position and fill the remaining space making it dynamic. See the demo below and click here to read more about block formatting contexts
.searchbox {
display: table;
width: 500px;
background-color: grey;
}
/* select, .form-group{
display:table-cell;
margin:0;
} */
select {
float: left;
}
.form-group {
overflow: auto;
}
input {
width: 100%;
box-sizing: border-box; /* keep box model properties subtracted from width not added */
}
<div class="searchbox">
<select>
<option>Abras</option>
<option>Brat</option>
</select>
<div class="form-group">
<input placeholder="Search" name="q"/>
<span>icon_placeholder</span>
</div>
</div>
There are many ways to turn an element into a block formatting context, I have opted to set the overflow property to hidden.
If you want an element to sit on the right of .form-group make sure to add it before the .form-group element in your mark up and float it right. The form-group will then fill the remaining space in the middle of the 2 floated elements.
Lastly when using floats don't forget to clearfix your container

Related

Tabs with only CSS (specifically, vertical Tabs)

I am creating my personal version of Tabs using only a CSS solution, specifically a version in which Tabs are placed aside content, in a vertical solution, so I'd need to have Tabs on the left and content on the right.
My fisrt attempt was using "Absolute positioning", to place each full content on the right side, mantaining tabs on the left. This solution runs correcly playing with opacity value of each one, as you can see in the linked example.
But... it's have a limit... Due to absolute positioning I have to "force" an height of the entire Tabs container with overflow-y:auto; rule applied to longest content. In this way, there will always be a content that will make scrollable Tabs container and not the entire page.
In an attempt to supersede these limitations, i found a possible solution using Grid layout applied to inner content, that is "animatable to auto" (please see reference here at the end of article). The specific code of the example was:
.content {
display: grid;
grid-template-rows: 0fr;
transition: 1s;
overflow: hidden;
}
.content .inside {
min-height: 0;
}
.content.expanded {
grid-template-rows: 1fr;
}
Applying it to my case, would result in this HTML:
<div class="tabs-css vertical">
<div class="tab-accordion-item">
<input id="tab-accordion_hoqc_1" type="radio" name="tab-accordion" checked="">
<label for="tab-accordion_hoqc_1"> Intestazione Tab 1 </label>
<div class="item-content">
<div class="item-content-inner">
<div class="description">
<p>...</p>
</div>
</div>
</div>
</div>
<div class="tab-accordion-item">
<input id="tab-accordion_hoqc_2" type="radio" name="tab-accordion">
<label for="tab-accordion_hoqc_2">Questa è una intestazione di prova lunga</label>
<div class="item-content">
<div class="item-content-inner">
<div class="description">
<p>...</p>
</div>
<div></div>
</div>
</div>
</div>
</div>
and this sCSS:
.tabs-css
{
display:flex;
position:relative;
height: 300px;
> .tab-accordion-item
{
$label-height:45px;
> label
{
display:block;
background: gray;
color: white;
}
> .item-content
{
overflow-y:auto;
position:absolute;
z-index:1;
top:3px;
left:0;
height:calc(100% - $label-height + 3px); // Container height - Label height + Container padding-top
width:100%;
opacity:0;
.item-content-inner {
min-height: 0;
}
}
> input[type=radio]
{
display:none;
&:checked
{
+ label
{
z-index:2;
background: red;
+ .item-content
{
opacity:1;
z-index:3;
}
}
}
}
}
&.vertical {
flex-direction: column;
> .tab-accordion-item
{
> label
{
max-width: 400px;
padding: 10px 16px;
height: auto;
line-height: inherit;
white-space: normal;
}
> .item-content {
top: 0;
bottom: 0;
left: 450px;
width: auto;
height: auto;
}
}
}
}
But, renouncing to absolute positioning I'm not able to replicate side Tabs layout.
I could add:
.tab-accordion-item {
display: flex;
}
That "seems" similar to what I'd need, placing side-by-side Tab and relative content, but the behaviour si more similar to an Accordion, instead of a Tab...

Two div's, first auto-adjust, second fixed width

I'm trying to make a simple subscription form, which consists of two elements:
Textbox - Floated left, fills up remaining space.
Button - Floated right, 100px width.
The problem is I can't get the textbox to fill up the remaining width.
.container
{
width: 100%;
}
.input-field
{
float: left;
}
.button
{
float: right;
width: 100px;
}
<div class='container'>
<input class='input-field'/>
<div class='button'>Subscribe</div>
</div>
http://jsfiddle.net/7nyY7/136/
For some reason the textbox is not stretching till the start of the button.
So I tried a different approach and used tables, this is exactly what I'm trying to accomplish, BUT the problem is whenever I add padding to the button and input, they both overflow each other:
http://jsfiddle.net/B46wu/111/
Is it possible to make the textbox end right where the button starts, regardless if the padding is present or not?
Because of the design, I need the textbutton and button to be exactly next to each other. Is this possible without JS? Thanks!
The best way is to use Flexbox...apply flex:1 to the input to get the remaining space
Stack Snippet
.container {
display: flex;
}
.input-field {
flex: 1;
}
.button {
width: 100px;
background: red;
color: white;
text-align: center;
}
<div class='container'>
<input class='input-field' />
<div class='button'>
Subscribe
</div>
</div>
And if you want to use float solution you will need to set the width of input is equal to calc(100% - 100px)
.container {
width: 100%;
}
.input-field {
float: left;
}
.button {
float: left;
width: 100px;
background: red;
color: white;
text-align: center;
}
input {
width: calc(100% - 100px);
box-sizing: border-box;
}
.container:after {
content: "";
display: table;
clear:both;
}
<div class='container'>
<input class='input-field' />
<div class='button'>
Subscribe
</div>
</div>
You can apply display: flex to the container, and add the flex-grow property to the textbox, which will make it grow to fill the remaining space.
You can read up on flexbox here
.container {
width: 100%;
display: flex;
}
.input-field {
background-color: red;
opacity: 0.5;
flex-grow: 1;
}
.button {
width: 100px;
background-color: blue;
opacity: 0.5;
}
<div class='container'>
<input class='input-field' />
<div class='button'>
Subscribe
</div>
</div>
For Accessibility use proper HTML as in the html below buttons instead of
<div class='button'>
Subscribe
</div>
.container{
box-sizing: border-box;
margin: 0;
padding: 0;
width: 100%;
/*This makes the immediate children into flex items*/
display: flex;
}
.input-field {
/*This will span out the whole width minus the 100px for the button*/
flex: 1;
}
button {
/*Set button width*/
width: 100px;
padding: 5px 20px
}
<div class='container'>
<input class='input-field' />
<button class='button'>Subscribe</button>
</div>

firefox height does not grow up but works in chrome

I have two display: table-cell columns. Left one has a button and it adds content to left column when clicked. And right one has text box which should grow its height with the height of left column. So, I gave some fixed height value to right column: #step-right { height: 10px; }.
This works fine in chrome but still having issue in firefox. I found firefox have some issue regarding height: 100% but could not say this is exactly the same problem. I want to solve using no JS tricks.
Any help will be much appreciated. Thanks
function step() {
var stepLeft = document.getElementById('step-left');
stepLeft.innerHTML = 'Step <br/>' + stepLeft.innerHTML;
}
* {
box-sizing: border-box;
}
.step-content {
display: table;
background-color: blue;
}
.step-bar {
display: table-cell;
height: 100%;
}
#step-left {
background-color: yellow;
}
#step-right {
height: 10px;
background-color: green;
}
.input-group {
height: 95%;
display: table;
}
.input-group textarea {
height: 100%;
}
<div class="steps">
<div class="step">
<div class="step-content">
<div class="step-bar" id="step-left">
<button type="button" onClick="step()">Step</button>
</div>
<div class="step-bar" id="step-right">
<span class="input-group">
<textarea></textarea>
</span>
</div>
</div>
</div>
</div>

Have link to right of an input and the input take up the full remaining width with CSS?

This is a very basic question but I think inputs behave strangely so im struggling to find a solution.
I have a liquid width layout. I need a link to sit to the side of an input. I need the input to take up all the available width:
Information Link
<input type="number" class="form-control form-control-default-new" placeholder="400">
If the input was a div I would just float the link the right and not have to do anything else. However if I make the input display block it wont take up the full width. And If I make it width 100% then it takes up the whole line and the link no longer sits along side it.
If you can wrap that input in a div container, you can achieve that effect pretty easy:
float right for the a tag
overflow: hidden to the div container of the input
set input width to 100%
done.
Check out the demo here
a{
float: right;
}
div{
overflow: hidden;
padding-right: 20px;
}
input{
box-sizing: border-box;
width: 100%;
}
Information Link
<div><input type="number" class="form-control form-control-default-new" placeholder="400"/></div>
Example with display: block and float: left :
* {
box-sizing: border-box;
}
a, input {
display: block;
float: left;
}
a {
text-align: center;
width: 20%
}
input {
width: 80%
}
<input type="number" class="form-control form-control-default-new" placeholder="400">
Information Link
You can try using display: table and display: table-cell. The white-space: nowrap CSS prevents the second cell (with the link) from line-breaking and the width: 100% on the first cell makes that cell grow as large as the table will allow it to (i.e. until the cell runs into the second cell with the nowrap restriction.
JSFIDDLE DEMO
CSS:
* {
box-sizing: border-box;
}
input {
width: 100%;
}
.container {
width: 100%;
display: table;
}
.container div {
display: table-cell;
white-space: nowrap;
}
.link {
text-align: right;
padding-left: 10px;
}
.input-box {
width: 100%;
}
HTML:
<div class="container">
<div>
<input type="number" class="form-control form-control-default-new" placeholder="400" />
</div>
<div class="link">
Information Link
</div>
</div>
I would set the desired width for the input fields, like this http://codepen.io/anon/pen/PwpBoK
.wrapper {
width: 100%;
height: 120px;
background: #ccc;
padding: 12px;
}
.text {
margin: 0 auto;
width: 600px;
}
.container {
background: #fff;
margin: 0 auto;
width: 600px;
height: 45px;
padding: 10px;
}
input {
width: 400px;
margin-right: 8px;
}
.form-control form-control-default-new {
width: 400px;
}
<div class="wrapper">
<div class="text">
<p>I need this:</p>
</div>
<div class="container">
<input type="number" class="form-control form-control-default-new" placeholder="400">Information Link
</div>
</div>

HTML layout of several boxes on one line

I am breaking my head over this seemingly easy problem, perhaps someone could help. I would like an arbitrary amount of inputs, with labels, stacked horizontally on one line like in the image.
There are a number of ways to go about this. Personally, I like using tables for this type of data (but if it's not tabular data it is recommended to use other means like DIVs). I'll try to show a quick example of a table:
Table:
<table width="100%" cellpadding="0" callspacing="0" border="0">
<tr>
<td width="200">LABEL 1</td><td> </td> <!-- this is the padding table cell -->
<td width="200">LABEL 2</td><td> </td>
<td width="200">LABEL 3</td><td> </td>
</tr>
</table>
Example Table JSFiddle
Using Div's are slightly more involved, as they are inline by default; you would get your labels on different lines. You can look into CSS attributes like "display: table-cell" to achieve the same results as the above, otherwise you can look into absolute and relative positioning using CSS.
<div width="100%">
<div style="position:absolute; top:0px; width: 33%;">LABEL 1</div>
<div style="position: absolute; top:0px; left: 33%; width: 33%;">LABEL 2</div>
<div style="position: absolute; top:0px; left: 66%; width: 34%;">LABEL 3</div>
</div>
However, there are still some problems with this as it's assuming your layout is 100% the width of the page/browser viewing area.
Generally, when you want something to "take up the remaining space" (like your input box) you have 3 options:
Flexbox, which would be ideal, but not widely supported yet.
Tables, like explained in Kevin Reids answer
Establish separate Block Formatting Contexts, example below
HTML
<div class="container">
<div class="field">
<label for="in1">Label</label>
<div><input type="text" id="in1"></div>
</div>
<div class="field">
<label for="in2">Label</label>
<div><input type="text" id="in2"></div>
</div>
<div class="field">
<label for="in3">Label</label>
<div><input type="text" id="in3"></div>
</div>
</div>​
CSS
.container {
padding: 20px;
background: #999;
overflow: hidden; /* for float containment */
}
.field {
padding: 4px;
background: #fff;
border: 2px solid #999;
float: left;
width: 33%;
-webkit-box-sizing: border-box; /* 33% effective width */
-moz-box-sizing: border-box;
box-sizing: border-box;
}
label {
float: left;
width: 100px; /* fixed width of label */
}
.field div {
overflow: hidden; /* create a new Block Formatting Context */
}
/* inputs fill the new BFC */
input {
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
​
There is only 1 added layout element, which would be the div that wraps the input. This is because input doesn't want to behave like a block element, even if you tell him to do so.
fiddle: http://jsfiddle.net/RqzJC/
EDIT: updated to address fixed width labels. (arbitrarily set to 100px)
http://jsfiddle.net/SebastianPataneMasuelli/XHrSr/
HTML:
<div>
<div>
<div class="label">LABEL</div>
<div>filler</div>
</div>
<div>
<div class="label">LABEL</div>
<div>filler</div>
</div>
<div>
<div class="label">LABEL</div>
<div>filler</div>
</div>
</div>
CSS:
div { width: 100%; }
div div {
width: 33%;
background-color: salmon;
float: left;
position: relative
}
div div div {
background-color: pink;
position: relative;
z-index: 2
}
div div div:last-child {
background-color: red;
position: absolute;
width: 100%;
z-index: 1
}
.label { width: 100px }
​
​
The best option for this type of classic “GUI widget layout engine” layout is the CSS 3 flexbox feature, but browser support is not yet consistent enough that I would recommend using it.
Absent that, flexible "fill space" layouts generally require table layout. Thanks to CSS display, there is no particular necessity to write the table as a HTML table. The following example is similar to your example image:
<html><head>
<title>example</title>
<style type="text/css">
ul.myform { display: table; width: 100%; margin: 0; padding: 0; border-collapse: collapse; }
.myform li { display: table-cell; border: .1em solid gray; }
.myform li > * { display: table; width: auto; margin: .4em; }
.myform label { display: table-cell; width: 1%; padding-right: .4em; white-space: nowrap; }
.myform input { display: table-cell; width: 100%; }
.col1 { width: 33%; }
.col2 { width: 33%; }
.col3 { width: 34%; }
</style>
</head><body>
<form>
<ul class="myform">
<li class="col1"><span><label for="a">Label</label> <input id="a" name="a"></span></li>
<li class="col2"><span><label for="b">Label</label> <input id="b" name="c"></span></li>
<li class="col3"><span><label for="c">Label a bit longer</label> <input id="c" name="c"></span></li>
</ul>
</form>
</body></html>
There is exactly one element introduced solely for layout in the markup: the <span> is needed to serve as the table within the table-cell.
The width: 1%; of the label cell is not an actual dimension but simply to force it as narrow as possible (an absolute rather than percentage with will not have the same effect). The white-space: nowrap; prevents the label from getting wrapped due to this.
The .col1 and so on are for specifying the widths of the columns.

Resources