CSS: Inline element stretch to fill available horizontal space of container - css

For example I have a 200px div containing three buttons, the text is only minimal so the buttons don't fill the horizontal space available. Is it possible to..
Make the last button stretch to occupy all the remaining space?
The First button to stretch to fill the remaining space pushing the last two buttons along?
The middle button to stretch to fill the remaining space pushing the last button along?

I've realised that the real issue is buttons won't stretch until you give them an explicit width (ie, width:100%). You still need the table-cells though to constrain that 100% to a 'what will fit' model. You could just set 33% on each button but that won't work if your buttons are being added dynamically (unless you calculate the percentages on the server).
METHOD 1 (doesn't work): Buttons don't expand to fit the row (ie, display:table-cell appears to be ignored).
<div style="display:table;width:200px">
<div style="display:table-row">
<button style="display:table-cell">1</button>
<button style="display:table-cell">2</button>
<button style="display:table-cell">3</button>
</div>
</div>
For IE prior to IE8 you'll need to feed a real table or a compatibility script like IE8-js. The basic concept is easy enough though:
<!--[if ie lt 8]>
<script><!--pseudo-code, not real js-->
for (el in getElementsByTagName('button')) {
if el.style.find('display:table-cell') {
el.innerHTML = '<td><button>'+el.innerHTML+'</button></td>'
}
}
</script>
<![endif]-->
METHOD 2 (works): Hmmm.. Well for whatever reason the display:table-cell style does not work on button elements. I was able to do it with some extra markup though.
<div style="display:table;width:500px;">
<div style="display:table-row">
<div style="display:table-cell"> <button style="width:100%">1938274</button> </div>
<div style="display:table-cell"> <button style="width:100%">2</button> </div>
<div style="display:table-cell"> <button style="width:100%">3</button> </div>
</div>
</div>
I admit it ain't pretty but it will ensure all of the horizontal space is filled. It can be cleaned up a bit by using classes like in this demo I put together. Still, when combined with IE's shortcomings this is probably a case where I'd say ignore the purists and just use a table:
<style>table button {width:100%}</style>
<table style="width:500px;">
<tr> <td><button>1938274</button> <td> <button>2</button> <td> <button>3</button> </tr>
</table>

Similar to Roberts:
HTML
<div id="container">
<button id="one">One</button><button id="two">Two</button><button id="three">Three</button>
</div>
CSS
div#container {
border: solid 1px;
width: 200px;
}
div#container button {
width: 33%;
}
div#container button:last-child {
width: 34%;
}
That doesn't allow for a fluid layout: #container width must be known, then you do the math.
To allow for a fluid layout you need to hop into the world of absolute positioning:
div#container {
border: solid 1px;
width: 50%; /* resize your browser window to see results */
position: relative;
}
div#container button {
position: absolute;
width: 50px;
}
button#one {
top: 0;
left: 0;
}
button#two {
top: 0;
left: 55px;
}
button#three {
width: auto !important; /* get rid of the 50px width defined earlier */
top: 0;
left: 110px;
right: 0px;
}
Watch out for the height of #container. It's gone since all it's children in this example are absolutely positioned--you can see that from the border.

Can't you just set the widths like so...
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>test css button stretch</title>
<style>
#btn_container
{
width: 200px;
}
#btn_container button
{
width: 20%;
}
#btn_container button.stretch
{
width: 58%;
}
</style>
</head>
<body>
<div id="btn_container">
<p>last button stretch...</p>
<button type="button">eat</button>
<button type="button">drink</button>
<button class="stretch" type="button">sleep</button>
<br>
<p>first button stretch...</p>
<button class="stretch" type="button">eat</button>
<button type="button">drink</button>
<button type="button">sleep</button>
<br>
<p>middle button stretch...</p>
<button type="button">eat</button>
<button class="stretch" type="button">drink</button>
<button type="button">sleep</button>
</div>
</body>
</html>
This seems to get the desired effect, is fluid (if the div button container's width is changed or set to a %), and works in IE, Firefox and Opera.
edit: removed the redundant btn class; bumped up the width % for the stretch class; added the doctype. Left the types on, could technically haved removed for just an example, but meh.
#rpflo: the types are in there because my buttons in this example are not submit buttons. If these were part of a form and were submitting, I'd have left them off since the default is type=submit. (W3C HTML BUTTON)

Related

The keyboard pushes a div up & out of the screen

I'm using Ionic 3 to make a website which will be part of another native app in a webview so I don't user cordova or any native plugins.
I have a form with an embedded Google Map View above the elements and here is my HTML :
<div style="height: 40%; width: 100%">
<div id="map_loader" *ngIf="showMapLoader">
<div class="sk-wave">
<div class="sk-rect sk-rect1"></div>
<div class="sk-rect sk-rect2"></div>
<div class="sk-rect sk-rect3"></div>
<div class="sk-rect sk-rect4"></div>
<div class="sk-rect sk-rect5"></div>
</div>
</div>
<div #mapCanvas style="width: 100%; height: 100%;"></div>
</div>
<form (ngSubmit)="submit()" padding>
<ion-list>
......
......
.....
</ion-list>
</form>
and here is my CSS :
#map_loader {
margin:auto;
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100%;
z-index: 1000;
position: absolute;
}
.scroll-content {
top: 38%;
position: absolute;
margin-top: 32px;
}
Now once the user open the website on his phone and start filling the form the keyboard shifts the map out of the screen ( Up ) and it stays that way and a blank empty space shows bellow the form.
Am I doing it right? Is that happening because of my CSS? and what is the best way to make a div takes a specific percentage of the screen height? I tried ion-grid but it seems that it can't help me for this case.
it's bug in ionic, once you focus on any input the keyboard will show up and will add padding-bottom for the scroll-content class to lift the for above the keyboard and it doesn't remove the padding-bottom after you close the keyboard.
I tried to check if I have any JS event on the mobile keyboard but we don't so my work around is to set a fixed padding-bottom for the scroll-content class to prevent changing it on the runtime.
.scroll-content {
padding-bottom: 0 !important;
}
Change in the AndroidManifest.xml file did the trick for me. android:windowSoftInputMode="adjustPan"
Yes, You can avoid this issue by using Ionic grid.You need to set CSS as shown below.
your-page.scss
ion-grid {
min-height: 100%;
}

HTML form overlay on a widget contained in a div

I am a novice when it comes to modern HTML (HTML5/CSS/Ajax/JQuery, etc). I have a web application that is using a Google Earth plugin like tool called Cesium. Like Google Earth, it allows you to view and interact with a global map of the earth. Cesium runs as a widget in a div container. The canvas takes up a whole div element. In my app it takes the entire width and most of the body.
I have a need for a small text search form that exists outside of this div container.
It consists of one form input and a couple of buttons. I would like this to sit on top (overlay) the div container that contains the cesium widget. I would like it to only take up a small section in the upper left corner, overlaying the cesium widget. I would be great if the background, underneath the form input field and buttons were transparent.
Below is a small sample of the HTML and CSS. I know it will involve some CSS but as I said I’m a novice.
Any helpful hints on slick ways for doing this would be appreciated.
Thanks!
body
{
background-color : #000000;
margin : 0;
margin-bottom : 20px;
margin-top : 20px;
width : 100%;
}
.textSearchSection
{
display:inline-block;
float:left;
height : 5%;
padding-top: 5px;
padding-right: 0px;
padding-bottom: 5px;
padding-left: 5px;
width: 500px;
}
.textInputField
{
width : 200px;
}
.map
{
height : 95%;
overflow : hidden;
width : 100%;
}
.button
{
width : 80px;
}
<html>
<head>
<link rel="stylesheet" type="text/css" href="../cesium/Build/Cesium/Widgets/widgets.css">
<script>
var cesiumViewer = null; //declare these here so processTextInputForm() has access to them
</script>
</head>
<body>
<!--I want this to semi transparently overlay the cesiumContainer div, and only take a minumum amount of width-->
<div class="textSearchSection" id="textSearchSection">
<form id="searchForm" name="searcForm">
<input type="text" id="searchText" name="searchText" class="textInputField" onchange="somejavascriptfunction()"/>
<input id="searchButton" type="button" value="Text Search" class="button" onclick="somejavascriptfunction()">
<input id="clearButton" type="button" value="Clear" class="button" onclick="somejavascriptfunction()">
</form>
</div>
<!--This is the div that contains the cesium application-->
<div class="map" id="cesiumContainer"></div>
<script>
cesiumViewer = new CesiumViewer(); //This can't be created until after the cesiumContainer id is declared in the div.
</script>
</body>
</html>
My approach would be to move the textSearchSection so that it nests inside a parent container as a sibling element to cesiumContainer:
<div id="parentContainer">
<div class="map" id="cesiumContainer"></div>
<div class="textSearchSection" id="textSearchSection">...</div>
</div>
Then you can style parentContainer so that it is exactly the same size as cesiumContainer and style textSearchSection with:
#textSearchSection {
position: absolute;
top: 0;
left: 0;
z-index: 12;
}
Actually moving the form div (searchContainer below) into the cesiumContainer div, and using CSS z-index attributes as shown below (searchOverlay set to 1, map set to 0) does the trick. So it is a child of the cesiumContainer div.
.map
{
height : 100%;
overflow : hidden;
width : 100%;
z-index : 0;
}
.searchOverlay
{
left : 10;
position : relative;
top : 33;
width : 50%;
z-index : 1;
}
<div class="map" id="cesiumContainer">
<div class="searchOverlay" id="searchContainer">
<input class="textSearch" id="searchText" name="searchText" type="text" onchange="processTextInputForm()"/>
<input class="button" id="searchButton" type="button" value="Search" onclick="processTextInputForm()" onkeydown="searchEnter(event)">
<input class="button" id="searchButton" type="button" value="Clear" onclick="clearResults()">
</div>
</div>

Internet Explorer 8 doesn't apply display inline and block correctly

In short.
I have something like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<html>
<head>
<style>
.vertical_panel > .fields > .item {
display: block;
background-color: #344;
}
.horizontal_panel > .fields > .item {
display: inline;
background-color: #FAE;
}
.item {
width: 100px;
height: 50px;
margin: 2px;
}
.fields {
margin: 0px;
padding: 0px;
}
#specialSpan {
display: table;
margin: 0px auto;
}
</style>
</head>
<body>
<div class="horizontal_panel" id = "specialSpan" style="width: 300px; height: auto;">
<fieldset class="fields">
<span class="vertical_panel item" style="width: 300px; height: auto;">
<fieldset class="fields">
<div class="item">
<span>text</span>
</div>
<div class="item">
<span>text</span>
</div>
</fieldset>
</span>
<div class="item">
<span>text</span>
</div>
<div class="item">
<span>text</span>
</div>
</fieldset>
</div>
</body>
</html>
It's an approximation to my code structure. There are more elements inside the fields. So, I have a javascript function which toggles class of panels.
The problem is: I have correct selectors, correct values of style are set(display), but Internet Explorer 8 does not apply it correctly. The items does not change their direction if I call that function. Under “does not change direction” I mean that items does no rendered as display: block or display: inline.
There is a key part: if I open debug tools and enter display: inline for instance manually for panels, almost everything looks fine. But if I have correct view before manual style changes and I have changed the style, I can't change view back to normal in ordinary way — with call of function.
The function is something like:
function SetPanelOrientation(panel) {
// this attribute doesn't exit in example but actually exist in project's code
// and always correct
var isVertical = panel.getAttribute("IsVertical");
if (isVertical == '0') {
$(panel)
.removeClass('vertical_panel')
.addClass('horizontal_panel');
} else {
$(panel)
.removeClass('horizontal_panel')
.addClass('vertical_panel');
}
};
I can see in debugger tools that class changed, but view doesn't change. I've tried many combinations with block and inline-block but have not found working combination.
Due to the doctype you are using, you are in quirks mode, and IE will perform as if it were 1998 all over again. New web pages should not be using that doctype since 1999.
The only way around this is to set the element's CSS properties to how you want them to be versus how other browsers are correctly displaying them.
There was nothing in doctype, nor in property values. Set styles with jquery instead of css file helps.

IE6/7 - CSS popup within a - tr td

I am struggling with a CSS popup and hoping someone can help.
We have various tds that have this popup within their cell, in firefox, chrome etc (the usual) it works fine. However in the older browsers below IE8 it is having problems.
It seems that the :hover is lost when the mouse moves out of the cell, even if it moves over the popup area (which is situated just below the cell). You are probably saying yes that is what it should be doing but a child element of the parent that is hovered in firefox keeps the :hover class on the parent.
The popup div is positioned absolute and given a margin-left of -999px; (This is ok)
On :hover of the parent div element the margin-left is set to -125px (half of width of popup div, so it is centered - also ok)
All this is fine and works perfect in modern browsers as previously stated.
HTML Snippet
<tr>
<td>
<div class="tooltip">
<span class="events">CONTENT</span>
</div>
</td>
<td>
<div class="tooltip">
<span class="events">CONTENT</span>
</div>
</td>
<td>
<div class="tooltip">
<span class="events">CONTENT</span>
</div>
</td>
<td>
<div class="tooltip">
<span class="events">CONTENT</span>
</div>
</td>
<td>
<div class="tooltip">
<span class="events">CONTENT</span>
</div>
</td>
</tr>
CSS Thusfar
#page-content .block_calendar_month { overflow: visible; }
.tooltip { border-bottom: 1px dotted #000000; color: #000000; outline: none; cursor: help; text-decoration: none; }
.tooltip span { margin-left: -999em; position: absolute; }
td.day:hover { background-color: #fbf16b; }
.tooltip:hover span { font-size: 12px; position: absolute; left: 0em; z-index: 5000; top: 1em; margin-left: -125px; width: 250px; }
.tooltip:hover span div { }
.events {padding: 0.8em 1em; }
Hope someone can give me some advice, as I have lost a few hours trying to solve this.
I haven't touched IE6 in a while, but from working with IE7 I can tell you it does some funky stuff with tables and z-index. I found that the best solution when working with tooltip is to not use tables. Why not strip out the table code and have:
<div class="tooltip">
<span class="events">CONTENT</span>
</div>
Also, I am not sure what plugin you are using (in fact, it looks like you aren't using any), But if you use JQuery Tools tooltip plugin, you can set the popup's offset distance as a JSON parameter. Read more http://jquerytools.org/demos/tooltip/dynamic.html.
If you are going to keep the current implementation, I'd recommend toggling between display:block and display:none for the tooltip.

CSS alignment of spans, inputs, and buttons

I'm looking for a way to align a number of elements (spans, inputs, and buttons) such that despite their differing sizes, their vertical mid point is on the same horizontal line:
How do I achieve this in CSS? Here's the HTML file to play with:
<html>
<head>
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.3.0/build/cssreset/reset-min.css">
<style>
.content { font-size: 18px; border: 1px dotted blue; }
.content input, .content button { font-size: 40px; float: left; }
.label { border: 1px dotted red; float: left; }
.clear { clear: both; }
</style>
</head>
<body>
<div class="content">
<span class="label">Label: </span><input type="text">
<span class="label">More text: </span><input type="text">
<button type="submit">Submit Me</button>
<div class="clear"></div>
</div>
</body>
</html>
Set the main div's line-height: height of tallest element in px, then set vertical-align: middle. You may have to set display:inline or display:inline-block on the subelements as well.
That should work.
As others (David Nguyen and thirtydot) have said, adding vertical-align:middle; will accomplish the effect you're after so long as you get rid of the floats that are currently in your code. Adding display:inline-block; will let you have better control over the dimensions, and I don't know if you were planning on it, but I'd definitely swap out your <span class="label"> for actual <label> tags.
Your span, input and button need the property:
vertical-align:middle;display:inline

Resources