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>
Related
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...
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
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>
#container {
display:flex;
height:300px;
background:#333;
}
#child1 {
width:30%;
background:#3cf;
}
#child2 {
width:30%;
background:#3fc;
}
#child3 {
width:40%;
background:#cf3;
}
#child1_child {
width:100%;
background:#fc3;
}
pre {
margin:0px;
}
<div id="container">
<div id="child1"><div id="child1_child"><pre>CONTENT<BR>CONTENT<BR>CONTENT<BR>CONTENT</pre></div></div>
<div id="child2"></div>
<div id="child3"></div>
</div>
The height of #child1 is automatically set to the same height of #container, How can I make it to fit to #child1_child rather than 100% height of #container?
The height of #child1_child is not static, it can be changed by content inside of it, height of #child1 with static value is useless.
fit-content is limited in support; IE won't ever support it, and Firefox still requires a prefix. This solution has jQuery for demo purposes only and is not required for the solution. There are four choices:
NONE: No extra styles on .A
FIT-CONTENT: Adds the CSS property fit-content on .A
MAX-CONTENT: Adds the CSS property max-content on .A
TABLE: Adds the CSS property display:table on .A
Option 2 and 3 behave identically , so in conclusion the simplest solution is to apply display:table and it's incredibly compatible as it is simple. height: fit-content and max-content is almost as compatible with one minor caveat being that IE does not support it (IE is going the way of the dinosaur so it's pretty much a non issue).
Demo
$('.rad').on('change', switchStyle);
function switchStyle(e) {
var pick = $(this).val();
switch (pick) {
case 'nil':
$('.A').removeClass('fit max tab');
break;
case 'fit':
$('.A').addClass('fit').removeClass('max tab');
break;
case 'max':
$('.A').addClass('max').removeClass('fit tab');
break;
case 'tab':
$('.A').addClass('tab').removeClass('fit max');
break;
default:
break;
}
}
.box {
display: flex;
height: 300px;
background: #333;
}
.A {
width: 30%;
background: #3cf;
}
.B {
width: 30%;
background: #3fc;
}
.C {
width: 40%;
background: #cf3;
}
.A1 {
width: 100%;
background: #fc3;
}
pre {
margin: 0px;
}
.set {
position: relative;
z-index: 1;
bottom: 300px;
left: 30%;
width: 30ch;
font: 400 16px/1.428 Verdana;
}
.A.fit {
height: -moz-fit-content;
height: -webkit-fit-content;
height: -fit-content;
}
.A.max {
height: max-content;
}
.A.tab {
display: table;
}
<div class="box">
<div class="A">
<div class="A1"><pre>
CONTENT
CONTENT
CONTENT
CONTENT</pre>
</div>
</div>
<div class="B"></div>
<div class="C"></div>
</div>
<fieldset class='set'>
<label>NONE
<input class='rad' name='rad' type='radio' value='nil' checked>
</label>
<label>FIT-CONTENT
<input class='rad' name='rad' type='radio' value='fit'>
</label><br>
<label>MAX-CONTENT
<input class='rad' name='rad' type='radio' value='max'>
</label>
<label>TABLE
<input class='rad' name='rad' type='radio' value='tab'>
</label>
</fieldset>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Try setting min-height or min-width... Magic.
#container {
display: flex;
height: 100%;
min-height: 0;
}
By default, flex items won’t shrink below their minimum content size (the length of the longest word or fixed-size element). To change this, set the min-width or min-height property. (See §4.5 Automatic Minimum Size of Flex Items.)
https://www.w3.org/TR/css-flexbox-1/#propdef-flex
Using of experimental values of the height CSS property is generally discouraged.
If it is individual flexbox child which you want to fill the height according to its content, use align-self: baseline; for it (see the example). If it is all the children, put align-items: baseline; into the parent container.
#container {
display: flex;
height: 300px;
background: #333;
}
#child1 {
width: 30%;
background: #3cf;
align-self: baseline;
}
#child2 {
width: 30%;
background: #3fc;
}
#child3 {
width: 40%;
background: #cf3;
}
#child1_child {
width: 100%;
background: #fc3;
}
pre {
margin: 0;
}
<div id="container">
<div id="child1"><div id="child1_child"><pre>CONTENT<BR>CONTENT<BR>CONTENT<BR>CONTENT</pre></div></div>
<div id="child2"></div>
<div id="child3"></div>
</div>
This plunkr shows the issue.
http://plnkr.co/edit/Zr4ncVcNa53Sawbk42kK?p=preview
I'd like the blue divs to precisely cover up the red divs.
How do I do this?
The yellow divs cannot be hardcoded in terms of height because their content is variable.
I can't use overflow else the SVG will also overflow, cutting off my chart.
If restructuring the HTML is required (add, remove or moving elements), I can't do it at or above the container class (as I use an HTML partial system and this HTML is generated via nested partials).
I'd like it purely done in the container, variable and fill-vertically CSS classes.
HTML
<li class="fixed left">
<view-widget>
<view-gadget>
<div class="container">
<div class="variable">
Title
<br>
Subtitle
<br>
Something else
</div>
<div class="fill-vertically">
SVG Kendo Chart
</div>
</div>
</view-gadget>
</view-widget>
</li>
<li class="fixed right">
<view-widget>
<view-gadget>
<div class="container">
<div class="variable">
Title
</div>
<div class="fill-vertically">
SVG Kendo Chart
</div>
</div>
</view-gadget>
</view-widget>
</li>
CSS
.container {
background:green;
}
.variable {
background: yellow;
}
.fill-vertically {
background: blue;
color: white;
}
.fixed {
background: red;
list-style: none;
height: 150px;
width: 45%;
}
.left {
position: absolute;
left: 0;
}
.right {
position: absolute;
right: 0;
}
Using flexible boxes: Plunker
.container {
height: 100%; /* fill .fixed's height */
display: flex;
flex-direction: column;
}
.fill-vertically {
flex-grow: 1;
}
Compatibility: Chrome, Firefox 28+, IE11+.
Use the display:table trick in case you need to support older browsers: Plunker
.container {
display: table;
width: 100%;
height: 100%; /* fill .fixed's height */
}
.variable, .fill-vertically {
display: table-row;
}
.variable {
height: 1px; /*computed = as little height as possible to fit content*/
}
.fill-vertically {
height: 100%; /*computed = remaining available height*/
}
Compatible with IE8+ and all modern browsers.