I was working on a JavaScript dialog with a transparent background overlay when I ran into a problem on large pages.
If the page was large, the transparent overlay would be a solid colour (i.e. no longer transparent). I did some testing and found this only happened in the overlay was greater than 4096 pixels high (hmmm, suspicious, that's 2^12).
Can anyone verify this issue? Have you seen a work-around?
Here's my test code (I'm using Prototype):
<style>
.overlayA {
position:absolute;
z-index:10;
width:100%;
height:4095px;
top:0px;
left:0px;
zoom: 1;
background-color:#000;
filter:alpha(opacity=10);
-moz-opacity:0.1;
opacity:0.1;
}
.overlayB {
position:absolute;
z-index:10;
width:100%;
height:4097px;
top:0px;
left:0px;
zoom: 1;
background-color:#000;
filter:alpha(opacity=10);
-moz-opacity:0.1;
opacity:0.1;
}
</style>
<div style="width:550px;height:5000px;border:1px solid #808080">
Display A = 4096h
<br />Display B = 4097h
</div>
<div id="overlayA" onclick="Element.hide(this)" class="overlayA" style="display:none"></div>
<div id="overlayB" onclick="Element.hide(this)" class="overlayB" style="display:none"></div>
Since you have an opacity filter on the CSS I believe you are indirectly using DirectShow under the covers for alpha blending and image composition. DirectShow uses DirectX textures, which have a 4096x4096 pixel limit for DX9, which would explain this erratic behavior.
How about making the overlay the size of the window instead of the size of the page, and moving it up or down on scroll.
You are operating at the edge already (that's huge...) so I don't know that MS would classify it as a bug or 'fix' it even if it was.
You might need to break it up into smaller overlay DIVs.
Why wouldn't you postion the overlay fixed?
That way it wouldn't have to be as big as the whole page content.
Simply doing:
#Overlay{
position:fixed;
left:0px;
top:0px;
height:100%;
width:100%;
rest of declarations
}
Just make sure it's parent is the document and the document has a width and height of 100%. That way you should be good with a much smaller overlay.
THe posotion:fixed will make sure the overlay is positioned relative to the viewport. Thus its always displayed in the top left corner.
The position:fixed solution is a spotty solution..It is not well supported in IE.
The best thing is to automatically create and append additional transparent elements (with a max height of 2048px to cover XP DX8 which has this issue as well).
Here's the code I used, assuming you already have a floating div solution.
if(document.getElementById('document_body').scrollHeight > 2048)
{
document.getElementById('float_bg').style.height = "2048px";
document.getElementById('float_bg').style.zIndex = -1;
count=1;
total_height=2048;
while(total_height < document.getElementById('document_body').scrollHeight)
{
clone = document.getElementById('float_bg').cloneNode(true);
clone.id = 'float_bg_'+count;
clone.style.zIndex = -1;
//clone.style.backgroundColor='red';
clone.style.top = (count*2048)+"px";
document.getElementById('float_el').insertBefore(clone,document.getElementById('float_bg'));
count++;
this_add = 2048;
if((total_height + 2048) > document.body.scrollHeight)
{
clone.style.height = (document.body.scrollHeight - total_height);
}
total_height += this_add;
}
}
else
{
document.getElementById('float_bg').style.height = document.body.scrollHeight + "px";
}
Related
i am looking for a way to get the size of a rendered image within a webpage, which size is defined as a percentage value.
I need this because of a relative positioning of 2 images which should be invariant go the size of the browser window, as well as the zooming of the site.
I did some research and this one here describes my problem pretty well:
Button width as a percentage of parent
Quote:
"To set a percentage height, its parent element must have an explicit height."
Here are the relevant parts of my project:
<div style="display: block; width:90%; height:100%; background-color:rgba(128,128,0,0.5)">
<button style=#myStyle #onclick="#(e => doFunction(5))"> </button>
with myStyle:
myStyle = "top: -30%; left: 0%; width: 15%; height: 15%; overflow: hidden; background-color: rgba(201, 76, 76, 0.3); position: relative;"
So, i got the button within a structure, and the size of the structure is again given as a percentage with respect to its superordinate structure. (but this topmost structure then has absolute values).
Is there a way to calculating and getting the absolute values (width/height) of the first structure "while rendering"?
I hope i could explain my problem sufficiently understandable, i'm happy about any answers regarding this problem, even if the answer is "it does not work like that". Thanks!
I would do it like this:
Give your image an ID:
<div id="some-id" style="display: block; width:90%; height:100%; background-color:rgba(128,128,0,0.5)">
In JavaScript, set an Event Listener when the window is loaded:
window.addEventListener('load', function() {
//set the image's dimensions to the divs that need it
var imageDiv = document.getElementById("some-id");
var otherDiv = document.getElementById("other-div");
otherDiv.style.height = imageDiv.offsetHeight + "px";
otherDiv.style.width = imageDiv.offsetWidth + "px";
});
I don't think I can explain this very well in words, so here's a gif:
The p is a <p> tag that appears when it's display is changed to block in js (by default it's none).
When this happens, h1 shifts a bit upward. (here it's only one line, it's usually more)
How can I go about animating h1's movement upward?
You can harness display: table and display: table-cell properties to emulate a gravity to the bottom using vertical-align: bottom.
Then with a little bit of jQuery goodness, you should be able to trigger CSS animations on specific events, such as the loading of a new element.
Check out this implementation on JSFiddle
In the snippet, hObj is the h1 tag you wish to move and pObj is the paragraph tag you want to insert later. You can use css transitions to animate objects.
var hObj = document.getElementById("hObj");
var pObj = document.getElementById("pObj");
function move(){
hObj.style.top = "60px";
hObj.addEventListener("transitionend", function(){ pObj.style.visibility = "visible"; });
}
<h1 style="position:absolute; left:100px; top:100px; transition:top 0.5s linear; cursor:pointer; " id="hObj" onclick="move()">h1</h1>
<p style="position:absolute; left:100px; top:100px; visibility:hidden" id="pObj">p</p>
I have a site with 4,000+ pages and 10 or more jpeg images per page, of varying sizes. I'm trying to make the site more mobile friendly. To that end, i want to make it possible for the images to shrink to fit on smaller screens. I know that i can do something like this to signal that the images can shrink:
img.bodyImg
{
width: 100%;
max-width: 357px;
height: auto;
}
But what if not all images have a width of 357 (or whatever), and i don't want smaller images stretched beyond their true dimensions? And just to make things more fun, what if the images tags don't have height and width attributes specified?
My goal is to find a solution that doesn't require me to adjust tens of thousands of image calls manually, but i can do a search and replace. Images are currently wrapped in a div container and have a class, like so:
<div class="imgDiv"><img class="bodyImg" src="http://www.example.com/image.jpg"></div>
I'm also open to the possibility that i'm going about this in the wrong way entirely.
Using max-width is simple, effective, and requires no JavaScript.
The CSS below creates responsive images that shrink to fit the container's width but won't expand beyond their native sizes.
img.bodyImg {
max-width:100%
}
In the demonstration below, both images are 300px X 75px. The first container is 200px wide and the second one is 400px wide. Notice that the first image shrinks to fit in the container, but the second image does not expand beyond its native size. Also note that the proportions of each image remain accurate.
div {
background-color: #CCC;
margin:0 0 .5em;
padding:.25em;
}
div.one {
width: 200px;
}
div.two {
width: 400px;
}
img {
display:block;
max-width: 100%;
}
<div class="one">
<img src="http://lorempixel.com/300/75/abstract/4/" />
</div>
<div class="two">
<img src="http://lorempixel.com/300/75/abstract/4/" />
</div>
Additional Notes
I've included display:block to remove the descender space below the image.
If your images have specific height and width attributes (as they arguably should), you can add height:auto and/or width:auto to override those attributes.
Bootstrap uses this method for responsive images.
You can use a little jQuery to figure out each image's native width, and set perscriptive max-widths for each image afterward:
$('.bodyImg').each(function() {
// Create new offscreen image to test
var theImage = new Image();
theImage.src = $(this).attr("src");
// Get accurate measurements from that.
var imageWidth = theImage.width;
$(this).css({
"max-width" : imageWidth
});
}
UPDATE: And if you want each image to have a uniform width, you can store the smallest max width and apply it to all of the images:
var smallMax;
$('.bodyImg').each(function() {
// Create new offscreen image to test
var theImage = new Image();
theImage.src = $(this).attr("src");
// Get accurate measurements from that.
var imageWidth = theImage.width;
// if the variable exists and is bigger than
// the current width, use the new max width
if (smallMax !== undefined && smallMax > imageWidth) {
smallMax = imageWidth;
}
// set the variable if it hasn't been set yet
else if (smallMax == undefined) {
smallMax = imageWidth;
}
// keep the old variable if it is defined and smaller
else {}
$(this).css({
"max-width" : smallMax
});
}
Why not just:
max-width:100%; /*Ensure the width scales to the width of the parent container*/
width:auto; /* Not required, but sometimes is nice to ensure the width not being overridden by other factors like browser quirks */
height: auto; /*Ensure the image keeps its ratio*/
Try using max-width:100% and height: auto in your css. If you want to make your site mobile friendly I would suggest looking into bootstrap framework for more flexibility.
I have a nested shopping-type list that is grouped by type (and has descriptions for each item).
What I'm wanting to do is have the last type scrolling in the list, until the point that it would scroll off the top of the list.
A list may declared as
<div id="items">
<item-type>Type A</item-type>
<description>a</description>
<description>b</description>
<description>c</description>
<item-type>Type B</item-type>
<description>d</description>
<description>e</description>
<description>f</description>
<description>g</description>
<description>h</description>
</div>
I'm using element types so that I can use #items > item-type:last-of-type in CSS3 to select the last element.
#items {
word-wrap: break-word;
overflow: auto;
height: 100%;
}
#items > * {
display: block;
}
#items > item-type:last-of-type {
position:absolute;
bottom: 100px;
}
So the only point now, is how do I keep it (effectively) position: relative; top: 0 to position: absolute; top: 0 using only CSS3?
I'm using FF4 and HTML5, so you can go all out; this won't be supported on older browsers. Also, using calc() is fine.
The valid view options are be something like:
______________________________________
Type A a Type B
a b e
b c f
c Type B g
d h
---------------------------------------
Where the lines are the visible area, and each column shows how it would appear given a certain amount of data (progression left to right)
If I understand the problem correctly, you want to create something like the iPhone Contacts list. Looking at the solution someone already built it uses JavaScript. Also, I've thought about it and gone through all the CSS3 specs but cannot determine anything that could be used here to achieve the same affect without JavaScript.
I knocked up a small demo, but again this uses JavaScript. I just don't think it's possible with pure CSS, although I'm sure someone will correct me if that's not the case :-)
HTML
<div id="items">
<item-type>Type A</item-type>
<description>a</description>
<description>b</description>
<description>c</description>
<item-type>Type B</item-type>
<description>d</description>
<description>e</description>
<description>f</description>
<description>g</description>
<description>h</description>
<description>i</description>
<description>j</description>
<description>k</description>
<description>l</description>
</div>
CSS
#items {
word-wrap: break-word;
overflow: auto;
height:100px;
border:1px dashed red;
width:200px;
}
#items > * {
display: block;
}
#items > item-type {
border:1px dashed blue;
background-color:#fff;
width:180px;
}
JavaScript (jQuery 1.6+)
var itemsTop = $('#items').position().top;
var itemTypeHeight = $('item-type').height();
var itemTypeBottom = itemsTop + itemTypeHeight;
$('#items').scroll(function() {
$('item-type').each(function() {
$(this).css({position:''});
if ($(this).position().top < itemsTop + itemTypeHeight) {
$(this).css({position:'fixed',top:itemsTop});
}
});
});
I think it's not possible for the following reasons (which may or may not be related):
When in normal viewing, a relative position is needed; at the top of the visible area, it would need to change to absolute
you could use calc() and min() or max() with the visible height, the current element's height and the current scroll position; except that none of these calculated properties are available to css
Another idea is making more absolute positioning of the 2nd item level, but there's no way of referencing the absolute-parent's height as well as the absolute-grandparent's height.
I think the first point is the easiest way to convince myself that it's not possible. The other two convince me that combinations of fancy css functions and absolute positioning are sunk as well.
Any idea to make an element in the page full screen?
For example,a div or an img?
With "full screen" I mean that it should take all the space of user's screen,just like when we watch a video with the full screen model. I do not want the task bar/menu bar of the browser window display.
Any idea?
div.fullscreen{
display:block;
/*set the div in the top-left corner of the screen*/
position:absolute;
top:0;
left:0;
/*set the width and height to 100% of the screen*/
width:100%;
height:100%;
background-color:red
}
I have tried the above code,however it is not what I want,it juse take all the space of the browser's content area rather than the user's computer'screen.
HTML elements can't break out of the bounds of the browser document window. The menu and tool bar are outside of the document window (which is a child of the browser window), so you can't "reach" them.
I think the only solution is to trigger full screen mode with JavaScript.
This answer shows how you can do that: How to make the window full screen with Javascript (stretching all over the screen)
There is a relatively new fullscreen JavaScript api which can make an element full screen.
It has to be called as the result of user input to prevent possible abuse, but it's relatively straight-forward to use:
Code from MDN article:
document.addEventListener("keydown", function(e) {
if (e.keyCode == 13) {
toggleFullScreen();
}
}, false);
function toggleFullScreen() {
if (!document.fullscreenElement && // alternative standard method
!document.mozFullScreenElement && !document.webkitFullscreenElement) { // current working methods
if (document.documentElement.requestFullscreen) {
document.documentElement.requestFullscreen();
} else if (document.documentElement.mozRequestFullScreen) {
document.documentElement.mozRequestFullScreen();
} else if (document.documentElement.webkitRequestFullscreen) {
document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
}
} else {
if (document.cancelFullScreen) {
document.cancelFullScreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
}
}
}
This is not possible now, and it will probably never be.
Just imagine what would happen if every website you visit had free reign to take over your desktop.
In order to do this, you can use the screen.availWidth and screen.availHeight properties to get the screen size. Next, set the element size to their corresponding properties in js.