Vertical align in Materialize CSS - css

I'm trying to center a form on the screen using Materialize. I tried everything, but I can not do it for all resolutions and also be responsive. In certain resolutions it works perfect, but when you add or remove controls (), in some resolutions it looks good, in others it goes wrong. Some help? Thank you!
Code
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Test</title>
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.1/css/materialize.min.css">
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<style>
.card {
margin: 1rem 0 1rem 0 !important;
}
.card .card-title {
background-color: #26a69a;
}
.card-title span {
display: block;
text-align: center;
padding: 5px;
}
.card-content {
padding: 30px;
}
.valign {
width: 100%;
}
.valign-wrapper {
width: 100%;
background: url("http://vunature.com/wp-content/uploads/2016/10/trees-woods-tree-nature-path-forest-landscape-amazing-pictures-of-wallpapers.jpg") no-repeat;
}
.circle {
display: block;
margin: 10px auto;
}
</style>
</head>
<body>
<header class="navbar-fixed">
<nav class="top-nav">
<div class="nav-wrapper grey darken-3">
<a class="brand-logo center" href="#">Logo</a>
<ul class="right">
<li>
Register
</li>
<li>
Log in
</li>
</ul>
</div>
</nav>
</header>
<div class="valign-wrapper">
<div class="valign">
<div class="container">
<div class="card">
<div class="card-title white-text">
<span>Register</span>
</div>
<div class="card-content">
<p>
Text text text text text text text text text text text text text text text text text text text text text text text
</p>
<form action="#" enctype="multipart/form-data" id="externalRegisterForm" method="post" novalidate="novalidate">
<div class="validation-summary-valid text-danger" data-valmsg-summary="true">
<ul>
<li style="display:none" />
</ul>
</div>
<div>
<section style="position: absolute; left: 50%; transform: translateX(-50%); display: none;">
<input type="submit" class="btn" value="Sign In">
<input type="submit" class="btn" value="x">
</section>
<img class="circle" src="https://images.google.com/images/branding/googleg/1x/googleg_standard_color_128dp.png" width="128" height="128" alt="">
</div>
<div class="row">
<div class="input-field col s12 m4 l4 xl4">
<input class="validate" data-val="true" data-val-required="El campo Nombre de usuario es obligatorio." id="UserName" name="UserName" type="text" />
<label for="UserName" class="active">Username</label>
</div>
<div class="input-field col s12 m4 l4 xl4">
<input class="validate" data-val="true" data-val-required="El campo Nombre(s) es obligatorio." id="Name" name="Name" type="text" />
<label for="Name" class="active">Name</label>
</div>
<div class="input-field col s12 m4 l4 xl4">
<input class="validate" data-val="true" data-val-required="El campo Apellido(s) es obligatorio." id="LastName" name="LastName" type="text" />
<label for="LastName" class="active">Last name</label>
</div>
<div class="input-field col s12">
<input class="validate" data-val="true" data-val-required="El campo Email es obligatorio." id="Email" name="Email" type="text" />
<label for="Email" class="active">Email</label>
</div>
</div>
</form>
</div>
<div class="card-action">
<input type="submit" class="btn" value="Sign In" form="externalRegisterForm" />
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.1/js/materialize.min.js"></script>
<script type="text/javascript">
$(function() {
$('.button-collapse').sideNav();
});
</script>
</body>
</html>
EDIT
https://image.ibb.co/h7ESBk/1.jpg
See the white line below. It is a resolution of 1366x768. If you add more input, it looks "normal" and responsive. But if you delete an input you can see how the white background is larger.

Based on the feedback you gave in the comments, I think all you need is to add min-height: calc(100vh - 64px); to .valign-wrapper.
That will fill the whole page. You may have to modify the background property as well to make sure the image fills up the whole element, I couldn't load the image so I couldn't test that. The vertical alignment is already working.
Before:
After:

These UI libraries have been offering a 'grid' solution to this for some time now. However, I find vanilla CSS flexbox (whether hard coded or scripted with JS in the browser) to be super easy for centering both ways.
As for breakpoints, you will need them. I went thru all this on this here project https://github.com/rhroyston/firebase-v4-auth. Feel free to copy& paste as you need. Snippet below.
//ON LOAD INITIALLY ASSUME PHONE
var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
doc.getElementById("title").style.display = "flex";
doc.getElementById("title-right").style.display = "none";
if (width >= 840) {
//IT'S A DESKTOP
doc.getElementById("title").style.display = "none";
doc.getElementById("title-right").style.display = "flex";
}
else if (width >= 480) {
//IT'S A TABLET
doc.getElementById("title").style.display = "flex";
doc.getElementById("title-right").style.display = "none";
}
//ON RESIZE INITIALLY ASSUME PHONE
window.addEventListener("resize", resizeThrottler, false);
var resizeTimeout;
function actualResizeHandler() {
// assuming device is a phone
doc.getElementById("title").style.display = "flex";
doc.getElementById("title-right").style.display = "none";
if (window.innerWidth >= 840) {
//device is a desktop
doc.getElementById("title").style.display = "none";
doc.getElementById("title-right").style.display = "flex";
}
else if (window.innerWidth >= 480) {
//device is a tablet
doc.getElementById("title").style.display = "none";
doc.getElementById("title-right").style.display = "flex";
}
}
function resizeThrottler() {
// ignore resize events as long as an actualResizeHandler execution is in the queue
if (!resizeTimeout) {
resizeTimeout = setTimeout(function() {
resizeTimeout = null;
actualResizeHandler();
// The actualResizeHandler will execute at a rate of 15fps
}, 66);
}
}

Related

Bootstrap 4: validation breaks styling on inline form elements?

I am trying to validate an inline form field, with Bootstrap 4.
When validation is triggered, the inline form field jumps in width. Here is a fiddle (just click Enter without entering a value, to see the problem): https://jsfiddle.net/aq9Laaew/213418/
How can I fix this?
This is my HTML:
<form class="form-inline needs-validation" id="form-stage1" novalidate>
<label class="sr-only" for="stage1-amount">Amount in thousands</label>
<div class="input-group mb-1 mr-sm-1">
<div class="input-group-prepend"><div class="input-group-text">£</div></div>
<input type="number" step="5000" min="0" class="form-control" id="stage1-amount" required>
<div class="invalid-feedback">Please enter an amount to proceed</div>
</div>
<button type="submit" class="btn btn-secondary mb-1">Enter</button>
</div>
</form>
And this is my JavaScript:
d3.select('#form-stage1').on('submit', function(e) {
d3.event.preventDefault();
d3.event.stopPropagation();
d3.select(this).attr('class', 'was-validated');
});
Try this :
var form = document.getElementById('form-stage1');
d3.select('#form-stage1').on('submit', function(e) {
d3.event.preventDefault();
d3.event.stopPropagation();
d3.select(this).attr('class', 'form-inline was-validated');
$(".invalid-feedback").show();
if (form.checkValidity() !== false) {
d3.select('#stage1-results').style('display', 'inline-block');
var val = d3.select('#stage1-amount').property("value");
d3.select('#stage1-output').text(formatPounds(val));
var percentile = getPercentile('property', val)
d3.select('#stage1-lower').text(percentile);
d3.select('#stage1-higher').text(100-percentile-1);
}
});
.row {
background: #f8f9fa;
margin-top: 20px;
}
.col {
border: solid 1px #6c757d;
padding: 10px;
}
.form-control{
width:auto!important;
flex:0!important;
}
.input-group{
width:auto!important;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<!--
Bootstrap docs: https://getbootstrap.com/docs
-->
<div class="container">
<form class="form-inline needs-validation" id="form-stage1" novalidate>
<label class="sr-only" for="stage1-amount">Amount in thousands</label>
<div class="input-group mb-1 mr-sm-1">
<div class="input-group-prepend"><div class="input-group-text">£</div></div>
<input type="number" step="5000" min="0" class="form-control" id="stage1-amount" required>
</div>
<button type="submit" class="btn btn-secondary mb-1">Enter</button>
<div class="invalid-feedback">Please enter an amount to proceed</div>
</div>
</form>
</div>
https://jsfiddle.net/aq9Laaew/215767/

leading specialcharacters appear as trailing while using direction rtl

I am using direction property for a label. My label contains windows style directory paths(the ones with backslashes). The purpose of using direction:rtl; is to show the end part(or rather filenames) of the path, but the problem is I am getting the leading backslashes as trailing which might confuse the user. How can I prevent this.
Link to fiddle: http://jsfiddle.net/pguwo67m/2/
This is what I am working on:
AddenduM
I have noticed that this problem also arises for other leading special characters as well.
Fiddle: http://jsfiddle.net/6L1az99t/1/
How about this which will remove part of the path when it is too long:
NodeList.prototype.forEach = Array.prototype.forEach;
window.onload = function () {
adjustWidths();
};
function adjustWidths() {
// get all label elements
var labels = document.querySelectorAll('.path').forEach(function (lab) {
var width = lab.getBoundingClientRect().width;
if (width >= 260) {
var path = lab.innerHTML;
var pathArr = path.split("\\");
var newpath = pathArr[0] + '\\...\\' + pathArr[pathArr.length - 1];
lab.title = path;
lab.innerHTML = newpath;
}
});
}
#wrapper {
width: 300px;
border: 1px solid blue;
}
input {
width: 20px;
}
<div id="wrapper">
<div>
<input type="checkbox" />
<label class="path">development\productinfo.php</label>
<div style="clear:both;"></div>
</div>
<div>
<input type="checkbox" />
<label class="path">development\application\models\cron\dropshipmodel.php</label>
<div style="clear:both;"></div>
</div>
<div>
<input type="checkbox" />
<label class="path">develoment\application\controllers\cron\dropship.php</label>
</div>
<div>
<input type="checkbox" />
<label class="path">development\application\models\cron\dropshipmodel.php</label>
<div style="clear:both;"></div>
</div>
<div>
<input type="checkbox" />
<label class="path">develoment\application\controllers\cron\dropship.php</label>
<div style="clear:both;"></div>
</div>
<div>
<input type="checkbox" />
<label class="path">development\productinfo.php</label>
<div style="clear:both;"></div>
</div>
<div>
<input type="checkbox" />
<label class="path">development\application\models\cron\dropshipmodel.php</label>
<div style="clear:both;"></div>
</div>
<div>
<input type="checkbox" />
<label class="path">develoment\application\controllers\cron\dropship.php</label>
</div>
</div>
Check this.
Changes -
1. Add text in span inside label
2. Set width of span and display as block.
Thats it.
label {
direction: rtl;
float: left;
overflow-x:hidden;
white-space: nowrap;
}
label span{
width:150px !important;
display:block;
}
input {
float: left;
}
<div>
<input type="checkbox">
<label class="alterable"><span> \\\\development\productinfo.php</span></label>
<div style="clear:both;"></div>
</div>
<div>
<input type="checkbox">
<label class="alterable"><span>\development\application\models\cron\dropshipmodel.php</span></label>
<div style="clear:both;"></div>
</div>
<div>
<input type="checkbox">
<label class="alterable"><span>\develoment\application\controllers\cron\dropship.php</span></label>
<div style="clear:both;"></div>
</div>
<div>
<input type="checkbox">
<label class="alterable"><span>This is normal text, i want to display end part of a string</span></label>
<div style="clear:both;"></div>
</div>
Thnaks.

show spinner for input type number in HTML5

I am working with HTML5, I am using an numeric control (input type="number"). By default I need the spinner (up & down arrows) to be visible in the control, right now on hover it is visible.
Can I achieve it by CSS? Or is there any other way?
You can achieve this using the pseudo classes -webkit-inner-spin-button and -webkit-outer-spin-button. Be aware that this trick will work only in Webkit based browsers, such as Chrome.
Example:
/* Always */
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
opacity: 1;
}
Since you want to display when hover event is triggered, the previous example would be:
/* On hover */
input[type=number]:hover::-webkit-inner-spin-button,
input[type=number]:hover::-webkit-outer-spin-button {
opacity: 1;
}
Check this snippet to see an working example.
If you want to expand your functionality to other browsers, you will need to create an widget. The fastest way is using the jQuery UI Spinner widget.
Input type number does not show increase/decrease buttons on iPhone
Its built into jQuery UI - http://jqueryui.com/spinner/
Or see an example here: http://codepen.io/gmkhussain/pen/mgoZjK
 
Hopefully this solution helps you or someone else out there with this problem.
console.log("Thank You Jesus!");
$(document).ready(function() {
/* alert("ready");//Thank You Saviour */
var minusButton = $(".spinnerMinus"); //to aquire all minus buttons
var plusButton = $(".spinnerPlus"); //to aquire all plus buttons
//Handle click
minusButton.click(function() {
trigger_Spinner($(this), "-", {
max: 10,
min: 0
}); //Triggers the Spinner Actuator
}); /*end Handle Minus Button click*/
plusButton.click(function() {
trigger_Spinner($(this), "+", {
max: 10,
min: 0
}); //Triggers the Spinner Actuator
}); /*end Handle Plus Button Click*/
});
//This function will take the clicked button and actuate the spinner based on the provided function/operator
// - this allows you to adjust the limits of specific spinners based on classnames
function trigger_Spinner(clickedButton, plus_minus, limits) {
var valueElement = clickedButton.closest('.customSpinner').find('.spinnerVal'); //gets the closest value element to this button
var controllerbuttons = {
minus: clickedButton.closest('.customSpinner').find('.spinnerMinus'),
plus: clickedButton.closest('.customSpinner').find('.spinnerPlus')
}; //to get the button pair associated only with this set of input controls//THank You Jesus!
//Activate Spinner
updateSpinner(limits, plus_minus, valueElement, controllerbuttons); //to update the Spinner
}
/*
max - maxValue
min - minValue
operator - +/-
elem - the element that will be used to update the count
*/ //Thank You Jesus!
function updateSpinner(limits, operator, elem, buttons) {
var currentVal = parseInt(elem.val()); //get the current val
//Operate on value -----------------
if (operator == "+") {
currentVal += 1; //Increment by one
//Thank You Jesus ----------------
if (currentVal <= limits.max) {
elem.val(currentVal);
}
} else if (operator == "-") {
currentVal -= 1; //Decrement by one
//Thank You Jesus ----------------
if (currentVal >= limits.min) {
elem.val(currentVal);
}
}
//Independent Controllers - Handle Buttons disable toggle ------------------------
buttons.plus.prop('disabled', (currentVal >= limits.max)); //enable/disable button
buttons.minus.prop('disabled', (currentVal <= limits.min)); //enable/disable button
}
.spinnerVal {
text-align: center;
}
.customSpinner {
display: flex;
margin-bottom: 10px;
}
/*Apply individual Styles to one*/
.spinner-roundVal {
margin: auto 2px;
border-radius: 20px !important;
width: auto !important;
}
.spinner-roundbutton {
border-radius: 100px !important;
}
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" type="text/css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
</head>
<body>
<!-- God is good. -->
<div class="container">
<h4 style="text-align:center;margin-bottom:50px;margin-top:5%;margin-bottom:5%;">
Simple Bootstrap Spinners
</h4>
<div class="row" style="
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
">
<div class="col-lg-4">
<!--Input Form1-->
<div class="input-group customSpinner <!--Thank You Jesus!-->">
<div class="input-group-prepend">
<button class="btn btn-primary spinnerbutton spinnerMinus spinner-roundbutton">
<span class = "fa fa-minus"></span>
</button>
</div>
<input type="text" readonly value="0" class="form-control spinnerVal spinner-roundVal" />
<div class="input-group-append">
<button class="btn btn-primary spinnerbutton spinnerPlus spinner-roundbutton">
<span class = "fa fa-plus"></span>
</button>
</div>
</div>
</div>
<div class="col-lg-4">
<!--Input Form2-->
<div class="input-group customSpinner <!--Thank You Jesus!-->">
<div class="input-group-prepend">
<button class="btn btn-danger spinnerbutton spinnerMinus">
<span class = "fa fa-minus"></span>
</button>
</div>
<input type="text" readonly value="0" class="form-control spinnerVal" />
<div class="input-group-append">
<button class="btn btn-danger spinnerbutton spinnerPlus">
<span class = "fa fa-plus"></span>
</button>
</div>
</div>
</div>
<div class="col-lg-4">
<!--Input Form3-->
<div class="input-group customSpinner <!--Thank You Jesus!-->">
<div class="input-group-prepend">
<button class="btn btn-warning spinnerbutton spinnerMinus">
<span class = "fa fa-minus"></span>
</button>
</div>
<input type="text" readonly value="0" class="form-control spinnerVal" />
<div class="input-group-append">
<button class="btn btn-warning spinnerbutton spinnerPlus">
<span class = "fa fa-plus"></span>
</button>
</div>
</div>
</div>
<div class="col-lg-4">
<!--Input Form4-->
<div class="input-group customSpinner <!--Thank You Jesus!-->">
<div class="input-group-prepend">
<button class="btn btn-success spinnerbutton spinnerMinus">
<span class = "fa fa-minus"></span>
</button>
</div>
<input type="text" readonly value="0" class="form-control spinnerVal" />
<div class="input-group-append">
<button class="btn btn-success spinnerbutton spinnerPlus">
<span class = "fa fa-plus"></span>
</button>
</div>
</div>
</div>
</div>
</div>
</body>
<!-- God is good. -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy"></script>
</html>
More easy and beautiful if you has vue.js v-money-spinner :)
DEMO

alternative for css float and clear with ie7

I have a page with this elements:
<body>
<div class="C2">
<div class="Ban">
<div class="blockWithLabel position BankCode">
<span>BankCode</span>
<br />
<input type="text"/>
</div>
<div class="blockWithLabel position BranchCode">
<span>BranchCode</span>
<br />
<input type="text" style="width:500px"/>
</div>
<div class="blockWithLabel position AccountNumber">
<span>AccountNumber</span>
<br />
<input type="text"/>
</div>
<div class="blockWithLabel position CheckDigits">
<span>CheckDigits</span>
<br />
<input type="text"/>
</div>
<div class="blockWithLabel position BankName">
<span>BankName</span>
<br />
<input type="text"/>
</div>
<div class="position validator">
<div class="validator">VALIDATOR</div>
</div>
</div>
</div>
</body>
I want to apply this style:
.Ban { overflow:hidden }
div.blockWithLabel { display:inline-table; overflow:none; }
.C2 { background-color: blue; }
.C2 div.blockWithLabel { background-color:yellow; margin:2px;}
.C2 div.position { float:left}
With all browsers, I have (if the width of the screen is enough big) 6 elements in the same line
Now, I want to make breaks using
.C2 div.position.AccountNumber, .C2 div.position.validator { clear:left }
The problem is that with IE7, AccountNumber appears in a new line, but the next elements CheckDigit and BankName doesn't appear in the same line but in the previous !!
How can I fix it ?
use conditional comments for IE7
<!--[if lte IE 7]>
<style type="text/css">
/* hide other layout for other browsers by
setting display to none
*/
.C2 {
display:none;
}
</style>
Use ie7 formatting here with tables instead of divs.
<table>
<TR>
<T...................
<![endif]-->

Cannot center span element

I've got three items on the top of my web page. I expect them to be located left, center, and right. However, that one in the center is a bugger (partially because it's created late in the game). I've tried the auto margin tricks with no luck. I've tried relative positioning but can't get it perfectly centered (and it draws on its neighbors). In the full code below, can you get the "showInMiddle" centered? You need to click the login button for that item to show up. Ideally, the items would wrap if the page was too narrow but still maintain their alignment (rather than drawing on top of each other or all on the left).
<!DOCTYPE html>
<html>
<head>
<title>This is dumb</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="http://knockoutjs.com/js/knockout-2.1.0.js"></script>
</head>
<body style="font-family: 'Segoe UI'; margin: 5px 20px;">
<header style="width: 100%">
<h4 id="showOnLeft" style="font-size: 1.1em; display: inline;">I'm the title</h4>
<span id="showInMiddle" data-bind="visible: LoggedIn">
I'm supposed to be in the middle with my two buttons.
<button>B1</button>
<button>B2</button>
</span>
<div id="showOnRight" style="display: inline; float: right">
<form id="someLoginForm" style="display: inline;" data-bind="visible: !LoggedIn(), submit: login" action="" method="post">
<input type="text" placeholder="Username" />
<input type="password" placeholder="Password" />
<input type="submit" value="Login" />
</form>
<form id="someLogoutForm" style="display: inline;" data-bind="visible: LoggedIn(), submit: logout" action="" method="post">
<span>Howdy</span>
<input type="submit" value="Logout" />
</form>
</div>
<nav><hr/></nav>
</header>
<script type="text/javascript">
function LoginViewModel() {
var self = this;
self.LoggedIn = ko.observable(false);
self.login = function (formElement) { self.LoggedIn(true); };
self.logout = function (formElement) { self.LoggedIn(false); };
}
ko.applyBindings(new LoginViewModel());
</script>
</body>
</html>
You cannot center a span because it's an inline element which doesn't know its width by default.
You can simply replace span with div like this (watch the inline CSS):
<div id="showInMiddle" data-bind="visible: LoggedIn" style="text-align:center ">
I'm supposed to be in the middle with my two buttons.
<button>B1</button>
<button>B2</button>
</div>
This is quick - I am off to go home. Try adjusting the width where the login form is concerned. You need to be aware that the total of floatdiv should never exceed the total of container or it will go wrong.
<!DOCTYPE html>
<html>
<head>
<title>
This is dumb
</title>
<style>
#container {
width:900px;
margin: auto 0;
overflow: auto;
}
.floatdiv {
float:left;
margin:0;
}
</style>
</head>
<body style="font-family: 'Segoe UI'; margin: 5px 20px;">
<div id="container">
<div class="floatdiv" style="font-size: 1.1em; width:200px">
I'm the title
</div>
<div class="floatdiv" id="showInMiddle" data-bind="visible: LoggedIn" style="text-align:center; width:300px ">
<button>
B1
</button>
<button>
B2
</button>
</div>
<div class="floatdiv" id="showOnRight" style="width:300px; float:right; text-align:right">
<form id="someLoginForm" style="" data-bind="visible: !LoggedIn(), submit: login" action="" method="post">
<input type="text" placeholder="Username" />
<input type="password" placeholder="Password" />
<input type="submit" value="Login" />
</form>
<form id="someLogoutForm" style="" data-bind="visible: LoggedIn(), submit: logout" action="" method="post">
<span>
Howdy
</span>
<input type="submit" value="Logout" />
</form>
</div>
</header>
</div>
</body>
</html>
It ends up that this works flawlessly when you use a table. Who knew?
<!DOCTYPE html>
<html>
<head>
<title>This is dumb</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="http://knockoutjs.com/js/knockout-2.1.0.js"></script>
<style type="text/css">
table, tr, td, h4, div { margin: 0px; padding: 0px; }
</style>
</head>
<body style="font-family: 'Segoe UI'; margin: 5px 20px;">
<header style="width: 100%">
<table style="width: 100%; border-width: 0px;">
<tr>
<td><h4 id="showOnLeft" style="font-size: 1.1em;">I'm the title</h4></td>
<td>
<div id="showInMiddle" data-bind="visible: LoggedIn" style="text-align: center;">
I'm supposed to be in the middle with my two buttons.
<button>B1</button>
<button>B2</button>
</div>
</td>
<td>
<div id="showOnRight" style="text-align: right;">
<form id="someLoginForm" style="display: inline;" data-bind="visible: !LoggedIn(), submit: login" action="" method="post">
<input type="text" placeholder="Username" />
<input type="password" placeholder="Password" />
<input type="submit" value="Login" />
</form>
<form id="someLogoutForm" style="display: inline;" data-bind="visible: LoggedIn(), submit: logout" action="" method="post">
<span>Howdy</span>
<input type="submit" value="Logout" />
</form>
</div>
</td>
</tr>
</table>
<nav><hr/></nav>
</header>
<script type="text/javascript">
function LoginViewModel() {
var self = this;
self.LoggedIn = ko.observable(false);
self.login = function (formElement) { self.LoggedIn(true); };
self.logout = function (formElement) { self.LoggedIn(false); };
}
ko.applyBindings(new LoginViewModel());
</script>
</body>
</html>

Resources