8

I have the following dummy code:

<!doctype html>
<html>
  <head>
    <style>
      p {font-size: 20px;}
    </style>
  </head>
  <body>
    <script type="text/javascript">
      window.onload = function () {
        var body = document.getElementsByTagName('body')[0],
            p = document.createElement('p'),
            el;

          p.style.height = '20px';
          p.innerText = 'Some Test';

        for (var i = 0, len=30; i<len; i++) {
          el = p.cloneNode(true);
          body.appendChild(el);
        }
      };
    </script>
  </body>
</html>

It's render some

elements and on page preview it looks like the following: enter image description here

I need to add borders to first and last elements to be like the following: enter image description here

Is it possible to make by using CSS and to get work in webkit?

EDIT: To everyone who advise the following css

p:nth-child(1){
 border-top : solid 1px gray;
}
p:last-child{
   border-top : solid 1px gray;
}

or

p:first-child {border-top : solid 1px gray;}
p:last-child {border-bottom : solid 1px gray;}

That dont's work for me because it works accross all pages and looks like this: enter image description here

I need to work in chrome

Erik
  • 14,060
  • 49
  • 132
  • 218
  • An alternative is to calculate the number of `p`s you display in one page and use the `:nth-child()` selector. – otinanai Jul 08 '13 at 12:20
  • How can I calculate it? How can I get height of printing page? – Erik Jul 08 '13 at 12:37
  • If it wasn't for a webkit browser like Chrome I would propose a solution that would add a border to the top and bottom of each page printed. Interested in this? – otinanai Jul 08 '13 at 13:13

4 Answers4

0

You can use two containers and place one at the top of the page and the other one at the bottom. These containers must be placed in position:fixed and they will print in every page. This will work in Firefox, Opera and Internet Explorer but not in webkit browsers.

Demo here


After a few tests, I think the best values for your CSS are the following:

#top {
  height: 2px;
  position: fixed;
  width: 100%;
  top: 0;
  left: 0;
  border-bottom: 1px solid #000;
}
#bottom {
  height: 2px;
  position: fixed;
  width: 100%;
  left: 0;
  bottom: 1px;
  border-top: 1px solid #000;
}
p {
  padding-top: 20px;
}

and your HTML:

<div id="top"></div>
<div id="bottom"></div>
<p>abc</p>
<p>abc</p>
.....
Mike Cluck
  • 31,869
  • 13
  • 80
  • 91
otinanai
  • 3,987
  • 3
  • 25
  • 43
  • @Erik works fine for me in FF and IE. See this html file and print it out: https://dl.dropboxusercontent.com/u/68296155/print.html – otinanai Jul 08 '13 at 13:38
  • Firefox, Opera and IE have the same bug – Erik Jul 08 '13 at 13:54
  • @Erik that's not a bug! I set `top:1px`. If you set `top:0` (or negative value) and add the `padding-top:20px` or `height:20px` on `p` (like your OP has) then you'll see that the border doesn't overlap on `p`. – otinanai Jul 08 '13 at 13:58
  • top:1px? should I need to make p position: absolute? – Erik Jul 08 '13 at 13:59
  • @otinanai: Thus the horizontal rows are just fixed at the top and the bottom of the page. I think OP wants them to be exactly above/below the first/last item of a page? – Stefan Surkamp Jul 09 '13 at 11:51
  • @ШтефанСуркамп There's no way IMO you can achieve this without js, so you can simulate this behavior by adding the borders on the page. Same effect with pure CSS. – otinanai Jul 09 '13 at 12:19
  • @otinanai: As the question was tagged with "JavaScript" I assumed my answer could be a potential solution :) – Stefan Surkamp Jul 09 '13 at 12:29
  • @ШтефанСуркамп The question tags include CSS ..and still I don't see a clear answer other than a thought in your answer. – otinanai Jul 09 '13 at 12:41
0

A more complicated solution would be to calculate the viewable page height (JavaScript, jQuery or the like) for each user and check how many items fit onto one page. Afterwards you can style the desired elements (nth-child(x)). Not the best solution but might work if you have conrete requirements (as a certain browser, OS, ...)

EDIT:

A possible solution could be: http://jsfiddle.net/VKDVd/

HTML: Just a few place-holder divs... Pay attention that you have set your doctype (otherwise $(window).height() will not work properly!)

JavaScript/jQuery:

$(document).ready(function () {

    // when including images in your side you should use $(window).load(function() {[...]} to make sure they are completely loaded before the script calculates the heights

    var pageHeight = $(window).height(); // JS-only and IE-compatible solution see my answer
    var sumElementHeights = 0;
    var count = -3; // ensures that the black border is inside the viewport

    for (var i = 0; i < $('div').length && sumElementHeights < pageHeight; i++, count++) {
        sumElementHeights += $('div').eq(count).height(); // sums up the div heights
    }

    $('div').eq(0).css('border-top', '10px solid black');
    $('div').eq(count).css('border-bottom', '10px solid black');
    // you could add a loop here for each page individually...       
});

PS: You could also add further code that updates the div borders if the viewport size changes (e.g. if the user resizes the browser window).

PPS: You can also play around with the numbers for count - as it certainly depends on the borders you add to the elements.

Stefan Surkamp
  • 972
  • 1
  • 16
  • 31
  • How can I know viewable page height? – Erik Jul 08 '13 at 13:33
  • When using jQuery: $(window).height(); --> returns height of browser viewport (source: http://api.jquery.com/height/) – Stefan Surkamp Jul 08 '13 at 13:44
  • In simple JavaScript you can use var height = window.innerHeight; or var height = document.getElementsByTagName('body')[0].clientHeight; (for IE) – Stefan Surkamp Jul 08 '13 at 13:47
  • @ШтефанСуркамп What if each row doesn't have a specific height? You'll need a script to calculate the height of each row besides the height of the printable page. – otinanai Jul 09 '13 at 12:21
  • @otinanai: Yeah, so? You can calculate the "page height" with the functions mentioned in my second/third comment. The same functions are applicablet to elements, so you can add up each of these to get the sum. – Stefan Surkamp Jul 09 '13 at 12:26
  • I don't see any script in your answer. You just repeated my comment under the OP – otinanai Jul 09 '13 at 12:39
  • Oh, I read that over. Sorry. I will edit my answer with a script in a few secs. – Stefan Surkamp Jul 09 '13 at 12:43
  • @Erik: Maybe my example (see EDIT) is a starting point for a solution? – Stefan Surkamp Jul 09 '13 at 14:34
  • @StefanSurkamp It doesn't work for me. The point is to have a line before the first element of the page and after the last element **when printing**. So basically, you calculate the viewport but you don't (and generally can't) calculate the paper size that is been printed on. My solution works on every paper size you are about to print to. – otinanai Jul 09 '13 at 17:30
  • Ah, now I get it.. Maybe OP wants to utilize *page-break-after* for a fix page break. Unfortunately this does not work in Chrome afaik. – Stefan Surkamp Jul 09 '13 at 18:00
-1

If you do not give a damn about old browsers. Then this will work for you...

@media print
  {
      p:nth-child(1){
          border-top : solid 1px gray;
      }
      p:last-child{
          border-bottom : solid 1px gray;
      }
  }

But if you want this to work with older browsers(especially IE) you'll have to use some JS technique.

mohkhan
  • 11,925
  • 2
  • 24
  • 27
  • 2
    This does not work - nth-child will select the n*th* child *of its parent*, not of the printed page. – LSerni May 15 '17 at 14:51
-3

Try first-child and last-child.

For Instance,

p {font-size: 20px;}
p:first-child {...} /* Add your desired style here */
p:last-child {...} /* Add your desired style here */
Nitesh
  • 15,425
  • 4
  • 48
  • 60
  • this will not be supported in IE8 and below. – mohkhan Jul 08 '13 at 12:06
  • Small sidenote: this does not work in older IE's (ot sure if IE9 supports this). If that is needed, you need a more javascript solution – Martijn Jul 08 '13 at 12:07
  • Also, not sure how first-child is supported, coiuld be replaced bij nth-child(1) – Martijn Jul 08 '13 at 12:07
  • Unfortunately it appyes styles accross all pages but I need to each one – Erik Jul 08 '13 at 12:09
  • http://jsfiddle.net/FDD5P/ - @Erik It applies style to first and last elements as mentioned in OP – Nitesh Jul 08 '13 at 12:11
  • Yes. nth-child as well as first-child both are supported. - @Martijn Older IEs support neither. – Nitesh Jul 08 '13 at 12:11
  • I agree - @mohkhan But then it is CSS3 – Nitesh Jul 08 '13 at 12:12
  • first-child and last-child apply the style to the first and last child of the parent element. This is not what the question asked, which was to apply the style to the first element after a page break or last element before a page break. It would be good if this was possible, maybe even for column breaks too. – thomasrutter May 30 '19 at 03:28