How to remove/change print document margin in printTask? - javascript

I wonder how I can achieve a borderless print.
At the moment my output looks like this:
I'd like to have the image start at the very top left corner. Is this possible? I already tried to set a negative margin to my print-style box, but the image will get cut then.
I know that maybe not all printers are capable of printing the area of the border, but in my use-case the picture will be white in these areas. (The mountain-image is just for demo purposes)
Can I specify the document border somehow via printTask?
See my current setup:
HTML:
<div id="pdf-render-output"></div>
CSS:
body > #pdf-render-output {
display: none;
}
#media print {
body > * {
display:none;
max-width: 100%;
}
html {
max-width: 100%;
border-top: 0;
}
body > #pdf-render-output {
display: block;
border: none;
max-width: 100%;
width: 100%;
height: 100%;
position: relative;
margin: 0; /* I tried to set negative margin/padding eg. here */
padding: 0;
}
}
JS:
$('#pdf-render-output').append("<img src="..." style=\"width: 100%\" />");
I played around with all possible margins/paddings and stuff, but the image will get cut and the white border stays 'over' it.
I hope that there might be a printTask-option I missed browsing the msdn?
Update:
I tried to set all margin/padding/border values with !important. No change.
Here is a screenshot from the simulator, displaying only the print-css-style:
I got to the point thinking it's an issue with the printTask itself. Are there any options regarding to this problem?

If the margin values of DocumentSource is set to 0, gaps will decrease very much. However, compared with PrintTask by C#+XAML, a top margin(Probably header/footer area) is made a little.
var printTask = printEvent.request.createPrintTask("Print Sample", function (args) {
var src = MSApp.getHtmlPrintDocumentSource(document);
src.rightMargin = 0;
src.leftMargin = 0;
src.topMargin = 0;
src.bottomMargin = 0;
src.shrinkToFit = false;
args.setSource(src);
}
In my environment, when this CSS was used, it has removed the margin without the necessity for src.rightMargin, etc.
#page {
margin:0cm;
}

Related

Css - how to change element size if it reached to certain spot on screen?

I've dynamically created some divs with random color who are scattered over the page randomly. I want to use css to give them a condition that says that if the div is located above let's say 600px on the screen - his size will change. I know the "if" statement for css is #media but I didn't figure how to use it right in this situation. Can you help me?
Example of a div (they all have the same class - "frog")
<div id="frog" class="fas fa-ad" style="width: 66px; height: 66px;
background-color: rgb(87, 58, 55); position: absolute; left: 312px; top:
93px; display: block;"></div>
You can't do that with CSS only. The only way you can have dynamic styling based on what happens in the windows in CSS is to use media queries. However, the docs precise that you can only detect window-level data, like the device width, or whether the page is displayed on a screen or on a printed paper, etc.
You'll have to change your style with JS. This is often a bad way to have dynamic styling, because the only way to do so is to 'probe' the DOM (using for example setInterval). Luckily your case is an exception - since you update your divs position with JS, you can check directly after that the position of your divs, and update your styles accordingly!
Example using the very useful getBoundingClientRect:
// select the frog element
let frog = document.getElementById('frog');
let count = 0;
setInterval(() => {
// update the frog position
frog.style.top = `${count}px`;
count = (count+2)%200;
// check if the frog is after 100px from the top of the window
if (frog.getBoundingClientRect().top>100) {
frog.className = 'over-100';
} else {
frog.className = '';
}
}, 1000/30);
#frog {
position: fixed;
top: 0;
left: 0;
width: 50px;
height: 50px;
background-color: green;
}
#frog.over-100 {
background-color: olive;
}
<div id="frog"></div>

how to stop header from scrolling at some point and make it fixed

I have a header, in which i put my h1 and h2 headings at top. The problem is that header scrolls along the scroll bar which is of course normal but i want to fixed it at some point when all the headings on header scroll away. At this point I want header to stop and stays fixed.
I already tried fixed position but of course it fixed heading as well which exactly I don't want.
I also tried this JavaScript but no luck.
JavaScript
$(window).scroll(function() {
var _height = 120 - (120 * $(this).scrollTop() / $('body').height());
if (_height >= 80) {
$('.header_container').height(_height);
}
});
and here qre my HTML and CSS codes respectively.
HTML
<div class="header_container" id="header_container">
<div id="header_titles">
<h1 class="homepage-heading">Browse</h1>
<h2 class="homepage-heading-subtle">GENRES & MOODS</h2>
</div>
</div>
CSS
#header_container {
background-color: black;
width: 100%;
height: 120px;
top: 0;
left: 0;
right: 0;
}
#header_titles {
position: absolute;
width: 100%;
font-size: 35px;
text-align: center;
padding-top: 10px;
}
So, let me see if I get this...you want your header to be scrolled normally with the page until a certain point where it becomes fixed?
EDIT
Ok, well, you could determine the element on the page that you want the position to be triggered at. Like, the top of a certain paragraph, and use that position in your condition.
var condition = $(element).offset().top;
if($(window).scrollTop > condition) { //add a fixedClassName } else { remove the fixedClassName }
and have header.fixedClassName have those proprieties ( with position fix, top 0 and width: 100% to your header etc). Be sure to add and remove a class on the body that gives it padding-top with the height of your displaced header.
Used some similar effect here http://goodmen.se/ after a point the logo shows up in the header, then there's a background change. You do something similar with your position.
EDIT 2
Here's an example fiddle http://jsfiddle.net/Corsico/vpskd8hd/
So you want a sticky header?
In your javascript create a code:
var $header_container = $('#header_container');
var header_height = $header_container.outerHeight(true);
if($(window).scrollTop() < header_height){
$header_container.removeClass('sticky');
} else{
$header_container.addClass('sticky');
}
$(window).on('scroll', function(){
if($(window).scrollTop()< header_height){
$header_container.removeClass('sticky');
} else{
$header_container.addClass('sticky');
}
});
This will add a sticky class to your header, and then you can set the header to be fixed:
.sticky{
position:fixed;
top:0;
left:0;
width:100%;
display:block;
}
This should do it. When you scroll pass the height of the header, you'll get the 'sticky' class, if not, you'll remove the sticky class...

Slide trigger from top to bottom

I am using this for a slide trigger from top to bottom but on click my button is not moving from the top and the content is falling before button. I want as the content and my button to fall together.
Here you have my code for this.
HTML
<section class="drawer">
<header class="clickme">Click Me</header>
<div class="drawer-content">
CONTENT HERE
</div>
</section>
CSS
.drawer {
height: 800px;
overflow: hidden;
position: absolute;
width: 100%;
z-index: 5;
}
.drawer > header {
background: url(../img/UP-Discover.png);
background-repeat: no-repeat;
display: block;
height: 77px;
margin-left: 30%;
overflow: hidden;
width: 100%;
}
.drawer-content {
background: #fff;
padding-top: 22px;
background-repeat: no-repeat;
border-collapse: collapse;
height: 742px;
width: 100%;
border-bottom: 10px;
border-color: #000;
}
jQuery
$(function() {
$('.drawer').slideDrawer({
showDrawer: false,
// slideTimeout: true,
slideSpeed: 500,
slideTimeoutCount: 3000,
});
});
EDIT: This is the plugin that I am using. It was based on bottom. If I place it in bottom it will slide together.
(function(e) {
var t = {
init: function(n, r) {
if (n.showDrawer == true && n.slideTimeout == true) {
setTimeout(function() {
t.slide(r, n.drawerHiddenHeight, n.slideSpeed)
}, n.slideTimeoutCount)
} else if (n.showDrawer == "slide") {
t.slide(r, n.drawerHiddenHeight, n.slideSpeed)
} else if (n.showDrawer == false) {
t.hide(n, r)
}
e(".clickme").on("click", function() {
t.toggle(n, r)
})
},
toggle: function(n, r) {
e(r).height() + n.borderHeight === n.drawerHeight ? t.slide(r, n.drawerHiddenHeight, n.slideSpeed) : t.slide(r, n.drawerHeight - n.borderHeight, n.slideSpeed)
},
slide: function(t, n, r) {
e(t).animate({
height: n
}, r)
},
hide: function(t, n) {
e(n).css("height", t.drawerHiddenHeight)
}
};
e.fn.slideDrawer = function(n) {
var r = this.children(".drawer-content"),
i = parseInt(r.css("border-top-width"));
drawerHeight = this.height() + i;
drawerContentHeight = r.height() - i;
drawerHiddenHeight = drawerHeight - drawerContentHeight;
var s = {
showDrawer: "slide",
slideSpeed: 100,
slideTimeout: true,
slideTimeoutCount: 5e3,
drawerContentHeight: drawerContentHeight,
drawerHeight: drawerHeight,
drawerHiddenHeight: drawerHiddenHeight,
borderHeight: i
};
var n = e.extend(s, n);
return this.each(function() {
t.init(n, this)
})
}
})(jQuery);
You need to position your absolutely positioned drawer. Currently, it's just absolute. It's out of the flow of elements, but you need it "docked" to the bottom so that it's size, when it changes, starts bottom up.
I put together a fiddle with your code and some CSS liberties of my own. I also updated your header to have something in it to click. What #NewToJS was pointing out is that you had a header but nothing to click in it.
CSS for position:
.drawer {
bottom: 0;
max-height: 700px;
overflow: hidden;
position: absolute;
width: 100%;
z-index: 5;
}
Fiddle for you: http://jsfiddle.net/eaxkmh73/
Edited: I also forgot to mention you need to be careful with your heights. Part of the CSS liberties I took, aside from changing colors and playing with borders :), was to adjust the drawer and drawer-content heights. As they were, with an absolutely positioned drawer, when it grew the clickable header moved up past the top of the visible area. Obviously this means you can't click it closed. So, make sure you adjust your heights appropriately to keep items in view.
Also, in the future it is very helpful to put together one of these Fiddles yourself and provide the link with your question. That way, we can see exactly what you are experiencing and we can work off of that instead of putting together our own.
Update: After your latest comment I looked at what the script was doing and it looks fairly straight forward. Enough to do on your own with a simple DIY script. I am not sure if there is an advanced piece of functionality you need, but if not, the two Fiddles below offer optional approaches: One toggling a class for CSS transition; one for using jQuery slideToggle.
CSS Transition: http://jsfiddle.net/ceh0t3vv/3/
slideToggle: http://jsfiddle.net/11w2ufdr/2/
I left the option of supplying a 'data-target' attribute to the header if you wanted more flexibility in what you used for the content. But they can be simplified even further.
CSS simplified: http://jsfiddle.net/ceh0t3vv/4/
slideToggle simplified: http://jsfiddle.net/11w2ufdr/3/
Obviously the CSS is adjusted for each of those as well.
Updated Per latest comment, here is an example with positioning and margin applied to elements: http://jsfiddle.net/ceh0t3vv/5/
You could also combine a toggleClass and slideToggle, though you would need way more finesse than I put into this example. This is more of an example of why it might be better to position and z-index the actual drawer from the start, rather than toggle on open/close. Honestly, just less effort:
http://jsfiddle.net/11w2ufdr/4/

Get dimensions of text block via JavaScript, not the size of container's `getBoundingClientRect`

I want to get the size of text inside a container. Let's consider general case when the container has padding and border.
The problem is that getBoundingClientRect returns the size of text PLUS left border and padding, in case the text overflows. Otherwise it returns just the size of border box of the container.
You can get the width if you create a placeholder div with all of the same text formatting options and find it's width.
For instance, I will create a div with the class .hidden that has the same attributes as the original div.
div.container
{
font-size: 16px;
}
div.hidden
{
font-size: 16px;
display: none;
}
Then, using jQuery, copy the contents of .container to .hidden and find the width of .hidden:
$(function(){
$("div.container").each(function(){
$("body").append("<div class='hidden'>"+$(this).html()+"</div>");
var width = $("div.hidden").width();
$("div.width").html("Actual width: "+width+"px");
$("div.hidden").remove();
});
});
JSFiddle
Interesting! You could use javascript to clone the text inside of an empty element offscreen that has 0 padding/margin/border. Then you could get the width of that element.
var txt = document.getElementById('fixed').innerHTML,
clone = document.getElementById('clone');
clone.innerHTML = txt;
var width = clone.offsetWidth;
document.getElementById('output').innerHTML = width;
#fixed {
width: 8em;
height: 8em;
border: .5em solid red;
}
#clone {
margin: 0;
padding: 0;
border: 0;
position: fixed;
left: -9999px;
}
<div id="fixed">asdfkjahsdflkahjsdflkjhasdljfhalsdkjfhalsdkjfhalsdkjfhalksdhjflasd</div>
<div id="clone"></div>
Width of text: <span id="output"></span>
People who had answered here came with a brilliant idea of wrapping the text into a <div> having zero margin, border and padding;
I just developed the idea further. I place the div inside the container, making the text have exactly the same style as it had without wrapper.
JsFiddle
This solution will work almost everywhere. It can be broken by not very encouraged way of writing CSS, like
.container div b {
padding: 5px; /* firing only when test is run */
}
If you do not code CSS in you project like that, you are the lucky one to use my snippet )

How do I achieve equal height divs (positioned side by side) with HTML / CSS ?

I have two divs inside of a container. One on the left, one on the right, side by side. How am I able to make each one be of equal height, even though they have different content.
For example, the right div has a lot of content, and is double the height of the left div, how do I make the left div stretch to the same height of the right div?
Is there some JavaScript (jQuery) code to accomplish this?
You could use jQuery, but there are better ways to do this.
This sort of question comes up a lot and there are generally 3 answers...
1. Use CSS
This is the 'best' way to do it, as it is the most semantically pure approach (without resorting to JS, which has its own problems). The best way is to use the display: table-cell and related values. You could also try using the faux background technique (which you can do with CSS3 gradients).
2. Use Tables
This seems to work great, but at the expense of having an unsemantic layout. You'll also cause a stir with purists. I have all but avoided using tables, and you should too.
3. Use jQuery / JavaScript
This benefits in having the most semantic markup, except with JS disabled, you will not get the effect you desire.
Here's a way to do it with pure CSS, however, as you'll notice in the example (which works in IE 7 and Firefox), borders can be difficult - but they aren't impossible, so it all depends what you want to do. This example assumes a rather common CSS structure of body > wrapper > content container > column 1 and column 2.
The key is the bottom margin and its canceling padding.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Equal Height Columns</title>
<style type="text/css">
<!--
* { padding: 0; margin: 0; }
#wrapper { margin: 10px auto; width: 600px; }
#wrapper #main_container { width: 590px; padding: 10px 0px 10px 10px; background: #CCC; overflow: hidden; border-bottom: 10px solid #CCC; }
#wrapper #main_container div { float: left; width: 263px; background: #999; padding: 10px; margin-right: 10px; border: 1px solid #000; margin-bottom: -1000px; padding-bottom: 1000px; }
#wrapper #main_container #right_column { background: #FFF; }
-->
</style>
</head>
<body>
<div id="wrapper">
<div id="main_container">
<div id="left_column">
<p>I have two divs inside of a container. One on the left, one on the right, side by side. How am I able to make each one be of equal height, even though they have different content.</p>
</div><!-- LEFT COLUMN -->
<div id="right_column">
<p>I have two divs inside of a container. One on the left, one on the right, side by side. How am I able to make each one be of equal height, even though they have different content.</p>
<p> </p>
<p>For example, the right div has a lot of content, and is double the height of the left div, how do I make the left div stretch to the same height of the right div?</p>
<p> </p>
<p>Is there some JavaScript (jQuery) code to accomplish this?</p>
</div><!-- RIGHT COLUMN -->
</div><!-- MAIN CONTAINER -->
</div><!-- WRAPPER -->
</body>
</html>
This is what it looks like:
you can get it working with js:
<script>
$(document).ready(function() {
var height = Math.max($("#left").height(), $("#right").height());
$("#left").height(height);
$("#right").height(height);
});
</script>
I've seen many attempts to do this, though none met my OCD needs. You might need to dedicate a second to get your head around this, though it is better than using JavaScript.
Known downsides:
Does not support multiple element rows in case of a container with dynamic width.
Does not work in IE6.
The base:
red is (auxiliary) container that you would use to set margin to the content.
green is position: relative; overflow: hidden and (optionally, if you want columns to be centered) text-align: center; font-size: 0; line-height: 0;
blue display: block; float: left; or (optionally, if you want columns to be centered) display: inline-block; vertical-align: top;
So far nothing out of ordinary. Whatever content that blue element has, you need to add an absolutely positioned element (yellow; note that the z-index of this element must be lower than the actual content of the blue box) with this element and set top: 0; bottom: 0; (don't set left or right position).
All your elements now have equal height. For most of the layouts, this is already sufficient. My scenario required to have dynamic content followed by a static content, where static content must be on the same line.
To achieve this, you need to add padding-bottom (dark green) eq to the fixed height content to the blue elements.
Then within the yellow elements create another absolutely positioned (left: 0; bottom: 0;) element (dark blue).
Supposedly, if these boxes (yellow) had to be active hyperlinks and you had any style that you wanted to apply to the original blue boxes, you'd use adjacent sibling selector:
yellow:hover + blue {}
Here is a the code and demo:
HTML:
<div id="products">
<ul>
<li class="product a">
<a href="">
<p class="name">Ordinary product description.</p>
<div class="icon-product"></div>
</a>
<p class="name">Ordinary product description.</p>
</li>
<li class="product b">
<a href="">
<p class="name">That lenghty product description or whatever else that does not allow you have fixed height for these elements.</p>
<div class="icon-product"></div>
</a>
<p class="name">That lenghty product description or whatever else that does not allow you have fixed height for these elements.</p>
</li>
<li class="product c">
<a href="">
<p class="name">Another ordinary product description.</p>
<div class="icon-product"></div>
</a>
<p class="name">Another ordinary product description.</p>
</li>
</ul>
</div>
SCSS/LESS:
#products {
ul { position: relative; overflow: hidden; text-align: center; font-size: 0; line-height: 0; padding: 0; margin: 0;
li { display: inline-block; vertical-align: top; width: 130px; padding: 0 0 130px 0; margin: 0; }
}
li {
a { display: block; position: absolute; width: 130px; background: rgba(255,0,0,.5); z-index: 3; top: 0; bottom: 0;
.icon-product { background: #ccc; width: 90px; height: 90px; position: absolute; left: 20px; bottom: 20px; }
.name { opacity: 1; }
}
.name { position: relative; margin: 20px 10px 0; font-size: 14px; line-height: 18px; opacity: 0; }
a:hover {
background: #ddd; text-decoration: none;
.icon-product { background: #333; }
}
}
}
Note, that the demo is using a workaround that involves data-duplication to fix z-index. Alternatively, you could use pointer-events: none and whatever solution for IE.
here is very simple solution with a short css display:table
<div id="main" class="_dt-no-rows">
<div id="aside" contenteditable="true">
Aside
<br>
Here's the aside content
</div>
<div id="content" contenteditable="true">
Content
<br>
geht's pellentesque wurscht elementum semper tellus s'guelt Pfourtz !. gal hopla
<br>
TIP : Just clic on this block to add/remove some text
</div>
</div>
here is css
#main {
display: table;
width: 100%;
}
#aside, #content {
display: table-cell;
padding: 5px;
}
#aside {
background: none repeat scroll 0 0 #333333;
width: 250px;
}
#content {
background: none repeat scroll 0 0 #E69B00;
}
its look like this
Well, I don't do a ton of jQuery, but in the CSS/Javascript world I would just use the object model and write a statement as follows:
if(leftDiv.style.height > rightDive.style.height)
rightDiv.style.height = leftDiv.style.height;
else
leftDiv.style.height = rightDiv.style.height)
There's also a jQuery plugin called equalHeights that I've used with some success.
I'm not sure if the one I'm using is the one from the filament group mentioned above, or if it's this one that was the first google result... Either way a jquery plugin is probably the easiest, most flexible way to go.
Use this in jquery document ready function. Considering there are two divs having ids "left" and "right."
var heightR = $("#right").height();
var heightL = $("#left").height();
if(heightL > heightR){
$("#right").css({ height: heightL});
} else {
$("#left").css({ height: heightR});
}
Although many disagree with using javascript for this type of thing, here is a method that I used to acheive this using javascript alone:
var rightHeight = document.getElementById('right').clientHeight;
var leftHeight = document.getElementById('left').clientHeight;
if (leftHeight > rightHeight) {
document.getElementById('right').style.height=leftHeight+'px';
} else {
document.getElementById('left').style.height=rightHeight+'px';
}
With "left" and "right" being the id's of the two div tags.
This is what I use in plain javascript:
Seems long, but is very uncomplicated!
function equalizeHeights(elements){
//elements as array of elements (obtain like this: [document.getElementById("domElementId"),document.getElementById("anotherDomElementId")]
var heights = [];
for (var i=0;i<elements.length;i++){
heights.push(getElementHeight(elements[i],true));
}
var maxHeight = heights[biggestElementIndex(heights)];
for (var i=0;i<elements.length;i++){
setElementHeight(elements[i],maxHeight,true);
}
}
function getElementHeight(element, isTotalHeight){
// isTotalHeight triggers offsetHeight
//The offsetHeight property is similar to the clientHeight property, but it returns the height including the padding, scrollBar and the border.
//http://stackoverflow.com/questions/15615552/get-div-height-with-plain-javascript
{
isTotalHeight = typeof isTotalHeight !== 'undefined' ? isTotalHeight : true;
}
if (isTotalHeight){
return element.offsetHeight;
}else{
return element.clientHeight;
}
}
function setElementHeight(element,pixelHeight, setAsMinimumHeight){
//setAsMinimumHeight: is set, we define the minimum height, so it can still become higher if things change...
{
setAsMinimumHeight = typeof setAsMinimumHeight !== 'undefined' ? setAsMinimumHeight : false;
}
var heightStr = "" + pixelHeight + "px";
if (setAsMinimumHeight){
element.style.minHeight = heightStr; // pixels
}else{
element.style.height = heightStr; // pixels
}
}
function biggestElementIndex(arr){
//http://stackoverflow.com/questions/11301438/return-index-of-greatest-value-in-an-array
var max = arr[0];
var maxIndex = 0;
for (var i = 1; i < arr.length; i++) {
if (arr[i] > max) {
maxIndex = i;
max = arr[i];
}
}
return maxIndex;
}
I agree with initial answer but the JS solution with equal_heights() method does not work in some situations, imagine you have products next to each other. If you were to apply it only to the parent container yes they will be same height but the product name sections might differ if one does not fit to two line, this is where i would suggest using below
https://jsfiddle.net/0hdtLfy5/3/
function make_children_same_height(element_parent, child_elements) {
for (i = 0; i < child_elements.length; i++) {
var tallest = 0;
var an_element = child_elements[i];
$(element_parent).children(an_element).each(function() {
// using outer height since that includes the border and padding
if(tallest < $(this).outerHeight() ){
tallest = $(this).outerHeight();
}
});
tallest = tallest+1; // some weird shit going on with half a pixel or something in FF and IE9, no time to figure out now, sowwy, hence adding 1 px
$(element_parent).children(an_element).each(function() {
$(this).css('min-height',tallest+'px');
});
}
}

Categories

Resources