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

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

Related

React onMouseEnter/onMouseLeave used to hover in a map

I'm currently working on a dating website for a school project, but i'm stuck and not sure if i'm on the right way.
On the user profile, i want a list of the photos the user choose to show, and i want a hover on the photo where the pointer is.
In my state i added a listPhotoHover: [ ], a tab that contains variables true or false. listPhotoHover[0] = true means the first photo of the list has a hover, false means no hover.
I map and add a div for every photo with a onMouseEnter( ) that takes the photo index and set it an hover if fired.
The hover appears if listPhotoHover[index] exists, the hover div has an onMouseLeave( ) that takes the photo index and set the hover of the photo as false.
Everything seems to work but i'm not sure if it's the best way to do it, and when i move very fast on every photo the hover is still there i think the onMouseLeave( ) don't run.
Here's my code
Map of every photo :
photos.map((photo, index) => {
return
<div className={`flex row`} key={index} >
<img
className={classes.userPhotos}
src={photo}
alt={`photo de ${name}`}
onMouseEnter={() => { this.haveHover(index) }}
/>
{
listPhotoHover[index]
? <div
className={`
absolute flex center alignCenter
${classes.userPhotos} ${classes.photoHover}
`}
onMouseLeave={
() => { this.removeHover(index) }
}
/>
: null
}
</div>
})
function when onMouseEnter() or onMouseLeave() is fired:
haveHover (index, value) {
const tab = this.state.listPhotoHover
tab[index] = value
this.setState({listPhotoHover: tab})
}
I would like to know why does the onMouseLeave() don't work when my pointer move very fast and also what is the best way to do an hover on a map.
Thank you for your advices and sorry if i don't write english correctly
ps: i checked previous questions and didn't find any answer yet :(
Josephine
I don't believe you need javascript to achieve your desired effect. If it is simply to show something when the image is hovered, you can uses some advanced CSS selectors to do this. Run the snippet below to
html {
font-family: sans-serif;
font-size: 10px;
}
.wrap {
position: relative;
}
.image {
width: 80px;
height: 80px;
}
.imageinfo {
display: none;
width: 80px;
height: 17px;
background: #cc0000;
color: #efefef;
padding: 3px;
text-align: center;
box-sizing: border-box;
position: absolute;
bottom: -13px;
}
/* here's the magic */
.image:hover+.imageinfo {
display: block;
}
Hover the image to see the effect
<div class="wrap">
<img class="image" src="https://www.fillmurray.com/80/80" />
<div class="imageinfo">
Bill Murray FTW
</div>
</div>
I just realized i did it all wrong, i added a className with a '&:hover' on the div containing one photo, and it works. No need javascript :D
I don't know why i wanted to complicate it haha..
className:
ANSWER: {
'&:hover': {
opacity: '0.4',
cursor: 'pointer'
}
}
div with the photo:
photos.map((photo, index) => {
return <div className={`flex row ${classes.ANSWER}`} key={index} >
<img
className={classes.userPhotos}
src={photo}
alt={`${name}`}
/>
</div>
})
Hope my mistake will help some people

Where do these styles come from in reactjs examples on codepen?

Composition-vs-inheritance React
Documentation
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}
https://codepen.io/gaearon/pen/ozqNOV?editors=0010
When you're viewing a pen on CodePen, the styling will most likely be applied by the code in the CSS section. It's possible that there is inline CSS in the HTML, and it's also possible JavaScript is manipulating the styling inline, but in all three instances you'll be dealing with CSS code.
The example you posted is doing all of the styling in the CSS tab. The HTML tab only contains a container for the React elements to render to.
We'll use your FancyBorder function as an example.
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
You're constructing a <div> with the class name of 'FancyBorder-' + props.color, where props.color is a variable that will be used later on.
Continuing with your example, you use the following code to create a welcome dialog:
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1>
Welcome
</h1>
</FancyBorder>
);
}
In this code, you're calling the FancyBorder function and passing through color="blue" which is referenced in the original function as props.color. It now runs 'FancyBorder-' + props.color to generate a class named: FancyBorder-blue.
Now in the CSS section, you'll see your FancyBorder-blue is already setup as a class and has styling applied to it:
.FancyBorder-blue {
border-color: blue;
}
This specific CSS applies a blue border around the box we just created. Hopefully that clears things up.
Figured it out. Those styles when opened in CodePen in edit mode are not visible when tabs are minimized. It's enough to drag them open or change the link so they are opened by default. Just a CodePen feature =)
See the difference:
https://codepen.io/gaearon/pen/ozqNOV?editors=0010
https://codepen.io/gaearon/pen/ozqNOV
.FancyBorder {
padding: 10px 10px;
border: 10px solid;
}
.FancyBorder-blue {
border-color: blue;
}
.Dialog-title {
margin: 0;
font-family: sans-serif;
}
.Dialog-message {
font-size: larger;
}

Changing CSS running element counter style after few pages

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 ).

Lay a .png image partially over (on top of) menu

I have an accordion menu that I have tweaked to suit my needs. My last stumbling block is that I have an image (see attached image) of a FedEx Courier that I need to lay on top of the menu and yet still allow users to click through it to activate (access) the accordion menu. The image is a separate image that is set to the desired alpha as created in Photoshop. The file is merely a snapshot of how it would look if it was the way I wanted it.
If this is even possible, what code would I use and exactly where would I place it? If in the CSS file, where does it go and between which lines?
Original full size Image file
You can apply the css:
pointer-events: none;
to the image above the links.
See fiddle https://jsfiddle.net/4zgcrkyz/
pointer-events: none; is a suitable solution if you do not need to care about IE < 11. More info on compatibility here.
Alternatively you can use elementFromPoint() which has compatibility IE > 5.5
The following trick allow you to select under your cover image without using pointer-events: none;
https://jsbin.com/tuhotagize/edit?html,output
Explanation:
At click on cover image.
Hide cover image temporary.
Get mouse coordinates.
Get HTML element under that mouse coordinates (so you know what under the cover).
Trigger click event on that HTML element.
Show cover image again.
Another alternative solution to your problem, which does not include any JS is:
Trim your image in PhotoShop as should appear inside the menu. Use CSS background-image property on it
Use the courier FedEx image only as CSS background-image the body of your page.
You can achieve the same visual effect using only CSS.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test</title>
<style>
img {
position: absolute;
top: 0;
left: 0;
opacity: 0.4;
}
a {
display: block;
width: 300px;
height: 20px;
background-color: greenyellow;
}
a:hover {
background-color: #FF0000;
}
</style>
<script>
window.app = {
show: function () {
document.getElementById('cover').style.display = '';
},
hide: function () {
document.getElementById('cover').style.display = 'none';
},
event: null,
start: function () {
document.getElementById('cover').addEventListener('click', function (event) {
this.hide();
this.event = event;
var target = document.elementFromPoint(event.pageX, event.pageY);
this.show();
target.click();
}.bind(this));
var links = document.querySelectorAll('a');
for (var i = 0, len = links.length; i < len; i++) {
links[i].addEventListener('click', function (event) {
alert('click on ' + event.target.id);
}.bind(this));
}
}
};
</script>
</head>
<body onload="window.app.start();">
<img id="cover" src="http://placehold.it/200x200" />
<a id="a1">link</a>
<a id="a2">link</a>
<a id="a3">link</a>
<a id="a4">link</a>
<a id="a4">link</a>
<a id="a6">link</a>
</body>
</html>

fixed position menu with changing background colors

I have inherited a project, and have some questions on how to resolve a particular issue.
There is a fixed left sub-nav, seen below. As the user scrolls, there are 6-10 different "sections" that are stacked vertically. The top section has a background-image (seen below), while the remaining sections alternate between white & various colors, such as:
section 1: background-image
section 2: background-color: white
section 3: background-color: blue
section 4: background-color: white
section 5: background-color: green
... etc
The customer wants the menu items to change colors based on what background each item is over at a given time (so as you scroll, it's changing item by item). As you can see in the image, when I scroll from the header to the first content section, I'm moving to a white background, so my menu is white text on a white background (the 5th menu item is moving into the white background).
The guys that worked on this initially used jquery waypoint to trigger wholesale changes to the menu item color when a particular div scrolled to a certain location. This basically works - but only when the entire section is scrolled to the top of the menu (meaning the menu items are white-on-white until the last menu item is scrolled into the section).
Any thoughts on how to handle this?
[EDIT TO ADD]
I thought I made this pretty clear above. We're already using jquery waypoints. The problem is, waypoint cannot trigger on each menu item (primarily since the menu items are not part of the ancestral tree of the content nodes, which prohibits me from passing in a context to the waypoint handler), unless I create a handler for the section div at each offset of every menu item (which are different for each page). This would result in a crazy amount of waypoint handlers being bound, which I don't think is ideal.
Here is an example of what I'm describing. As you scroll, the menu items change all at once. You can see where this is a problem when you're scrolling down from the header into the first content section. The menu items are white. So is the background of the first content section. So until the waypoint is hit, the menu is effectively hidden. What I am looking to do is change the color of each menu item as it "enters" or "exits" a particular content div. I suppose I could do this on window.scroll, but that seems pretty expensive. Was hoping there's something I'm either missing with waypoints, or a better way to do this.
Alright, so I did solve this by creating an event handler at every offset. Given that I have 6-10 menu items per page (so 6-10 sections), I don't really like a solution where I create 36-100 event handlers, so I'm hopeful somebody has a better one (although I'm starting to doubt it).
SO is telling me I need to post code, so here goes:
HTML
<div class="menu">
<ul>
<li>
<a href='#header'>Header</a>
</li>
<li>
<a href='#getting-started'>Getting Started</a>
</li>
<li>
<a href='#zomglaserguns'>Laser Guns</a>
</li>
<li>
<a href='#pewpew'>Pew Pew</a>
</li>
</ul>
</div>
<div id="header" data-menu-color-down='#fff' data-menu-color-up='#000'>
Some header content
</div>
<div class="content">
<div id="getting-started" data-menu-color-down='#000' data-menu-color-up='#fff'>
some content
</div>
<div id="zomglaserguns" data-menu-color-down='#fff' data-menu-color-up='#000'>
laser guns!
</div>
<div id="pewpew" data-menu-color-down='#000' data-menu-color-up='#fff'>
pew pew!!!!
</div>
</div>
JS:
var myObj = {
menuOffsets: {},
pageSections: [],
init: function() {
myObj.initMenuOffsets();
myObj.initSections();
myObj.initWaypoints();
},
initMenuOffsets: function() {
$('.menu a').each(function() {
var self = $(this),
href = self.attr('href'),
menuItemHeight = self.height();
myObj.menuOffsets[href.substring(1, href.length)] = self.offset().top + self.height();
});
console.log(myObj.menuOffsets);
},
initSections: function() {
var header = $('#header'),
sections = $('.content > div');
if(header.length) {
myObj.pageSections.push('header');
}
sections.each(function() {
var self = $(this);
myObj.pageSections.push(self.attr('id'));
});
console.log(myObj.pageSections);
},
initWaypoints: function() {
var menuItemColor,
key,
i = 0,
len = myObj.pageSections.length;
for ( i; i < len; i++ ) {
for ( key in myObj.menuOffsets ) {
if( myObj.menuOffsets.hasOwnProperty( key ) ) {
(function ( key, i ) {
$('#' + myObj.pageSections[i]).waypoint(function(direction) {
var self = $(this);
menuItemColor = self.data('menuColor' + (direction === 'up' ? 'Up' : 'Down'));
$('.menu a[href="#' + key + '"]').css('color', menuItemColor);
}, { offset: myObj.menuOffsets[key] });
})(key, i);
}
}
}
}
};
myObj.init();
SEE-ESS-ESS:
.menu {
position: fixed;
top: 40px;
left: 10px;
color: white;
}
.menu li {
list-style-type: none;
}
.menu a {
color: inherit;
text-decoration: none;
}
.content {
}
#header {
background: black;
color: white;
height: 200px;
padding: 0 120px;
}
#zomglaserguns {
background: green;
color: #777;
}
.content div {
min-height: 300px;
padding: 0 120px;
}
Well, it's not too difficult to set up some ID's on the page, and use those as anchors for when to trigger the background change.
Say you had an HTML structure like this:
<header>
...
</header>
<div id="getting-started" data-background-color="lightBlue">
...
</div>
<div id="afford" data-background-color="red">
...
</div>
<div id="down-payment" data-background-color="green">
...
</div>
<div id="financing" data-background-color="blue">
...
</div>
And now you include jQuery Waypoints
<script type="text/javascript">
(function($) {
$('#getting-started').waypoint(function() {
var $this = $(this);
$('header').css('background-color', $this.data('background-color'));
});
})(jQuery)
</script>
Keep in mind this isn't a complete solution, just something to help poke you in the right direction.

Resources