How to achieve parallax effect with grandchildren - html

I've achieved the parallaxing background effect a few times before on codepen's and small, experimental projects.
This is my favorite tutorial on it - https://keithclark.co.uk/articles/pure-css-parallax-websites/
Here's the markup from the referenced tutorial:
<div class="parallax">
<div class="parallax__layer parallax__layer--back">
...
</div>
<div class="parallax__layer parallax__layer--base">
...
</div>
</div>
And the vital CSS bits:
.parallax {
...
perspective: 1px;
}
.parallax__layer--base {
transform: translateZ(0);
}
.parallax__layer--back {
transform: translateZ(-1px);
}
Basically - The .parallax element has a perspective, which essentially means it can view things in 3d space.
The .parallax__layer--base(which is the foreground layer) is placed at 0 on the z-axis. So it hasn't moved from it's origin.
The .parallax__layer--back (the background layer) is placed one pixel back on the z axis.
So now, when you scroll through the .parallax element, you can see these background and foreground layers moving in a 3d space, which gives the parallax effect.
But it only works if you are scrolling through the .parallax element - What about on a full-sized, robust page?
<div class='home'>
...
<div class="parallax">
<div class="parallax__layer parallax__layer--back">
...
</div>
<div class="parallax__layer parallax__layer--base">
...
</div>
</div>
...
</div>
The css and markup haven't changed. But now I'm scrolling through the .home element, and not the .parallax element. The foreground and background layers are still in a 3d space, but it's only relative to the .perspective element.
Is there a way to somehow pass that perspective down to the homepages grandchildren, or great grandchildren? Or do I need to divide my entire page into foreground and background sections in order to achieve this effect?

I came up with a "hacky" way of achieving this with JavaScript.
Here's a rundown of the steps (you may call it the algorithm):
listen for the window scroll event
wait until the parallax container (parent of what you defined as base and back) is in view
in my case, I fixed back and changed top value of base over a transition duration.
Here's my implementation (specific to my use case):
/**
* hacky parallax effect
*/
const viewportHeight =
'innerHeight' in window
? window.innerHeight
: document.documentElement.offsetHeight
const headerHeight = document.querySelector('header').offsetHeight
window.onscroll = () => {
const preFooterPosition = document
.querySelector('.pre-footer')
.getBoundingClientRect()
/** start parallax when pre-footer is in view */
if (
preFooterPosition.top <= headerHeight &&
preFooterPosition.bottom >= viewportHeight
) {
// parallax
document.querySelector('.content').classList.add('transform-content')
} else {
// reverse parallax
document
.querySelector('.content')
.classList.remove('transform-content')
}
}
.content {
display: flex;
flex-direction: column;
flex: 1;
z-index: 1;
position: relative;
top: 0;
transition: top 1s ease;
}
.transform-content {
top: -5rem;
}
.watermark {
position: absolute;
z-index: 0;
flex: 1;
display: flex;
}
<template>
<section class="pre-footer">
<div class="wrapper">
<div class="watermark">
<SVGIcon class="watermark-left" icon="LearnLongShort" />
<SVGIcon class="watermark-right" icon="FreeEducation" />
</div>
<div class="content">
<div class="content-left content-wrapper">
<div>
<h3 class="title">Evidence base</h3>
<div class="body">
<p>The Academy of Medical Cannabis Evidence Base is an advanced referencing tool for CBMP research. Containing the history of research to date and all emerging findings, this cutting-edge engine underpins our learning content.</p>
</div>
<WhiteButton text="View database" />
</div>
</div>
<div class="content-right content-wrapper">
<div>
<h3 class="title">White Papers</h3>
<div class="body">
<p>Alongside our learning platform, The Academy publishes a series of authoritative papers discussing the core topics and themes related to CBMPs. Register to view and download the archive.</p>
</div>
<WhiteButton text="Archive" />
</div>
</div>
</div>
</div>
</section>
</template>
I hope that helps. Let me know when you come up with a better solution.
In the meantime, I'm pushing this.
Cheers!

Related

Making iframe fit into an element that has left-margin set

Hi all I think this should be a relatively quick question but since I am a beginner to HTML and CSS I can't seem to figure this out.
I have the following CSS code:
<style>
div.specialspecial {
width: 100%;
height: 0;
padding-bottom: 56%;
position: relative;
margin-left: 160px;
}
iframe {
width: 90%;
height: 100%;
position: absolute;
display: block;
}
</style>
And this html code:
<div class="specialspecial">
<iframe src='dirToLocalHTML' id = 'bg'></iframe>
</div>
It seems that the margin-left set in the div class (which I need as I am using a sidebar on this website) makes it so the content inside the iframe is off center (presumably by 160px). Is there a way for me to use CSS to easily fix this? Or will I need to resort to JavaScript to resize the frame? I am comfortable with learning either approach.
Edit:
Apologies for not providing enough information. Hopefully adding this will help:
This is the body of my html:
<body>
<div class="w3-sidebar w3-bar-block w3-light-grey w3-card-2" style="width:160px;">
<button class="w3-button w3-block w3-left-align" onclick="myAccFunc('demoAcc')">
Accordion <i class="fa fa-caret-down"></i>
</button>
<div id="demoAcc" class="w3-hide w3-white w3-card-2">
Link
Link
</div>
</div>
<div class="specialspecial">
<iframe src='dirToLocalHTML' id = 'bg'></iframe>
</div>
</body>
This code is mainly taken from the example of: https://www.w3schools.com/w3css/tryit.asp?filename=tryw3css_sidebar_accordion
As I am trying to get a similar style for my webpage
I think the best fix is to simply create a container for the iframe that isolates it from the element with the large margin:
<div class="specialspecial">
<div class="pageContent">
<iframe src='dirToLocalHTML' id = 'bg'></iframe>
</div>
</div>
Even with no additional CSS, this should restrain the size of the iframe, which will get its size from the element without the large margin.
It's worth noting that layouts like that, which rely on large margins for side content, are somewhat archaic. Each part of the document should be contained in an element that doesn't care what's happening around it.
<style>
.page-container > * {
display: inline-block;
}
.page-sidebar {
width: 160px;
}
<div class="page-container">
<nav class="page-sidebar"></nav>
<main class="page-content"></main>
<div>
See also: http://www.developer.com/lang/understanding-the-proper-way-to-lay-out-a-page-with-html5.html

HTML & CSS working with images of different shapes

As some of you guys may know allowing users to upload images can be a hassle and especially if you have to create some sort of list with them.
I have been looking all over the web and have been unable to find concrete answers to what you do in the case where you need to show a list of images of different shapes. Therefor i turn to you.
Say User 1 uploads the following image:
And User 2 uploads this image:
As you can see these two images are very different in both height and width.
Now lets say that you have 10 images of different sizes and wish to display them in a grid 4 by 4 (for this purpose i use ng-repeat to show a loop)
<div class="col-xs-4" ng-repeat="image in images">
<img alt="" ng-src="{{image}}">
</div>
if you do this, this will create a list that is uneven! and will look very "ugly" to say the least.
So my question is what do you do? Are there any tricks using CSS to make it fit any images of any size so that everything is aligned?
I hope my description of the problem was accurate enough for the sake of demonstration here is a fiddle that shows this issue as well.
In short how do i make sure they are all the same size without making one of the images look cramped and / or distorting the individual image?
fiddle
As mentioned in my comment, one option is to crop all the images to a suitable format, a square might be a good compromise. You can do this by wrapping your images in a container first, and positioning the image in relation to the container. Example:
/* Latest compiled and minified CSS included as External Resource*/
/* Optional theme */
#import url('//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css');
body {
margin: 10px;
}
.image-container {
width: 150px;
height: 150px;
overflow: hidden;
position: relative;
padding: 20px;
}
.image-container img {
width: 100%;
height: auto;
position: absolute;
margin: auto;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
<div class="col-xs-12">
<div class="col-xs-4">
<div class="image-container"><img src="http://pngimg.com/upload/girls_PNG6448.png" width="100%" height="100%" class="image image-responsive"></div>
</div>
<div class="col-xs-4">
<div class="image-container">
<img class="image image-responsive" width="100%" height="100%" src="http://yeemei.mobile9.com/download/media/442/niceandsim_s8mhs1do.jpeg"></div>
</div>
<div class="col-xs-4">
<div class="image-container">
<img src="http://pngimg.com/upload/girls_PNG6448.png" width="100%" height="100%" class="image image-responsive"></div>
</div>
<div class="col-xs-4">
<div class="image-container">
<img class="image image-responsive" width="100%" height="100%" src="http://yeemei.mobile9.com/download/media/442/niceandsim_s8mhs1do.jpeg"></div>
</div>
</div>
</div>
Fiddle
You can also position the image in the container. For example if you wanted to center it you could add:
top: -100%;
bottom: -100%;
left: -100%;
right: -100%;
One solution is to provide the users with a cropper to your preferred ratio and allow them to select the part of the image to show.
An alternative is to use the images as background on a div with specific ratio and hope that it does not show irrelevant areas.
Here is a solution for the second case (with a - just for laughs - animation to show the whole of the image)
http://jsfiddle.net/mrccf3sv/
.image{
display:block;
background: url('') 50% 0% no-repeat;
background-size:cover;
border:1px solid #ccc;
animation:pan 10s linear infinite alternate;
}
.image:before{
content:'';
display:block;
padding-top:56.25%; /*ratio of 16:9*/
}
And see it responsive by using different bootstrap column count for each breakpoint.
http://jsfiddle.net/mrccf3sv/1
Scaling with CSS is incredibly bad practice. I mean, we all have to do it sometimes, but if you CAN scale server-side, better do that. Try PHP's imagick, if available.

Zurb-Foundation CSS clip property

I want to clip an img element from a CMS when it renders on the page so that, no matter the proportion of the XY dimensions of the original image, it looks the same as other buttons on the same page. The problem is when I build it with the following code, the Foundation grid breaks on smart phones and other mobile devices. Any suggestions?
.clipsquare {
overflow: hidden;
clip: rect(0px,60px,60px,0px);
position: absolute;
}
<div class="one columns">
<a class="th" href="http://my-url">
<div class="clipsquare"><img src="myImage.jpg" alt="title" width="90"></a></div>
</a>
</div>
class .one.columns on your div with the clipsquare image isn't correct foundation classes. In a standard 12 column layout you would do the following:
<div class="row">
<div class="large-12 columns">
<!-- Column content here -->
</div>
</div>
Further, there are two other questions I'd ask here:
Why aren't you using CSS to style your buttons? and/or...
Why aren't you letting your CMS resize your images for you?
clip has been deprecated. The new property that does the same thing and even more is called clip-path. It has few gotchas though,
AFAIK rect() doesn't work either. You need to use inset().
Dimensions need to be separated by space and not commas(,).
Webkit needs a prefix and positioning is not required.
Example,
.clipsquare {
overflow: hidden;
-webkit-clip-path: inset(0 60px 60px 0);
clip-path: inset(0 60px 60px 0);
}
For more information, on this topic, refer this excellent article on CSS Tricks,
http://css-tricks.com/clipping-masking-css/

Hyperlink not responding

My landing page has a slideshow with text and links that direct the visitor to it's corresponding page.
Landing page link: http://karenrubkiewicz.com/martin/
The yellow arrow in the second box should be a clickable link, but it doesn't respond.
Here is my coding:
HTML
<div id="maximage">
<div>
<img src="images/00_landing page/backgrounds/background_01.jpg" alt="" width="1400" height="1050" />
<div class="in-slide-content">
PLACES
</div>
<a class="in-slide-content2" href="places.html"><img src="images/arrow.png" height="20px"></a>
</div>
<div>
<img src="images/00_landing page/backgrounds/background_02.jpg" alt="" width="1400" height="1050" />
<div class="in-slide-content">
PLACES
</div>
<a class="in-slide-content2" href="places.html"><img src="images/arrow.png" height="20px"></a>
</div>
ETC...
</div> <!--END MAXIMAGE DIV-->
CSS
#maximage {
/* position:fixed !important;*/
display:block;
}
.in-slide-content {
font-family: 'Oswald', sans-serif;
font-size:16pt;
letter-spacing:1px;
position: absolute;
right:63px;
bottom:240px;
width: 220px;
background: rgba(0,0,0,0.8);
color:#FFF;
text-align:center;
text-decoration:none;
padding-top:23px;
padding-bottom:23px;
-webkit-font-smoothing:antialiased;
}
.in-slide-content2{
position: absolute;
right:63px;
bottom:162px;
width: 220px;
background: rgba(0,0,0,0.8);
text-align:center;
padding-top:25px;
padding-bottom:25px;
-webkit-font-smoothing:antialiased;
}
.in-slide-content2 a{
position: relative;
display:block;
}
I am using a maximage plugin, I am not sure whether that could be a possible cause of inference.
One more note, in my HTML, when I remove a certain div, the link begins to work, only then my slideshow falls apart.
EXAMPLE
<div id="maximage">
<div> <----REMOVE THIS DIV
<img src="images/00_landing page/backgrounds/background_01.jpg" alt="" width="1400" height="1050" />
<div class="in-slide-content">
PLACES
</div>
<a class="in-slide-content2" href="places.html"><img src="images/arrow.png" height="20px"></a>
</div> <-----AND REMOVE THIS DIV
ETC...
</div> <!--END MAXIMAGE DIV-->
I'm really stuck on this one.
Thanks in advance!
Place this in CSS:
#nav {
z-index: 2;
}
body .mc-cycle {
z-index: 0;
}
If it wont help, then this:
#nav {
z-index: 2 !important;
}
body .mc-cycle {
z-index: 0 !important;
}
Looking at your codes on your site, (which btw look different from what you posted here), I think things get complicated when your in-slide-content and in-slide-content2 divs are enclosed in your mc-image with its background set to your image file (instead of using an img tag).
This is what your current codes look like:
<div class="mc-image " ... background-image: url(http://karenrubkiewicz.com/martin/images/00_landing%20page/backgrounds/background_01.jpg);" data-href="">
<div class="in-slide-content">PLACES</div>
<a class="in-slide-content2" href="places.html"><img src="images/arrow.png" height="20px"></a>
</div>
Try convert your mc-image to an image tag and extract your in-slide-content and in-slide-content2 out of your maximage.
I think this live demo on jsfiddle is very similar to what you are trying to do.
The reason why manipulating the z-index attribute (of the image, the anchor tag etc.) in your css script probably won't work is because the jquery.cycle.all.js script assigns all your images with some high value z-index on start-up so that they can stack on top of each other.
// line 295 - 303
// set position and zIndex on all the slides
$slides.css({position: 'absolute', top:0, left:0}).hide().each(function(i) {
var z;
if (opts.backwards)
z = first ? i <= first ? els.length + (i-first) : first-i : els.length-i;
else
z = first ? i >= first ? els.length - (i-first) : first-i : els.length-i;
$(this).css('z-index', z)
});
As the script cycles through your images, some codes (I haven't figured out where yet) will reset the z-index of that image to z+1, so that current image will be stack on top of the rest. I tried setting the z-index of some of your HTML elements to some ridiculous high number but to no avail. Anyway, I still think the cleanest way to solve this is to look at the fiddle I shared.

Even out space layout (table)

For a web application I'm creating (in Umbraco, but don't think that really matters in this case) I need a page that can show an overview of different media types; audio, video and images.
No problem there, for images and videos (hosted on YouTube) I will show a thumbnail and for audio I will show a static image.
The rough layout of an item will be that the image is shown on top, and below that is some info like the title and a short description.
Now because of the difference in dimensions of the images (thumbnails can have a variable size, the audio static image will probably always be smaller than the thumbnails, etc.) one item (or column if you will) can be of less width than another.
What I would like to do is show three items per row, and when the row isn't completely filled I would like to fill it up with a colored box. But that box should not always be at the end, it could also be in between, or the beginning. It just is inserted 'randomly' when a space fill is needed.
Because a picture says more than 1000 words (wire-frame of what I'm trying to describe);
Now my question; is this at all possible? If yes, how?
I can't wrap my mind around it, it can't be done in pure HTML and CSS I think. Because you couldn't determine how big an item is and if a 'filler' is needed.
The rough HTML I have right now is something like this:
<table id="portfolio">
<tr>
<td>
<div class="portfolioItem">
<div class="portfolioItemImage">
<a rel="prettyPhoto" href="http://www.youtube.com/watch?v={video}"><img src="http://img.youtube.com/vi/{video}/1.jpg"/></a>
</div>
<br clear="both" />
<div class="portfolioItemDescription">
<h3>Title</h3>
<p>Description lorem ipsum etc.</p>
</div>
</div>
</td>
</tr>
</table>
Of course there is some more dynamic stuff in there to determine whether it is a video, audio or image, determine when to start a new row, etc. but that isn't relevant here.
Here is the CSS associated with it:
#portfolio {
width:100%;
}
#portfolio td {
width:33%;
}
#portfolio .portfolioItem {
border: 1px solid #000;
}
#portfolio .portfolioItem .portfolioItemImage {
margin:0px;
padding:0px;
}
Again; can this be done? And how?
Thank you!
I think that what you want is jQuery Masonry or the Wookmark jQuery Plugin.
I would create the grid using DIVs instead of TABLES, regardless I think this is what you are looking for?:
#portfolio td
{
min-width:33%;
}
EDIT:
Here is a rudimentary example of a grid created with DIV's:
http://jsfiddle.net/rdtnU/
<div class="con">
<div class="row">
<div class="cell">a</div>
<div class="cell">b</div>
<div class="cell is_last">c</div>
</div>
<div class="row">
<div class="cell">d</div>
<div class="cell">e</div>
<div class="cell is_last">f</div>
</div>
</div>
.con {}
.row { width:340px; margin:0 0 20px 0; overflow:hidden; }
.cell { width:100px; margin:0 20px 0 0; float:left; background:orange; }
.is_last { margin:0; }​
I would use the div's as suggested but I would not limit myself to the row/columns as stated. I would use a more fluid layout even if it is for a specified width of a certain section.
The following will only work if you know the width of the div with the content, to allow the floating to occur (this could work if there is a min-width or if your code can determine the size of the image)
Here is the HTML
<div class="elements">
<div class="singleElement">
text and graphics here.
</div>
<div class="singleElement">
text and graphics here.
</div>
<div class="singleElement">
text and graphics here.
</div>
<div class="singleElement">
thisonewillpushthewidthoftheboxfartherthanthe150pxwidth
</div>
<div class="singleElement">
small text
</div>
</div>
Here is the CSS (I put some simple background colors so you can see what is going on with the width and how things are tucked in where space is available.
.elements { overflow: hidden; width: 500px; background: #FCC; }
.singleElement { padding: 5px; white-space:nowrap; float: left;
height: 200px; min-width: 100px; background: #CCC;margin: 0 10px 10px 0; }
Please note the details of the styles are just for demonstrating the example. They can be altered to fit your need.
EXAMPLE: Here is the example in jsFiddle.