Height of tabContainers in dojo - css

I am using a Dojo tabContainer.
The quick question: do you have to specify the widget size in pixel in the CSS, if you are dealing with a Dojo container?
From what I am seeing, the only way to get a TabContainer to actually show is by giving it an absolute size via CSS.
UPDATE: I figured out that the elements body and html were missing the height attribute, and therefore it was computed to 0. So, now if I set them as 100% I will display the form... but, it will be huge! (as long as the page). The idea is to set its height to auto, so that it's "as long as it needs to be"... is that even possible?
In my HTML I have something like:
...
<body>
<div id="loginForm"> </div>
</body>
...
I then have then in the code:
require(["app/widgets/LoginForm"], function( loginForm){
// Create the "application" object, and places them in the right spot.
loginForm = new LoginForm( {} , 'loginForm');
loginForm.startup();
});
LoginForm is a simple template-based widget with the following template:
<div data-dojo-attach-point="tabContainer" data-dojo-type="app.TabFading" data-dojo-props="tabPosition:'top'" style="height:100%">
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-attach-point="loginPane" data-dojo-props="title: 'Login'">
<form data-dojo-type="dijit.form.Form" data-dojo-attach-point="loginForm" method="POST">
<label for="${id}_login">Login</label>
<input name="login" id="${id}_login" data-dojo-attach-point="login" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="required:true"/>
<label for="${id}_password">Password</label>
<input name="password" id="${id}_password0" data-dojo-attach-point="password" data-dojo-type="app.ValidationPassword" />
<input type="submit" data-dojo-attach-point="button" data-dojo-type="app.BusyButton" label="Login!" />
</form>
</div>
</div>
</div>
The CSS is as basic as it gets:
#loginForm {
width: 300px;
margin: 0 auto;
padding: 20px;
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
/*** Background Gradient - 2 declarations one for Firefox and one for Webkit ***/
background: -moz-linear-gradient(19% 75% 90deg,#FCFCFC, #CCCCCC);
background:-webkit-gradient(linear, 0% 0%, 0% 100%, from(#FCFCFC), to(#CCCCCC));
/*** Shadow behind the box ***/
-moz-box-shadow:0px -5px 300px #a9a0a0;
-webkit-box-shadow:0px -5px 300px #a9a0a0;
}
body {
background-color: #fcfcfc;
font: 9pt/1.5em Helvetica Neue, Helvetica, Arial, sans-serif;
margin: 0 0;
}
The only way I have to make the TabContainer actually appear is to have height:300px in it -- otherwise, the computed height is 0.
Is this how it's meant to be? Or am I doing something wrong?

If you set the property doLayout to false on either the ContentPane or the TabContainer it should automatically size the height to the content. The doLayout property of the dijit layout containers defaults to true, which then requires a specific height to be applied to it.

Just set the tab container to doLayout="false"
Detail example is here : https://dojotoolkit.org/reference-guide/1.7/dijit/layout/TabContainer.html#examples

Related

web page rendering mystery: button too wide

I have a document that contains HTML and CSS.
It is being rendered in a way that I don't understand.
I have observed this with 3 different browsers
(Firefox, Chromium, and Opera),
so it is unlikely to be a browser bug.
The following image shows what I expect to see.
(Before taking this screenshot, I used my
browser's zoom function to zoom in.)
The following image shows what I actually see.
(Again, I zoomed in before capturing this image.)
The upper group of buttons is as I expect.
However,
in the lower group of buttons,
the "y" button is wider than I expect.
I'll show the markup of the document in a moment,
but first I want to talk about it.
The difference between the two "y" buttons
is that the upper one has the
class button-wider-1,
whereas the lower one has the class button-wider-2.
In the CSS, each of these classes sets a width,
using a calc expression.
The difference between the two expressions
is that the expression for button-wider-2
adds the width of an "x" button,
which means that I expect
the right-hand border of the "y" button to
align with the
right-hand border of the right-hand "x" button.
However,
as you can see from the second image above, that doesn't happen.
My question is: why?
Here is the document (which is completely self-contained):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS Question</title>
<style type="text/css">
.mystery,
.mystery *
{
padding: 0;
border: 0;
margin: 0;
}
.button-container
{
background-color: #f77;
padding: 1rem;
margin: 1rem;
}
.button
{
float: left;
font-family: 'Courier', monospace;
width: 3.1rem;
height: 2rem;
border: solid black 2px;
margin-right: 0.7rem;
}
.button-wider-1
{
/*
The following 'calc' expression adds up:
* the standard width of a button (i.e. the width
of an element with class "button");
* the width of a button's border;
* the horizontal margin (i.e. the value of margin-right for a
button);
* the width of a button's border;
*/
width: calc(
3.1rem +
2px +
0.7rem +
2px
);
}
.button-wider-2
{
/*
The following 'calc' expression is the same as the previous,
except that there is an extra term at the end, the standard width
of a button.
*/
width: calc(
3.1rem +
2px +
0.7rem +
2px +
3.1rem
);
}
</style>
</head>
<body>
<div class="mystery">
<div class="button-container">
<button type="button" class="button">x</button>
<button type="button" class="button">x</button>
<div style="clear: both"></div>
<button type="button" class="button button-wider-1">y</button>
<div style="clear: both"></div>
</div>
<div class="button-container">
<button type="button" class="button">x</button>
<button type="button" class="button">x</button>
<div style="clear: both"></div>
<button type="button" class="button button-wider-2">y</button>
<div style="clear: both"></div>
</div>
</div>
</body>
</html>
I have observed this unexpected rendering in the following 3 browsers
(all on Linux):
Firefox ESR 52.5.2
Chromium 57.0.2987.98
Opera 50.0.2762.58 (the latest version of
Opera at time of writing)
You are calculating the width of your buttons by adding their width and their border-width. However, now browsers default to border-box for property box-sizing on buttons.
https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
A quick fix is to add box-sizing: content-box; to .button so that reality matches what you expect about calculating widths.
Another fix would be to remove the two +2px from the second calc(); borders being part of the width of a button, you only want your second button to be "2 buttons + 1 margin". The first button is unchanged because you actually want it to be "1 button + 1 margin + 2 borders" so it'll work with both border-box and content-box.

Using pseudo-element ::before to display low opacity background image in Div

Adding a background image to a DIV. Image must have low opacity, but the other elements in the DIV must have normal opacity.
jsFiddle of my code
I was following this SO answer (answer's Codepen is here).
However, I must be doing something wrong (knowing me, something painfully obvious). Can anyone spot my mistake, or suggest the solution?
In case my above jsFiddle someday disappers, here is my code:
HTML:
<div id="loginFormDIV">
<div id="headerDIV">
<p>Login Please</p>
</div>
<div id="formDIV">
<div id="fd_loginDIV">
<p>Login ID:</p>
<input id="fd_login" type="text" />
</div>
<div id="fd_pwordDIV">
<p>Password:</p>
<input id="fd_pword" type="password" />
</div>
<div id="fd_submitDIV">
<input id="fd_submit" type="button" value="Submit" />
</div>
</div>
</div><!-- #loginForm -->
CSS:
* { margin: 0; padding: 0; outline: 0 }
html {min-height:100%;margin-bottom:1px;font-size: 62.5%;background:#eaeaea;}
h1, h2, h3 {color:#f1f0ee;font-family:Segoe UI Light, Arial, Verdana, Geneva, sans-serif;font-family:"Segoe UI light","Segoe UI";}
h1 {font-size:2.5em;font-weight:normal;border-bottom:0px solid #c6beaa;padding-bottom:25px;}
#loginFormDIV {height:250px;width:400px;position:absolute;left:30%;font-size:1.6em;z-index:10;}
#headerDIV {height:40px;width:100%;background:white;}
#formDIV {height:210px;width:100%;position:relative;}
#formDIV:after{content:'';display:block;position:absolute;top:0;left:0;background:url(http://placekitten.com/400/250);background-size:cover;opacity:0.2;z-index:-2;}
#fd_loginDIV {height:35%;width:80%;margin:0 auto;border:1px solid blue;}
#fd_pwordDIV {height:35%;width:80%;margin:0 auto;border:1px solid red;}
#fd_submitDIV {height:25%;width:35%;float:right;border:1px solid orange;}
#fd_loginDIV p{}
#fd_pwordDIV p{}
#fd_login {height:40px;width:60%;}
#fd_pword {height:40px;width:60%;}
#fd_submit {}
How to use Chrome dev tools to find out the problem:
In the elements pane, find and select the :after pseudo-element
In the view pane, a tooltip appears. It indicates the element id, and the size: 0px x 0px.
That's why it is not visible.
Add:
width: 100%;
height: 100%;
to #formDIV:after.
As a side note, having readable code is very important, especially for debugging. Use new lines, spaces, indentation and comments generously!

CSS Bootstrap: Auto resize input field and button

I have a a text type input field, and I have a button for "Search". I would like these 2 objects to be horizontally aligned; with the button being as big as it wants to be, and the input field taking up the rest of the space. I have been trying with CSS all day, but with no avail.
I am using RoR, and employing the Bootstrap library. I was wondering if there was anything out of the box that would make this work. I have also tried using flexboxes, but the input field seems to have a mind of its own. Below is the problematic code.
<div class="mini-layout fluid">
<div class="mini-layout-body">
<h2>Shows</h2>
</div>
<div class="mini-layout-sidebar">
<div class="search_container">
<input id="search_shows_text" type="text" class="search-query">
<button id="search_shows_button"
type="submit" class="btn btn-primary">Search</button>
</div>
</div>
</div>
I've been able to get the search_container class to lay things out horizontally, but getting its children to resize appropriately has managed to escape me all day.
Any help is greatly appreciated.
EDIT Thanks to Krishnan and the SO community I got the solution working. Below is the code for anyone else.
HTML
Search
CSS
.search_container
{
text-align:center;
margin-top: 5px;
}
.text_area
{
width: 55%; //Change as per your requirement
display: inline-block;
margin: auto;
}
.but_area
{
width: 25%; //Change as per your requirement
margin: auto;
}
By default bootstrap have width set to 206px for text area and 71px for submit button. So in order to make it accomodate your requirements you have to override those default properties. I would probably do something like this.
create a class text_area with custom property
.text_area
{
width: 85%; //Change as per your requirement
}
create a class but_area with custom property
.but_area
{
width: 10%; //Change as per your requirement
}
And would use it in input text area and button.
<input id="search_shows_text" type="text" class="search-query text_area">
<button id="search_shows_button"
type="submit" class="btn btn-primary but_area">Search</button>
It will make my text area to occupy 85% of the space and button to occupy 10% space in my window and remaining 5% of space is left free.

Placeholder background/image while waiting for full image to load?

I have a few images on my page. I'm finding that the page starts to render before the images have been loading (which is good), but that the visual effect is not great. Initially the user sees this:
--------hr--------
text
Then a few milliseconds later the page jumps to show this:
--------hr--------
[ ]
[ image ]
[ ]
text
Is there a simple way that I can show a grey background image of exactly the width and height that the image will occupy, until the image itself loads?
The complicating factor is that I don't know the height and width of the images in advance: they are responsive, and just set to width: 100% of the containing div. This is the HTML/CSS:
<div class="thumbnail">
<img src="myimage.jpeg" />
<div class="caption">caption</div>
</div>
img { width: 100% }
Here's a JSFiddle to illustrate the basic problem: http://jsfiddle.net/X8rTB/3/
I've looked into things like LazyLoad, but I can't help feeling there must be a simpler, non-JS answer. Or is the fact that I don't know the height of the image in advance an insurmountable problem? I do know the aspect ratio of the images.
Instead of referencing the image directly, stick it within a DIV, like the following:
<div class="placeholder">
<div class="myimage" style="background-image: url({somedynamicimageurl})"><img /></div>
</div>
Then in your CSS:
.placeholder {
width: 300;
height: 300;
background-repeat: no-repeat;
background-size: contain;
background-image: url('my_placeholder.png');
}
Keep in mind - the previous answers that recommend using a div background approach will change the semantic of your image by turning it from an img into a div background. This will result in things like no indexing of these images by a search crawler, delay in loading of these images by the browser (unless you explicitly preload them), etc.
A solution to this issue (while not using the div background approach) is to have a wrapper div to your image and add padding-top to it based on the aspect ratio of the image that you need to know in advance. The below code will work for an image with an aspect ratio of 2:1 (height is 50% of width).
<div style="width:100%;height:0; padding-top:50%;position:relative;">
<img src="<imgUrl>" style="position:absolute; top:0; left:0; width:100%;">
</div>
Of course - the major disadvantage of this approach is that you need to know the aspect ratio of the image in advance.
There is a really simple thing to check before you start looking into lazy-loading and other JavaScript. Make sure the JPEG images you are loading are saved with the 'progressive' option enabled!
This will cause them to load the image iteratively, starting with a placeholder that is low-resolution and faster to download, rather than waiting for the highest resolution data before rendering.
It's very simple...
This scenario allows to load a profile photo that defaults to a placeholder image.
You could load multi CSS background-image into an element. When an avatar photo fails, the placeholder image appears default of div.
If you're using a div element that loads via a CSS background-image, you could use this style:
#avatarImage {
background-image: url("place-holder-image.png"), url("avatar-image.png");
}
<div id="avatarImage"></div>
Feel free to copy this:
<script>
window.addEventListener("load", function () {
document.getElementById('image').style.backgroundColor = 'transparent';
});
</script>
<body>
<image src="example.example.example" alt="example" id="image" style="background-color:blue;">
</body>
I got this from here: Preloader keeps on loading and doesnt disappear when the content is loaded.
Apart from all solutions already mentioned, the last solution would be to hide the document until everything is loaded.
window.addEventListener('load', (e) => {
document.body.classList.add('loaded');
});
body {
opacity: 0;
}
body.loaded {
opacity: 1;
}
<div id="sidebar">
<img src="http://farm9.staticflickr.com/8075/8449869813_1e62a60f01_b.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-1.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-2.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-3.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-4.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-5.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-6.jpg" />
</div>
Or show some animation while everything is loading:
window.addEventListener('load', (e) => {
document.body.classList.add('loaded');
});
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 70px;
height: 70px;
-webkit-animation: spin 2s linear infinite;
/* Safari */
animation: spin 2s linear infinite;
position: absolute;
left: calc(50% - 35px);
top: calc(50% - 35px);
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
body :not(.loader) {
opacity: 0;
}
body .loader {
display: block;
}
body.loaded :not(.loader) {
opacity: 1;
}
body.loaded .loader {
display: none;
}
<div class="loader"></div>
<div id="sidebar">
<img src="http://farm9.staticflickr.com/8075/8449869813_1e62a60f01_b.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-1.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-2.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-3.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-4.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-5.jpg" />
<img src="https://www.nla.gov.au/sites/default/files/pic-6.jpg" />
</div>
The only thing I can think of, to minimize the jump effect on your text, is to set min-height to where the image will appear, I would say - set it to the "shorter" image you know of. This way the jump will be less evident and you won't need to use lazyLoad or so... However it doesn't completely fix your problem.
Here's one naive way of doing it,
img {
box-shadow: 0 0 10px 0 rgba(#000, 0.1);
}
You can manipulate the values, but it creates a very light border around the image that doesn't push the contents. Images can load at whatever time they want, and you get a good user experience.
Here is what I did with Tailwind CSS, but it's just CSS:
img {
#apply bg-no-repeat bg-center;
body.locale-en & {
background-image: url("data:image/svg+xml;utf8,<svg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'><text x='50%' y='50%' style='font-family: sans-serif; font-size: 12px;' dominant-baseline='middle' text-anchor='middle'>Loading…</text></svg>");
}
body.locale-fr & {
background-image: url("data:image/svg+xml;utf8,<svg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'><text x='50%' y='50%' style='font-family: sans-serif; font-size: 12px;' dominant-baseline='middle' text-anchor='middle'>Chargement…</text></svg>");
}
}
You can find the width and height of the images in the developer tools console, for example in Chrome you can click the cursor icon in the developer tools console and when you hover on the page it will highlight all the properties of the elements in the page.
This will help you find the width and height of the images, because if you hover on top of your images it will give you the dimensions of the image and other more properties. You can also make an individual div for each image and make the div relative to the images width and height. You can do it like this:
The main div will contain the images and also the background-div which is below the image.
HTML:
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div class=".mainDiv">
<div class="below"></div>
<img src="https://imgix.bustle.com/uploads/image/2020/2/13/da1a1ca4-95ec-40ea-83c1-4f07fac8b9b7-eqb9xdwx0auhotc.jpg" width="500"/>
</div>
</body>
</html>
CSS:
.mainDiv {
position: relative;
}
.below {
position: absolute;
background: #96a0aa;
width: 500px;
height: 281px;
}
img {
position: absolute;
}
The result will be that .below will be below the image and so when the image has trouble loading the user will instead see the grey .below div. You cannot see the .below div because it is hidden below the image. The only time you will see this is when the loading of the image is delayed. And this will solve all your problems.
I have got a way. But you will need to use JavaScript for it.
The HTML:
img = document.getElementById("img")
text = document.getElementById("text")
document.addEventListener("DOMContentLoaded", () => {
img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAA1BMVEWIiIhYZW6zAAAASElEQVR4nO3BgQAAAADDoPlTX+AIVQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwDcaiAAFXD1ujAAAAAElFTkSuQmCC";
text.innerHTML = "Loaded but image is not";
});
window.onload = function() {
img.src = "https://media.geeksforgeeks.org/wp-content/uploads/20190913002133/body-onload-console.png";
text.innerHTML = "Image is now loaded";
};
#img {
width: 400px;
height: 300px;
}
<hr>
<img id="img" src="https://media.geeksforgeeks.org/wp-content/uploads/20190913002133/body-onload-console.png">
<p>Here is the Image</p>
<p id="text">Not Loaded</p>

position a picture in the middle

I (absolute beginner) would like to put an image into a box with a little margin around. I tried with padding and so, didn't work. Then I tried this:
<div style="border:1px solid #CC6699; width:11em; height:5.5em;">
<img style="align:center; width:10em; height:5em;" src="path">
</div>
But instead the image gets stuck in the upper left corner.
Couple of ways to do this:
My usual is to set a background image instead.
In your css:
div#img_container {
background: url(images/myImage.png) center center
}
In your html:
<div id="img_container"></div>
Or to just put some padding around it in your CSS
img#myImage {
padding: 20px;
}
and the HTML
<img id="myImage" src="images/myImage.png" />
Try this:
<html>
<head>
<style>
#wrap {
width: 500px;
text-align: center;
}
.pic {
padding: 5px;
border: 2px solid #000;
}
</style>
</head>
<body>
<div id="wrap">
<img src="logo.gif" class="pic">
</div>
</body>
</html>
CSS level 2 doesn't have a property for centering things vertically. There will probably be one in CSS level 3. But even in CSS2 you can center blocks vertically, by combining a few properties. The trick is to specify that the outer block is to be formatted as a table cell, because the contents of a table cell can be centered vertically.
<div style="border:1px solid #CC6699; width:11em; height:5.5em;text-align:center;vertical-align:middle;display:table-cell;">
<img style="width:10em; height:5em;" src="path">
</div>
EDIT
As rpflo suggests, using the background-position property is especially great if the container happens to be smaller than the image. Just remember to include the "background-repeat:none" style if you don't want the image to be tiled.
Use the following small jQuery plugin. It centers the loading image in the middle of the specified container (vertically and horizontally):
http://plugins.jquery.com/project/CenterImage
Demo site:
http://www.demosites.somee.com/demos/centerimage.html
Usage: This plugin positions a loading image centrally over a specified html container (div, span...).
Currently available configuration settings:
{ path: "../Images/ajax.gif", overlayColor: 'green', opacity: 0.2, zindex: 2000, isrelative:true }
Minimum configuration for initialization:
$('.4th').CenterImage({ path: "../Images/ajax-bar.gif" });
Call this, in order to remove the loading image (and the overlay)
$('.4th').CenterImage('remove');

Resources