On this page of the document, I need the images to be arranged messily on the page. My approach is to adjust each one via top and left percentage values. The figure elements are behaving strangely. #num1 does not respond to top at all, while #num4 requires extreme values to function, but #num5 is doing just fine. All 6 #num have the same properties. 1-3 are under <div id="divA" class="row"> while 4-6 are under <div id="divB" class="row">
Here is a link to my CodePen .
http://codepen.io/WallyNally/pen/QEZKrV
Here is the mockup I am working toward.
If you have insight as to why these figures are being difficult, or if you have alternative/improved ways of doing this, please let me know.
Also- once these are arranged, I plan to add script will .on(mouseover) push the non-hoveredfigures away from the hovered element. If there is a way of writing the html/css that would be amenable to being handled by script, bonus points for you.
I created example here which do not change format of boxes and images.
So, first image will have still the same format: 3:2.
box(es) are positioned absolutely to document (topleft corner), width is also calculated from document size.
box-border(s) create right format of boxes.
image-wrapper(s) create position for images - and it should be positioned over the hidden corner.
image-size(s) create right format of images
img use object-fit, which is not compatible with all browsers. If you are looking for for something, what will work on every modern browser, you can use background css style. There is also nice workaround, if you also need img tag for SEO (find Solution 2): Is there an equivalent to background-size: cover and contain for image elements?
#boxes-wrapper {
position: relative;
width: 100%;
padding-top: 63.12%;
}
#box1,
#box2,
#box3,
#box4,
#box5,
#box6 {
position: absolute;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
height: 0;
}
.box-border {
position: absolute;
top: 0;
left: 0;
width: 100%;
-webkit-box-shadow: 0 0 0 2px #5f2325;
-moz-box-shadow: 0 0 0 2px #5f2325;
-ms-box-shadow: 0 0 0 2px #5f2325;
-o-box-shadow: 0 0 0 2px #5f2325;
box-shadow: 0 0 0 2px #5f2325;
}
.image-wrapper {
position: absolute;
height: 0;
}
.image-size {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 0;
}
.image-size img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
#box1 {
top: 21.48%;
left: 4.88%;
width: 24.54%;
}
#box1 .box-border {
padding-top: 67.96%;
}
#box1 .image-wrapper {
bottom: -2.5%;
left: -3.05%;
width: 92.52%;
}
#box1 .image-size {
padding-top: 66.46%;
-webkit-transform: translateY(-100%);
-moz-transform: translateY(-100%);
-ms-transform: translateY(-100%);
-o-transform: translateY(-100%);
transform: translateY(-100%);
}
#box2 {
top: 31.36%;
left: 36%;
width: 19%;
}
#box2 .box-border {
padding-top: 67.8%;
}
#box2 .image-wrapper {
top: -7.85%;
left: -10.68%;
width: 92.52%;
}
#box2 .image-size {
padding-top: 66.54%;
}
#box4 {
top: 54.67%;
left: 1.42%;
width: 24.61%;
}
#box4 .box-border {
padding-top: 67.77%;
}
#box4 .image-wrapper {
bottom: -11.38%;
left: 10.74%;
width: 66.94%;
}
#box4 .image-size {
padding-top: 104.12%;
-webkit-transform: translateY(-100%);
-moz-transform: translateY(-100%);
-ms-transform: translateY(-100%);
-o-transform: translateY(-100%);
transform: translateY(-100%);
}
<div id="boxes-wrapper">
<div id="box1">
<div class="box-border">
<div class="image-wrapper">
<div class="image-size">
<img src="http://dummyimage.com/450x300/eee/333333.png" />
</div>
</div>
</div>
</div>
<div id="box2">
<div class="box-border">
<div class="image-wrapper">
<div class="image-size">
<img src="http://dummyimage.com/450x300/eee/333333.png" />
</div>
</div>
</div>
</div>
<div id="box4">
<div class="box-border">
<div class="image-wrapper">
<div class="image-size">
<img src="http://dummyimage.com/450x469/eee/333333.png" />
</div>
</div>
</div>
</div>
</div>
EDIT: Added boxes-wrapper, because of problem with 2nd row.
Related
I am trying to use the parallax effect on a site that has a fixed nav bar at the top of the page. Due to the way the parallax effect deals with overflows, the scroll bar appears to sit underneath the fixed nav bar at the top of the page.
I have included a fiddle to demonstrate this.
I have tried placing the fixed navbar div inside the parallax container. This moves the navbar beneath the scrollbar but also results in the navbar not fixing to the top of the page.
Here is my code so far...
HTML
<div class="navbar">NavBar</div>
<div class="parallax">
<div class="parallax_layer parallax_layer_back">
<img class="backgroundImage" src="https://images.pexels.com/photos/131212/pexels-photo-131212.jpeg?w=1260&h=750&auto=compress&cs=tinysrgb">
</div>
<div class="parallax_layer parallax_layer_base">
<div class="title">Title</div>
<div class="content">Content area</div>
</div>
</div>
CSS
.parallax {
height: 100vh;
overflow-x: hidden;
overflow-y: initial;
perspective: 1px;
-webkit-perspective: 1px;
}
.parallax_layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.parallax_layer_base {
transform: translateZ(0);
-webkit-transform: translateZ(0);
}
.parallax_layer_back {
transform: translateZ(-1px);
-webkit-transform: translateZ(-1px);
}
.parallax_layer_back { transform: translateZ(-1px) scale(2); }
.parallax_layer_deep { transform: translateZ(-2px) scale(3); }
/* Example CSS for content */
* {
margin: 0;
padding: 0;
}
.title {
position: absolute;
left: 10%;
top: 30%;
color: white;
font-size: 300%;
}
.backgroundImage {
width: 100%;
height: auto;
}
.content {
margin-top: 100vh;
width: 100%;
height: 800px;
background-color: #e67e22;
}
.navbar {width:100%; position: fixed; z-index: 999; background-color: red;}
Based on your source code, I have made a few changes. I'll explain step by step.
Assume that your NavBar's height is 50px, I lower .parallax class 50px down by using margin-top:50px;.
Also, we need to change your NavBar's position property from fixed to absolute.
Now there will be 2 scrollbar, one for the body and one for the .parallax contents. To hide the body's scrollbar, which is unnecessary, we can use overflow:hidden; for body tag.
This time, you will see that your NavBar won't cover the scrollbar, but the bottom of the scrollbar is unfortunately unseeable since the contents is shifted 50px from to top. To solve this I use a simple Jquery code to set .parallax height equal to the remaining window's height.
You can have a look at the snippet.
$(document).ready(function(){
$(".parallax").css("height",$(window).height()-50);
});
.parallax {
margin-top:50px;
overflow-x: hidden;
overflow-y: initial;
perspective: 1px;
-webkit-perspective: 1px;
}
.parallax_layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.parallax_layer_base {
transform: translateZ(0);
-webkit-transform: translateZ(0);
}
.parallax_layer_back {
transform: translateZ(-1px);
-webkit-transform: translateZ(-1px);
}
/* Depth Correction */
.parallax_layer_back { transform: translateZ(-1px) scale(2); }
.parallax_layer_deep { transform: translateZ(-2px) scale(3); }
/* Example CSS for content */
* {
margin: 0;
padding: 0;
}
.title {
position: absolute;
left: 10%;
top: 30%;
color: white;
font-size: 300%;
}
.backgroundImage {
width: 100%;
height: auto;
}
.content {
margin-top: 100vh;
width: 100%;
height: 800px;
background-color: #e67e22;
}
.navbar {
width:100%;
position: absolute;
top:0;
z-index: 999;
background-color: red;
height:50px;
}
body{
overflow:hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="navbar"> NavBar </div>
<div class="parallax">
<div class="parallax_layer parallax_layer_back">
<img class="backgroundImage" src="https://images.pexels.com/photos/131212/pexels-photo-131212.jpeg?w=1260&h=750&auto=compress&cs=tinysrgb">
</div>
<div class="parallax_layer parallax_layer_base">
<div class="title">Title</div>
<div class="content">Content area</div>
</div>
</div>
I have two identical elements. The top one, I'm scaling to double the size and then centering over the normal-sized one. I want its inner element to then be scaled back down to normal size and placed exactly where the normal sized element's inner element is placed.
This seems to be impossible. There seems to be no logic in the scaling + translation of position.
How would I do this?
https://jsfiddle.net/0urdrvao/
HTML:
<div class="top">
<div class="inner">
Inner
</div>
</div>
<div class="bottom">
<div class="inner">
Inner
</div>
</div>
CSS:
body, html
{
margin: 0px;
padding: 0px;
width: 100%;
height: 100%;
}
.top,
.bottom
{
position: relative;
top: 0px;
left: 0px;
width: 300px;
height: 300px;
background-color: gray;
z-index: 0;
}
.top
{
position: fixed;
transform-origin: 0 0 0;
transform: translate(-150px, -150px) scale(2);
opacity: .5;
z-index: 1;
}
.inner
{
position: relative;
top: 20vh;
left: 0px;
width: 100px;
height: 40px;
background-color: red;
}
.top .inner
{
/* This doesn't work */
transform: translate(150px,150px) scale(.5);
/* This also doesn't work (doing half)*/
/*transform: translate(75px,75px) scale(.5);*/
/* This also doesn't work (doing double)*/
/*transform: translate(300px,300px) scale(.5);*/
transoform-origin: 0 0 0;
background-color: yellow;
}
Since the top: 20vh will be scaled times 2, the transform-origin should be 0 -20vh.
When reverse a scale/translate you need to go backwards and start with scale and then the translate
.top{
position: fixed;
transform-origin: 0 0;
transform: translate(-150px, -150px) scale(2);
opacity: .5;
z-index: 1;
}
.top .inner{
transform: scale(.5) translate(150px, 150px);
transform-origin: 0 -20vh;
background-color: yellow;
}
Updated fiddle
Or one could do like this, setting origin to 0 0 and transform: scale(.5) translate(150px,150px) translateY(-20vh);
Updated fiddle
I currently have an ng-repeat that looks like this:
<div class="repeaterDiv" data-ng-repeat="item in itemArray">
<div class="wrapper">
<img class="imageClass" ng-src="{{item.image}}"/>
<div class="corner-ribbon bottom-right sticky green shadow">Changed</div>
</div>
</div>
Here is the CSS pulled from this codePen:
.corner-ribbon{
width: 200px;
background: #e43;
position: absolute;
top: 25px;
left: -50px;
text-align: center;
line-height: 50px;
letter-spacing: 1px;
color: #f0f0f0;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.corner-ribbon.sticky{
position: fixed;
}
.corner-ribbon.shadow{
box-shadow: 0 0 3px rgba(0,0,0,.3);
}
.corner-ribbon.bottom-right{
top: auto;
right: -50px;
bottom: 25px;
left: auto;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.corner-ribbon.green{background: #2c7;}
I am trying to figure out how to get the ribbon to be restricted to the wrapper class. Does anyone know how I can do that? so I'm still using the same ribbon, but instead of being in the bottom right of the screen, it is at the bottom right of the image for which it applies?
you need to use relative/absolute position and reset display of .wrapper to shrink on image. Then add overflow:hidden to cut off edges of ribbon:
.corner-ribbon {
width: 200px;
background: #e43;
position: absolute;
top: 25px;
left: -50px;
text-align: center;
line-height: 50px;
letter-spacing: 1px;
color: #f0f0f0;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.corner-ribbon.sticky {
position: absolute;
}
.corner-ribbon.shadow {
box-shadow: 0 0 3px rgba(0, 0, 0, .3);
}
.corner-ribbon.bottom-right {
top: auto;
right: -50px;
bottom: 30px;
left: auto;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.corner-ribbon.green {
background: #2c7;
}
.wrapper {
position: relative;
display: table-cell;/* or inline-block or float */
overflow: hidden;
}
img {
display: block;
}
<div class="repeaterDiv" data-ng-repeat="item in itemArray">
<div class="wrapper">
<img class="imageClass" ng-src="{{item.image}}" src="http://lorempixel.com/300/200" />
<div class="corner-ribbon bottom-right sticky green shadow">Changed</div>
</div>
</div>
The class has fixed positioning.
.corner-ribbon.sticky{
position: fixed;
}
So for exact css you may not be able to attach ribbon to each img, rather ribbon would go to specific place in window only. However, you can adjust css a bit. Make wrapper class relative, and .corner-ribbon.sticky absolute position. Then adjust your css fot top/bottom/left/right properties to align them.
.wrapper{
position: relative;
}
.wrapper .corner-ribbon.sticky{
position: absolute;
/* put top/bottom/left/right values here*/
}
I am trying to find a clean way to float multiple image bubbles around a large image in a circular manner.
There will probably be no more than six bubbles per image, but I want to find a recursive and responsive way to position these bubbles around any sized parent image. These parent images will be equal height/width and no lower than 100px. (100 x 100, 130 x 130, ect..)
Not sure how to do this best while making it responsive to the screen size and supported on all main browsers. I also would prefer if this can be done with pure css/sass, and without an external library.
Code so far: http://jsfiddle.net/qatkr261/1/
HTML
<div id="body">
<div id="background">
<div class="company-container">
<img class="company" src="https://placeholdit.imgix.net/~text?txtsize=10&txt=120%C3%97120&w=120&h=120" />
<img src="https://placeholdit.imgix.net/~text?txtsize=10&txt=50%C3%9750&w=50&h=50" class="company-side-bubble" />
<img src="https://placeholdit.imgix.net/~text?txtsize=10&txt=50%C3%9750&w=50&h=50" class="company-side-bubble" />
<img src="https://placeholdit.imgix.net/~text?txtsize=10&txt=50%C3%9750&w=50&h=50" class="company-side-bubble" />
</div>
<div class="company-container">
<img class="company" src="https://placeholdit.imgix.net/~text?txtsize=10&txt=120%C3%97120&w=120&h=120" />
<img src="https://placeholdit.imgix.net/~text?txtsize=10&txt=50%C3%9750&w=50&h=50" class="company-side-bubble" />
<img src="https://placeholdit.imgix.net/~text?txtsize=10&txt=50%C3%9750&w=50&h=50" class="company-side-bubble" />
<img src="https://placeholdit.imgix.net/~text?txtsize=10&txt=50%C3%9750&w=50&h=50" class="company-side-bubble" />
</div>
</div>
</div>
CSS (#body and #background are just demo containers)
#body {
height:500px;
width:500px;
}
#background {
background:#F9F9F9;
}
.company-container {
display:inline-block;
padding:20px;
}
.company {
border-radius: 80px;
display: block;
height: 130px;
width: 130px;
margin: 15px auto;
background:#E5E5E5;
}
.company:hover {
transform: scale(1.2);
cursor:pointer;
}
.company-side-bubble {
border-radius: 30px;
width: 40px;
height: 40px;
position:absolute;
top:0;
border: solid 1px red;
}
.company-side-bubble:hover {
transform: scale(1.2);
cursor:pointer;
}
.company-side-bubble:nth-of-type(2) {
margin-top: 15px;
margin-left: 44px;
}
.company-side-bubble:nth-of-type(3) {
margin-top: 34px;
margin-left: 91px;
}
.company-side-bubble:nth-of-type(4) {
margin-left: 109px;
margin-top: 81px;
}
You can do that using percents instead of pixels as unit.
Also you will need to to use translateX and translateY to compensate for the small images width and height.
Here, i have done it for you: http://jsfiddle.net/qatkr261/2/
.company-side-bubble:nth-of-type(2) {
top: 0%;
left: 50%;
transform: translateX(-50%) translateY(25%);
}
.company-side-bubble:nth-of-type(3) {
top: 25%;
right: 25%;
transform: translateX(50%) translateY(-50%);
}
.company-side-bubble:nth-of-type(4) {
right: 0%;
top: 50%;
transform: translateX(-25%) translateY(-50%);
}
.company-side-bubble:nth-of-type(5) {
top: 75%;
right: 25%;
transform: translateX(50%) translateY(-50%);
}
.company-side-bubble:nth-of-type(6) {
bottom: 0%;
left: 50%;
transform: translateX(-50%) translateY(-25%);
}
.company-side-bubble:nth-of-type(7) {
bottom: 25%;
left: 25%;
transform: translateX(-50%) translateY(50%);
}
.company-side-bubble:nth-of-type(8) {
top: 50%;
left: 0%;
transform: translateX(25%) translateY(-50%);
}
.company-side-bubble:nth-of-type(9) {
top: 25%;
left: 25%;
transform: translateX(-50%) translateY(-50%);
}
I have altered also some css on other classes to make it work, most important: .company do not have top:0 anymore and it's margin now is uniform (all four sides equal) and have grown, .company-container lost padding (compensated by .company margin) and gained position:relative
UPDATE:
If you want the bubbles to spread as well you will need to make additional selector for each one as follows:
.company:hover ~ .company-side-bubble:nth-of-type(2) {
top: -5%;
}
.company:hover ~ .company-side-bubble:nth-of-type(3) {
top: 20%;
right: 20%;
}
.company:hover ~ .company-side-bubble:nth-of-type(4) {
right: -5%;
}
...
I'm scaling a div up with the transform property, but I want to keep its children (which have 1px width or height) the same size. I counter-scaled them by .5, with the expected result that an element of 1px scaled by 2, and then .5, should end up back at 1px, but they wind up a blurry 2px.
Here's the box before scaling it:
.container {
width: 200px;
height: 200px;
margin: 100px;
background-color: #EEE;
position: absolute;
}
.outline {
position: absolute;
background: #1899ef;
z-index: 999999;
opacity: 1 !important;
}
.outlineBottom, .outlineTop {
width: 100%;
height: 1px;
}
.outlineLeft, .outlineRight {
height: 100%;
width: 1px;
}
.outlineRight {
right: 0px;
}
.outlineBottom {
bottom: 0px;
}
<div class="container">
<div class="outline outlineTop"></div>
<div class="outline outlineRight"></div>
<div class="outline outlineBottom"></div>
<div class="outline outlineLeft"></div>
</div>
As you can see, the elements at the edges are a clear, dark 1px blue. Here's what the box looks like after scaling, though:
.container {
width: 200px;
height: 200px;
margin: 100px;
background-color: #EEE;
position: absolute;
transform: scale(2);
}
.outline {
position: absolute;
background: #1899ef;
z-index: 999999;
opacity: 1 !important;
transform: scale(.5);
}
.outlineBottom, .outlineTop {
width: 100%;
height: 1px;
transform: scale(1,.5);
}
.outlineLeft, .outlineRight {
height: 100%;
width: 1px;
transform: scale(.5,1);
}
.outlineRight {
right: 0px;
}
.outlineBottom {
bottom: 0px;
}
<div class="container">
<div class="outline outlineTop"></div>
<div class="outline outlineRight"></div>
<div class="outline outlineBottom"></div>
<div class="outline outlineLeft"></div>
</div>
And here's a post-scaled render from Chrome 41.0.2272.89 Mac, which is what I'm running.
Adding transform-3d(0, 0, 0) didn't appear to help. A solution was found using the zoom property, but since zoom isn't well supported I'd like to avoid that. Adding filter: blur(0px); didn't appear to have any effect either.
It was posited in chat that perhaps the children are first scaled to .5 and then doubled in size, causing them to be scaled down to .5px and then back up from there. Is there any way to ensure the order that they're rendered in causes them to first be scaled up to 2px and then halved? Against my better judgement, I tried forcing the render order with JS, but unsurprisingly, that didn't have any effect (though, interestingly, the bottom element did maintain its original color).
Failing that, are there any other solutions floating around out there? I can't be the only one who's run into this problem.
It is to do with the default transform-origin on the scaled elements. It defaults to 50% 50% for any element being transformed, but this has issues when scaling down 1px values as it has to centre the scale on a half pixel and the rendering of the elements has issues from here on out. You can see it working here with the transform-origin moved to the relevant extremes for each item.
A bit of playing about shows that this same blurring happens on scaled elements for any dimension where the scaling ends up halving a pixel.
body {
padding: 1em;
}
.container {
width: 200px;
height: 200px;
margin: 100px;
background-color: #EEE;
position: absolute;
transform: scale(2);
}
.outline {
position: absolute;
background: #1899ef;
z-index: 999999;
opacity: 1 !important;
}
.outlineBottom, .outlineTop {
width: 100%;
height: 1px;
transform: scale(1, 0.5);
}
.outlineBottom {
bottom: 0;
transform-origin: 0 100%;
}
.outlineTop {
transform-origin: 0 0;
}
.outlineLeft, .outlineRight {
height: 100%;
width: 1px;
transform: scale(.5,1);
}
.outlineRight {
right: 0px;
transform-origin: 100% 0;
}
.outlineLeft {
left: 0px;
transform-origin: 0 0;
}
<div class="container">
<div class="outline outlineTop"></div>
<div class="outline outlineRight"></div>
<div class="outline outlineBottom"></div>
<div class="outline outlineLeft"></div>
</div>