Changing CSS running element counter style after few pages - css

I am generating PDF document using FlyingSaucer with page numbers in running header.
What I am trying to achieve is to be able to change style of counter applied to running element used for header.
Since the CSS is applied by FlyingSaucer I cannot use javascript.
Example html:
<body>
<div id="right-header"/>
<div id="title-page"></div> <!-- page i -->
<div id="toc-page"></div> <!-- page ii -->
<div id="content"> <!-- counter reseted -->
<div id="chapter1">
<!-- page i ( should display 1 instead of i )-->
<!-- page ii ( should display 2 )-->
</div>
<div id="chapter1">
<!-- page iii ( should display 3 )-->
<!-- page iv ( should display 4 )-->
</div>
</div>
</body>
css:
#right-header {
display: block;
text-align: right;
position: running(right-header);
}
#right-header:after {
content: counter(page, lower-roman)
}
#page:right {
#top-right {
content: element(right-header);
}
}
This piece of css correctly applies headers to the whole document after
<div class="right-header"></div>
is placed.
I am trying to start my document with above page styling ( lower-roman )
and after specific place in my document - let's say
I would like to either change content of right-header or replace #page content with different
running element for the rest of the document with styling set to decimal numbers.
I know that FlyingSaucer has limited CSS3 support but I cannot find any solution ( not restricted to only FlyingSaucer) for such problem.
Content of running header can be changed without effect on previous headers as FlyingSaucer allows to reset the counter at any point of the document using css rule.
-fs-page-sequence: start;
and change is visible only after that point.
So my current status is that I have pages numbered with lower-roman i-iv ( for title page, TOC etc. ) and then reset back to i and increment till the end of document. All I need to do is to change
#right-header:after {
content: counter(page, lower-roman)
}
to
.right-header:after {
content: counter(page)
}
or switch displayed running element to the new one.
Another solution I have tried which adds another possibility to solve this problem:
<div id="right-header">
<div id="before"/>
<div id="forcontent"/>
</div>
#forcontent {
display: none <!-- initially not displayed for a few first pages -->
}
#before:after {
content: counter(page, lower-roman)
}
#forcontent:after {
content: counter(page)
}
with this code I think the solution would be to enable #forcontent and disable #before at the beginning of #content.
I have tried working with ~ selector but it doesn't work for changing preceding elements.
Does anybody know how this could be achieved or could point me to different solutions I could try?

While working on something else I found that FlyingSaucer supports css3 named pages (https://www.w3.org/TR/css3-page/#using-named-pages) which allow elements to have different #page definition with another elements set as running headers and footers.
Below is short example how different styling for "introduction" pages can be achieved using this method.
html:
<html>
...
<div id="introduction-right-header-placeholder">...</div>
<div id="content-right-header-placeholder">...</div>
<div class="introduction">
<!-- these pages will have roman letters as page numbers -->
...
</div>
<div class="content">
<!-- these pages will have decimal page numbers -->
...
</div>
...
</html>
css:
#introduction-right-header-placeholder {
text-align: right;
position: running(introduction-right-header);
}
#introduction-right-header-placeholder:after {
content: counter(page, lower-roman)
}
#content-right-header-placeholder {
text-align: right;
position: running(content-right-header);
}
#content-right-header-placeholder:after {
content: counter(page);
}
.introduction {
page: introduction-page;
}
.content{
page: content-page;
}
#page introduction:right {
#top-right {
content: element(introduction-right-header);
}
}
#page content:right {
#top-right {
content: element(content-right-header);
}
}
This example shows how to add differently styled page numbers in FlyingSaucer for right side pages ( I removed left side to reduce amount of code ).

Related

CSS media query print:

Doing a page, html result like:
<div class="container table-page">
<div class="selected-block"> some info here </div>
<h1>Table header</h1>
<div class="notice-calc print-shown">Notices !</div>
<table class="input-data">...</table>
<button class="js-btn-add-row">Add row to a input table</button>
<button class="js-calculate">Calculate table values</button>
<div class="js-waiting" style="display: none;">Progress bar</div>
<table class="calc-result" style="display:none;">...</table>
</div>
Main idea of styles below - hide every direct children of '.container' except tables and some table elements with class="print-hidden" will be hidden too. For print version of page using rule:
#media print {
.container> :not(table),
.print-hidden {
display: none;
}
.print-shown {
display: block;
}
}
Later added notices must be shown at print version too, but it does not appear. Nevertheless if edit '.print-shown' rule like:
.container .print-shown {
display: block;
}
Then it shows. Tested in Chrome 88.0.4324.190 (Official Build) (64-bit)/ Dev.Firefox 86.0b9 (64x)/ Opera 74.0.3911.107. And Edge shows it in both cases.
Why single class selector does not work here?
It is because of this selector:
.container > :not(table)
It targets all direct children of .container (which is not a table). This also includes children with the .print-shown-class.
So, when you have a .print-shown element as a child of .container, the .container > :not(table) has presedence over the .print-shown class (because the first selector is more specific than the latter)

Fullcalendar how to print div: media print

I am using fullcalendar version 4 nicely. I am adding a print button to it. The docs say I don't need to include any other files (like version 3 needed), and I should be able to handle the printing using media queries.
I've been reading about media queries and have come up with some code to work on the print page of the calendar div.
<div class="portlet-body">
<div class='loader'>
</div>
<div class="row">
<div class="col-md-5">
<a id="print_calendar" class="btn btn-xs default">Print</a>
</div>
<div class="col-md-7">
</div>
<br>
<div id="calendar_full" style="padding-left: 10px; padding-right: 15px;">
</div>
</div>
</div>
I pulled some unnecessary code from the above to simplify this. When the user clicks the print link, I just want calendar_full to print.
I am including calendar_full.php on this index page which has my full calendar scripts. In that file, I have this following CSS. I am new to media print CSS, so this is the point I got to isolate only the calendar_full div.
<style type="text/css">
#media print {
body * {
visibility: hidden;
height: 0;
}
#calendar_full,
#calendar_full * {
visibility: visible;
height: auto;
}
#calendar_full {
position: absolute;
left: 0;
top: 0;
height: 100%
}
}
When print is selected, I see something like this:
The calendar NEVER extends past that height, no matter what view I'm in: list, week, etc. Events naturally are cut off, as it seems, to that viewpoint all the time. I don't know if this is a just a CSS issue or if I need to do something more with the full calendar plugin.
I basically need it to expand the entire print range to encompass all of the calendar div events.

How can I make a same class name unique to different pages

I am using single CSS file for all my pages, but I come across with this problem. I have an almost identical (with minor differences) element on two different pages ( let's say home page and about page; This is my CSS codes for a specific element in the Home page, I want to use this for another page with minor differences. How do I name those two classes,
Do I need to use completely separate class names like .home.topcontainer { and .about.topcontainer { etc, or is there any robust way handling this issue?
What is the best way of naming CSS blocks for different pages, if I am using a single CSS file for my whole website to avoid me get confused over class names?
Thanks
CSS
.top_container {
position:relative;
top:3px;
height:144px;
z-index:1;
background-color: #143952;
width: 90%;
left:5%;
right:5%;
font-family: 'Scope One', serif;
overflow:hidden;
min-width:900px;
The best practice is to add some relevant class in body tag (as you can see in several CMS like magento etc.) and then use like this:
<body class="home">
<div class="top_container">
<!-- Do something -->
</div>
</body>
--or--
<body class="about">
<div class="top_container">
<!-- Do something -->
</div>
</body>
now you can use css like:
.home .top_container{}
.about .top_container{}
Let's assume this is your Home page
<div id="home">
<div class="top_container">
//stuff
</div>
</div>
And this is your about page:
<div id="about">
<div class="top_container top_container_about">
//stuff
</div>
</div>
Now, in your CSS file, add the style for the 'top_container' class like so:
.top_container {
//css styles common to the top_container element
}
And then write the style that's unique to the top_container in the about section:
.top_container_about {
//css style unique to the about section
}
This is one way which takes advantage of the 'Cascading' property of a 'Cascading Style Sheet'.
Commonly used practice here is to use a base class and a variation to that base class. That way we use the base css-class for both elements and change it a little by overwriting some values with the variant-class. You didn't specify how you want the top containter to change but here is an example:
.top_container {
background: #000;
color: #fff;
width: 200px;
height: 50px;
padding: 10px;
}
.top_container.top_container--narrow {
width: 100px;
}
<div class="top_container">
Default
</div>
<div class="top_container top_container--narrow">
Narrow
</div>
I add the page name to the body class, and make changes like that using CSS like
.style {
margin: 0;
}
.home .style {
margin: 10px;
}
From what I learned in coding scss, it is better to make your class name a general one. In css only you can make it like this:
CSS
.top-container{
width: 100%;
}
.top-container.about{
width:60%
}
.top-container.contact{
width:30%
}
HTML
home.html
<div class="top-container"></div>
about.html
<div class="top-container about"></div>
contact.html
<div class="top-container contact"></div>
The about class will override whatever style you have in top-container. So its easy to use, short and quite simple. You can use this in making your class name a more general one.
If there are same elements on both pages such as Header then you can use the same class name for them on both pages so that they will look exactly identical on both pages. And for making some changes to those elements you can use different CSS selectors. In the below given code, I have used class and id as selectors.
I HOPE THIS ANSWER MEETS YOUR REQUIRMENTS.
Homepage: header background color is blue.
<header class="top_container" id="home_header">
<!--YOUR WEBSITE HEADER-->
<h1>TITLE</h1>
</header>
<div>
<!--YOUR SITE CONTENT-->
</div>
About page: header background color is red
<header class="top_container" id="about_header">
<!--YOUR WEBSITE HEADER-->
<h1>TITLE</h1>
</header>
<div>
<!--YOUR SITE CONTENT-->
</div>
CSS file:
.top_container{
background-color: blue;
color: white;
}
#about_header{
background-color: red;
}
I would do like so. Cause you might have a .top-container on every page you need to set like a "default" style for .top-container. So CSS Cascading Style Sheet. Cascade from top and if an element needs to be a little different just set the differences in a more specific defined class. Something like so:
.top-container {
/* apply all styles for .top-container */
}
.home.top-container {
/* this .top-container will have all styles from .top-container defined above */
/* so only define all DIFFERENT things for .home.top-container here */
}
.about.top-container {
/* define all DIFFERENT things for .about.top-container here */
/* like before it will always have the .top-container styles */
}

CSS: Target a DIV within a Section based on its ID in a One-Pager

I am working on a one-pager WordPress site, and I need to hide the logo of the page (#logo) on the first section (#home). The whole page is a one-pager, so the first section does not need the logo, in fact it should only appear for the other sections below the first one.
Can this be accomplished using CSS?
If it is, then I also want to change the color of the menu elements for the first section, and be something else for the others.
Short answer: No.
You will need to write some JavaScript or jQuery to determine when the first section (i.e. home section) is no longer in the view window.
The logo is typically within the <header>. It's one element within the HTML markup. It does not have a relationship to the sections. With styling, you position it where you want and then scroll the document to view the rest of the content sections.
I assume with this being a one-pager, you want the <header> to be fixed. It's a good assumption since you want to display the logo in the same spot for each section, except the first one.
How
There are many ways to accomplish this behavior. Essentially, you need to determine if the home section is in the browser window or not. When it is, the logo is hidden; else, it's displayed.
One strategy is:
Set the position where the logo will show by grabbing the 2nd section's position in the document (i.e. its offset().top position).
Then determine where the 1st section is within the window. If it's > showPosition, then it's out of view.
Here's some code to get you started. You'll need to adapt it for your specific needs.
(function ( $, window, document ) {
"use strict";
var sectionContainers,
showPosition = 400;
var init = function () {
initSection();
logoHandler();
}
function initSection() {
sectionContainers = $( '.section-container' );
showPosition = $( sectionContainers[1] ).offset().top;
}
function logoHandler() {
var $logo = $( '#logo' );
if ( $( sectionContainers[0] ).offset().top >= showPosition ) {
$logo.show();
}
$( window ).scroll( function () {
if ( $( this ).scrollTop() > showPosition ) {
$logo.show();
} else {
$logo.hide();
}
} );
}
$( document ).ready( function () {
init();
} );
}( jQuery, window, document ));
body {
color: #fff;
}
.site-header {
position: fixed;
}
.site-logo {
font-weight: bold;
border: 5px solid #fff;
padding: 10px;
}
.section-container {
width: 100%;
height: 400px;
text-align: center;
padding: 50px 5%;
background-color: #627f00;
}
.section-container:nth-child(odd) {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header class="site-header" itemscope itemtype="http://schema.org/WPHeader">
<p id="logo" class="site-logo" itemprop="headline" style="display: none;">Logo</p>
</header>
<section id="home" class="section-container">
this is the home section
</section>
<section id="about" class="section-container">
this is the about section
</section>
<section id="about" class="section-container">
this is the portfolio section
</section>
JSFiddle

JQuery Mobile header styling disappearing on a dynamically generated page

I have a second page that is populated using data from an Ajax call on the home page. The header on this dynamically generated page is missing all its JQuery styling, and I suspect the two are related. This is my HTML for the page being generated:
<div data-role="page" id="breakdownDialog" data-add-back-btn="true">
<div data-role="header" id="cvResultsDialog">
<h3></h3>
<span></span>
</div>
<div data-role="content" id="dialogContent">
</div>
</div>
There is also some CSS styling I have used, which I think needs streamlining, but I don't think is causing the problem. This is because when I comment out this code the header is still missing the styling:
#cvResultsDialog {
width:100%;
text-justify: distribute-all-lines;
}
#cvResultsDialog:after{
content: '';
display: inline-block;
width: 100%;
height: 0;
font-size:0;
line-height:0;
}
#cvResultsDialog > h3 {
display: inline-block;
display:inline;
text-align="left";
}
#cvResultsDialog span {
display: inline-block;
vertical-align: baseline;
text-align="right";
}
I then populate the header (and the page) using the response from an Ajax call from the previous page. The page is populated on the click of a button (#resultsList) linking to this page:
$('#resultsList').on('click', '#cvResults', function() {
//find previous result that matches the filename on the link.
for(var i=0;i<storedResponses.length;i++){
var currentTitle=storedResponses[i].title;
var textClicked=$("h3",this).text();
if(currentTitle===textClicked){
currentResult=storedResponses[i];
}
}
$('#cvResultsDialog h3').text(currentResult.title);
$('#cvResultsDialog span').text(currentResult.percentage);
//this last bit is populating the page, so is irrelevant for this question
$('#dialogContent').empty();
for(var i=0; i<currentResult.profile_json.length; i++){
$('#dialogContent').append(
'<table cellpadding="0" cellspacing ="0" width="100%" style="border: 4px solid transparent;"><tr id="'+
currentResult.profile_json[i].title+'"><td>'+
currentResult.profile_json[i].id+'</td><td align="right">'+
currentResult.profile_json[i].value+'</td></tr>'
);
}
});
Finally here is a picture of the header. You'll notice it doesn't have the JQuery Mobile styling and the back button is missing.
Thanks all!
To get the back button, you need to apply the data-add-back-btn="true" to the header div not the page div.
<div data-role="header" id="cvResultsDialog" data-add-back-btn="true">
Working DEMO
Other than that the header looks correct given the CSS styling you are applying... Perhaps you can tell us how you want the header to be arranged?

Resources