Zoom breaks CSS - css

I the following javascript which creates a rectangle of 125 divs by 75 divs. As follows:
function createFlag() {
var flag;
var counter = 1;
var rowCounter = 1;
var divs = 10000;
flag = '<table cellspacing="0" cellpadding="0"><tr>';
for (var i = 0; i < divs; i++) {
if (i % 125 === 0) {
flag += '</ tr><tr>';
rowCounter++;
counter = rowCounter;
} else flag += '<td id="pixel_' + counter + '" class="pixel"></td>';
counter += 80;
}
flag += '</tr></table>';
$('#flag').append(flag);
}
And I have some CSS which works fine while no zoom is applied. The CSS uses % and em for sizes which I thought should mean that relative proportions would be kept. The problem is as soon as you zoom in or out the rectangle of divs distorts shape.
To see what I mean the url in question is here: link here
How can I keep the proportions when zooming? All help appreciated of course.

Your table can't expand any more because the #flag div's width is 45% of the #container div width, which itself is 50% of the <body>. The width of the <body> doesn't change when you zoom, so the width of your table can't.
So you can either change the layout so that the form and the flag won't be float side by side, or just change #container's width to em's or px's.

Related

How to measure/convert CSS text margin/padding in the Photoshop?

How to get CSS text margin/padding from the Photoshop?
or
How to convert the distance from/to the text in Photoshop into CSS margin/padding?
Distances from text elements (paragraphs) in Photoshop do not correspond to margins/paddings in the CSS. Distances are measured, for example, using smart guides:
All because the line height is not used in the distances calculation. Therefore, the first recommendation I found is to use the formula:
margin_in_CSS = distance_in_PS - (line-height - font-size) / 2
or shorter:
CSS = PS - (line-height - font-size) / 2
This is the distance from some obvious border (line) to the text element. For the distance between two paragraphs we use, respectively:
CSS = PS - (line-height_1 - font-size_1) / 2 - (line-height_2 - font-size_2) / 2
As the font size increases, it becomes clear that this formula is not enough. The actual height of the line (obtained with the selection tool) in Photoshop is even less than the font size!
Although the photoshop still considers the height of the element to be approximately equal to the font size, which does not affect the distance to it :(. For example, on the Properties tab:
I calculated that the difference between the real height of the line and the font size is about 30% or 15% at the top and bottom of the text (I'm not saying this is 100% true!). And now I use the formula:
CSS = PS - (0.15 * font-size + (line-height - font-size) / 2)
Or between two paragraphs:
CSS = PS - (0.15 * font-size_1 + (line-height_1 - font-size_1) / 2)
- (0.15 * font-size_2 + (line-height_2 - font-size_2) / 2)
Similarly, we can not rely on the correct definition of the height of a paragraph in several lines by Photoshop. But here the situation is simpler, the real height of the paragraph in the CSS will be:
height = line-height * num_of_lines
The question is, is there a simpler way? О_о
Sorry for my English ^_^
UPDATE, shorter formulas:
text <> border
CSS = PS - (line-height - 0.7 * font-size) / 2
text <> text
CSS = PS - (line-height_1 - 0.7 * font-size_1) / 2
- (line-height_2 - 0.7 * font-size_2) / 2
UPDATE:
Now a script is being developed for the correct calculation of distances on the Adobe forum (link). At the moment, the script can calculate the distance from the bounding box of the text line with a standard (auto) line-height of 120%.
UPDATE:
It does not matter if you use a pointed text or a paragraph text, the result bounding box height is not equal to the text line-height (leading)
How to convert the distance from/to the text in Photoshop into CSS margin/padding?
The actual resulting glyph(s) (pink border in your image) of your text will have different height with the following contents:
"
[empty space] = no glyph at all
...
a
A
Qq
q
Margins and paddings should not be measured from the text itself, but from the boundaries of text line (or line-height in CSS).
In the above example:
65px is the actual height of text line (or line-height in CSS), (the distance from two text baselines when the text wraps) and what is used when calculating margin/padding. The end result being that no matter the contents of your text element, the distance from its baseline to the element following it should remain the same, based on line-height, (bottom) margin and (bottom) padding (and, of course, on the top margin and padding of next element).
To answer your question in a nutshell, PS does not apply a reduction to margins. It's just they are not calculated from the bounding box of the text glyphs (which might vary depending on contents), but from the bounding box of text line.
Another thing to consider when converting from .psd to HTML is that in HTML you have collapsing margins. In short, from two vertical adjacent margins only the largest one will be kept. If the other one is negative, it will be deducted from the positive one and if both are negative, the one with the largest value will be applied.
Finally, the script for measuring vertical distance is finished!
It can correctly calculate the vertical distance for CSS between layers, one of which or both are text layers.
Here's the link on Adobe Forums - A script for measuring the distance between two elements?
// version no CS6 or no effects
var old_units = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
try { app.activeDocument.suspendHistory("Get Text Bounds", "var bounds = get_selected_layers_bounds()") } catch(e) { alert(e); }
try { executeAction( charIDToTypeID( "undo" ), undefined, DialogModes.NO ); } catch(e) { alert(e); }
app.preferences.rulerUnits = old_units;
if (bounds)
{
if (bounds.length == 2)
{
var distance = 0;
if (bounds[0].bottom <= bounds[1].top) distance = bounds[1].top - bounds[0].bottom;
else if (bounds[1].bottom <= bounds[0].top) distance = bounds[0].top - bounds[1].bottom;
else alert("Intersecting layers")
var distance_in_css = distance - (bounds[0].leading - 1.2*bounds[0].size)/2 - (bounds[1].leading - 1.2*bounds[1].size)/2;
alert("distance = " + distance + "\ndistance_in_css = " + distance_in_css);
}
else
alert("More then 2 selected layers")
}
else
alert("There is no selected layers")
/////////////////////////////////////////////////////////////////////////////////////////////////
function get_selected_layers_bounds()
{
try {
var ref = new ActionReference();
ref.putProperty( charIDToTypeID( "Prpr" ), stringIDToTypeID( "targetLayers" ) );
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var desc = executeActionGet(ref);
if (!desc.hasKey( stringIDToTypeID("targetLayers") ) ) return null;
var n = 0;
try { activeDocument.backgroundLayer } catch (e) { n = 1; }
desc = desc.getList( stringIDToTypeID("targetLayers"));
var len = desc.count;
var selected_bounds = new Array();
for (var i = 0; i < len; i++)
{
try
{
var r = new ActionReference();
r.putIndex( charIDToTypeID( "Lyr " ), desc.getReference(i).getIndex() + n);
var ret = executeActionGet(r);
var size = 0;
var leading = 0;
if (ret.hasKey(stringIDToTypeID("textKey")))
{
var textStyleRangeList = ret.getObjectValue(stringIDToTypeID("textKey")).getList(charIDToTypeID("Txtt" ));
if (textStyleRangeList.count > 1) { alert("More than one textStyleRange in layer", "Oops!!"); }
var textStyle = textStyleRangeList.getObjectValue(0).getObjectValue(charIDToTypeID("TxtS" ));
var auto_leading = textStyle.getBoolean(stringIDToTypeID("autoLeading"));
size = textStyle.getUnitDoubleValue(stringIDToTypeID("size"));
leading = auto_leading?size*1.2:textStyle.getUnitDoubleValue(stringIDToTypeID("leading"));
var s = ret.getObjectValue(stringIDToTypeID("textKey")).getString(charIDToTypeID("Txt " ));
s = s.replace(/^./gm, String.fromCharCode(0x2588));
var d1 = new ActionDescriptor();
d1.putReference( charIDToTypeID( "null" ), r );
var d2 = new ActionDescriptor();
d2.putString( charIDToTypeID( "Txt " ), s);
d1.putObject( charIDToTypeID( "T " ), charIDToTypeID( "TxLr" ), d2 );
executeAction( charIDToTypeID( "setd" ), d1, DialogModes.NO );
ret = executeActionGet(r);
}
// var bounds = ret.getObjectValue(stringIDToTypeID("bounds")); // use this in CS6 or when you want to take into account the effects
var bounds = ret.getObjectValue(stringIDToTypeID("boundsNoEffects")); // in CS6 does not work
var obj = {
left : bounds.getUnitDoubleValue(stringIDToTypeID("left")),
top : bounds.getUnitDoubleValue(stringIDToTypeID("top")),
right : bounds.getUnitDoubleValue(stringIDToTypeID("right")),
bottom : bounds.getUnitDoubleValue(stringIDToTypeID("bottom")),
size : size,
leading: leading,
};
selected_bounds.push(obj);
}
catch (e) { alert(e); return null; }
}
return selected_bounds;
}
catch (e) { alert(e); return null; }
}
The script should be saved as a *.js or *.jsx file (for example, distance.js) in the Photoshop folder - C:\Program Files\Adobe\Adobe Photoshop CC 2017\Presets\Scripts
It will be available in the Photoshop menu - File > Scripts > Distance
it does not matter , psd is for showing how the website looks on completion you have to take in consideration the font size , for e.g. for paragraph text if the font size is 14 pt in psd and the grid is 1200px (bootstrap) than you have to convert the font in aspect ratio of browser ( default 16px now in bootstrap ) and calculate accordingly like 14pt in psd is equals to 14px + (14 * 0.16%)px in browser and everything else accordingly , similar for line height.
also if you want to set font size same as psd its up to you select 14px for html if our psd font size is 14pt for paragraph.

CSS: Make Canvas as big as possible while keeping aspect ratio

I have a Canvas element that is inside a container div. When the user selects an image from his machine, this image should be displayed on the canvas. I want the canvas to be big as possible but at the same time keep the aspect ratio of the image. I know neither the proportions of the image nor the size of the container div, as this is relative to the screen/window size of the user.
If I set max-width and max-height to e.g 100% the canvas will not fill the container if the selected image is smaller then the container. If I set width and height instead of max-width and max-height the canvas doesn't keep the aspect ratio.
Does anyone have an idea how to solve this?
If you're willing to use JQuery (or regular JavaScript), then a solution like this might work:
<script>
// Note: this uses jQuery.
// It makes getting/setting the dimensions easier,
// but you can do this with normal JavaScript
var img = $("#img");
var container = $("#container");
var width = img.width();
var height = img.height();
var maxWidth = container.width();
var maxHeight = container.height();
var ratio = maxWidth / width;
if(height * ratio > maxHeight) {
ratio = maxHeight / height;
}
img.width(width * ratio);
img.height(height * ratio);
</script>
What this does is that it finds the ratio to multiply the width and the height by, whichever one is smaller (so that it will always fit in the window).
Update: Tested on JSFiddle.net. See it here.
I hope this helps you!
After reading your clarification about video, check out the following:
https://jsfiddle.net/d0dox9xt/
body {
background: #eee;
}
#container {
margin:0 2% 0 2%;
}
#v {
position:absolute;
top:0;
left:0;
width:100%;
}
The only trick is setting width:100%; This will maintain aspect ratio.
Note that in the JS
document.addEventListener('DOMContentLoaded', function(){
var v = document.getElementById('v');
var canvas = document.getElementById('c');
var context = canvas.getContext('2d');
}
function draw(v) {
c.drawImage(v, 0, 0);
}
The drawImage function can take many arguments. The first argument is inserting the media, the next two are for positioning. There are many arguments you can have to position and change the height and width. I left them alone so it will follow the CSS rules.
Here is a link to more on placing in canvas: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage

How to position an element absolute to the window regardless of its DOM position?

I am creating a pop-up overlay modal and am having problems getting the positioning/scrolling working correctly.
I can set my modal to be position:fixed but then if the modal's height is too much, then the modal overflows off of the window and you cannot see the bottom of it.
If I set the modal to be position:absolute then the element becomes positioned relative to the closest ancestor with position:relative, correct? (or at least thats what it appears to do) Instead I want the modal to ALWAYS be relative to the window so that I can center it easily.
Is there a way to make the below .modal positioned relative to the window ( or element) even if the element is nested deep inside the DOM like this:
<body ng-app="myapp" ng-controller="mycontroller">
<div>
<div>
<div ui-view>
<div class=".modal"></div>
</div>
</div>
</div>
</body>
If you insist on having it in that same markup and nested in the same manner, your best bet is in JavaScript.
Here's some JS code that gives a good method of accomplishing what you asked for:
function ShowDivInCenter()
{
try
{
divWidth = 100;
divHeight = 100;
divId = 'divLogin'; // id of the div that you want to show in center
// Get the x and y coordinates of the center in output browser's window
var centerX, centerY;
if (self.innerHeight)
{
centerX = self.innerWidth;
centerY = self.innerHeight;
}
else if (document.documentElement && document.documentElement.clientHeight)
{
centerX = document.documentElement.clientWidth;
centerY = document.documentElement.clientHeight;
}
else if (document.body)
{
centerX = document.body.clientWidth;
centerY = document.body.clientHeight;
}
var offsetLeft = (centerX - divWidth) / 2;
var offsetTop = (centerY - divHeight) / 2;
// The initial width and height of the div can be set in the
// style sheet with display:none; divid is passed as an argument to // the function
var ojbDiv = document.getElementById(divId);
ojbDiv.style.position = 'absolute';
ojbDiv.style.top = offsetTop + 'px';
ojbDiv.style.left = offsetLeft + 'px';
ojbDiv.style.display = "block";
}
catch (e) {}
}
You can then call the function through any event, for example:
<body onload='ShowDivInCenter();' onresize='ShowDivInCenter();'>
if you want it to be dynamic.

Background-size cover jumping when background-position switches to fixed

I am working on a Parallax/Scrolling Timeline project and I am having a problem with the CSS3 Background-size cover property.
The div has these properties:
background: url(../images/timeline/back-6.jpg) no-repeat top center black;
background-size: cover;
padding-top: 90px;
height: 1855px;
position: relative;
Using jQuery I switch the background-attachment to fixed. When I do this the background image jumps "in" (meaning that parts of the image that were past the edge of the screen are now visible). Which isn't the desired result.
In testing I can switch the div to use background-size: 100% cover but it is causing different vertical jumping issues when scrolling.
Any ideas of how to prevent it from jumping in when I switch the background to fixed? (It also happens in reverse when I set the background to scroll).
I sadly can't link to a demo of this code as the page isn't ready to be deployed yet.
I had the same issue, when setting background-size to cover or contain
Setting a fixed height, in example for smaller screens via #media prevents the background-image from jumping. After my tests I came to the conclusion, that the jumping is due to the orientation of the element after setting background-attachment to fixed
Setting it to fixed, the size is calculated by the size of the viewport, not the element containing the background-image. This is where the jumping comes from and why setting a fixed height or width for the background-size solves this issue.
I had the same problem while creating a one page layout i wanted to use with a scrollTo-Plugin and so on....
The page layout was devided in two parts:
Left side for the background image which should change/scroll with the content on the right side.
So i used to make a kind of jquery Plugin to combine both "background-position: fixed" and "background-size: cover".
you just need to define the element by class/id for aligning the background-images.
dont complain about the code. im relatively new to javascript/jquery. but its working ;)
there it is:
function fixedResize() {
var targetEl = $('element where bg-images are in');
var targetWidth = targetEl.width();
var targetHeight = targetEl.height();
var targetPosX = targetEl.offset().left;
var targetPosY = targetEl.offset().top;
var leftRatio = targetWidth / targetHeight;
//console.log('TargetWidth', targetWidth, 'TargetHeight', targetHeight, 'Offset', targetPosX, targetPosY, 'leftRatio', leftRatio);
targetEl.each(function(){
var imgTarget = $(this);
var url = $(this).css('background-image').replace('url(', '').replace(')', '').replace("'", '').replace('"', '');
var bgImg = $('<img />'); // make background-image as image tag for getting width and height of the image
imgTarget.css('background-attachment','fixed');
bgImg.hide();
bgImg.bind('load', function(){
var imgHeight = $(this).height();
var imgWidth = $(this).width();
var imgRatio = imgWidth / imgHeight;
$(this).remove(); // remove img Tags again
// Calculate resize dimensions
if (imgRatio > leftRatio) {
var currentWidth = imgRatio * targetHeight; // image width after resize
var currentHeight = (currentWidth/imgWidth)*imgHeight;
var setToLeft = ((currentWidth - targetWidth)/2);
var imgPosX = targetPosX - setToLeft;
var imgPosY = (currentHeight - targetPosY - currentHeight/2 - targetHeight/2)* -1;
var resizeImg = 'background-size: auto '+ targetHeight +'px;';
} else if (imgRatio < leftRatio){
var currentWidth = targetWidth;
var currentHeight = (currentWidth/imgWidth)*imgHeight;
var imgPosX = targetPosX;
var imgPosY = (currentHeight - targetPosY - currentHeight/2 - targetHeight/2)* -1;
var resizeImg = 'background-size: '+ targetWidth +'px auto;'; // resize background
}
imgTarget.attr('style','background-attachment: fixed; background-position: '+ imgPosX +'px '+ imgPosY +'px;' + resizeImg);
console.log('imgWidth', imgWidth, 'imgHeight', imgHeight, 'imgRatio', imgRatio, 'currentWidth', currentWidth, 'currentHeight', currentHeight, 'setToLeft', setToLeft);
console.log('imgPos', imgPosX, imgPosY, 'setToLeft', setToLeft, targetPosX);
});
$(this).append(bgImg);
bgImg.attr('src', url);
});
}
fixedResize(); // initiate function
$(window).resize(function() {
fixedResize(); // initiate function for window resize (Fluid behavior)
});
or
jsfiddle.net/rowphant/eXb6e/14/

dynamic add component

I want to dynamically add component in Container like Canvas(TileList constraints each child has the same size, GridList is poor in performance), for example
<mx:Canvas id="myHolder" width="600" height="550">
</mx:Canvas>
<mx:Button label="Add Button" click="addButton()"/>
when I click the button, I hope add a component(whatever the component is, and maybe each component has different size), and if the total width of all added child is greater than myHolder, I hope the new child can begin in new line, and stretch the height of myHolder at the same time.(layout with custom code is better)
On Canvas you have complete freedom to lay components anywhere using their x and y properties, so there's a lot of ways to skin this cat. Since you need rows, one of the methods may be (not tested):
//inside of your Canvas-based component
private function updateChildrenPositions():void
{
var rowY:Number = 0;
var rowWidth:Number = 0;
var rowHeight:Number = 0;
for (var i:int = 0, total:int = numChildren; i < total; i++)
{
var child:DisplayObject = getChildAt(i);
if (rowWidth + child.width > width)
{
//child will cause overflow, start next row
rowY += rowHeight;
rowWidth = 0;
rowHeight = 0;
}
rowWidth += child.width;
child.x = rowWidth;
child.y = rowY;
if (child.height > rowHeight) rowHeight = child.height; //accumulating max height
}
height = rowY + rowHeight;
}
This assumes Canvas has fixed width and set height depending on layout. You can add paddings and gaps later, it's a good exercise :)
To get the functionality you want, I wouldn't use an HBox. As alxx suggested, a TileList would be a better fit in this situation.
Here are some examples using a TileList to get you started:
http://blog.flexexamples.com/category/halo/tilelist/
http://learn.adobe.com/wiki/display/Flex/TileList

Resources