Implementing a panning window over an image? - javascript

I'm trying to implement an effect where there is a moving/animating window that pans over a background image such that you can only see a certain section of the image at a time.
Actually, the window itself should not move as it will be a div sitting somewhere on the page - but the effect should be the background moves behind it. The background however, should not take up any space on the DOM (i.e it should not affect any elements around it).
What is the best way to implement this? Should I just create a background image for the window div and then adjust the background-position? Can this be animated using jQuery?
____________________
| |
| IMAGE |
| ___________ |
| | window | |
| |_________| |
|___________________|

UPDATE: jsFiddle for CSS based animation.
Check out this jsFiddle make sure it's what you want.
HTML
<div class="window">
</div>
JS
var position = 135;
$('.window').click(function() {
position += 20;
$(this).css('background-position-x', position);
});
CSS
.window {
background-image: url(image);
display: block;
height: 200px;
width: 200px;
background-position: 135px -40px;
}

Related

How to position the bottom-most container in a grid layout [duplicate]

This question already has answers here:
Fill remaining vertical space with CSS using display:flex
(6 answers)
Closed 2 years ago.
Here's a quick demo of what I have:
https://codepen.io/brslv/pen/RwobvgP?editors=1100
So, there's a .container div, which is a grid with grid-template-rows: 100px auto auto.
I need to be able to:
the whole layout should be the height of the screen (100vh), and the middle div should be scrolling, if the content gets too high.
keep the top-most div fixed height
have the middle div span the whole height of the page minus those 100px for the top div and minus the bottom-most div (which should be "fluid" and expand, depending on the height of the contents in it)
as described above, have the bottom-most div expand, depending on the height of the contents in it (in this case an autosize-able text area), but always stay on the bottom of the grid as small as possible, with, let's say min-height: 100px.
So essentially:
|------------------------------------------
| Section A: 100px
|------------------------------------------
|
|
| Section B: 100% - A - C(variable height)
|
|
|------------------------------------------
| Section C: variable height, min: 100px
| (here is the autosizing text-area)
|------------------------------------------
In my demo It's working as expected (https://codepen.io/brslv/pen/RwobvgP?editors=1100). But, if there is only one or two items in the middle div, it breaks, because the middle div isn't high enough and the bottom most compensates it, which is what I want to avoid.
I want to do it css-only, but if it's not possible I'll have to write a small JS to resize the middle one "by hand"...
Any ideas how to approach the problem with css-only?
You can change your css code and make it:
.container {
height: 100vh;
display: grid;
grid-template-rows: 100px 1fr auto;
}
What do you want is the 1fr. In this way the middle div will fill all the available empty space. See here for details about the fr unit: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout#the_fr_unit

Increase element width with content, but equal width otherwise - CSS

I am trying to make a rating component using multiple mat-button-toggle inside a mat-button-toggle-group in Angular 7. I managed to make them all of equal width using the following CSS:
mat-button-toggle {
width:100%
}
mat-button-toggle-group {
width: 100%;
}
So, this is how it will look normally, with equal width.
1 | 2 | 3 | 4 | 5 |
Now, the app is coded such that the first and the last toggle can have optional descriptive text which helps the user to understand the scale of the rating.
However, using the CSS above, it maintains 20% width for all the individual ratings. I tried width="auto" and while that changes the width depending on the text inside, all the other toggles become really thin, leaving a large white space at the right end of the toggle group.
Eg:
Worst 1 | 2 | 3 | 4 | 5 Best
Is it possible to maintain equal width, but on adding text to the first and last element, increase their width by reducing the width of the ones in between?
Desired final output:
Worst Option possible 1 | 2 | 3 | 4 | 5 Best Option possible |
Thanks.
Use flex
.options {
display: flex;
}
.options > div {
flex: 1;
border: 1px solid gray;
text-align: center;
}
<div class='options'>
<div>1 WORST</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6 BEST</div>
</div>

How can I have vertically fixed div element?

I would like to have vertically but not horizontally fixed div element. Currently, I am using jQuery to update the position top every time scroll occurs, but I don't want it seeing moving. I would like it to be fixed without moving. Is there a way to do this?
-----------------
| | |
| | |
| div A | div B |
| | |
| | |
| | |
-----------------
Scrolling down
-----------------
| div A | |
| | |
| | div B |
| | |
| | |
| | |
-----------------
I would like to be able keep Div B vertically fixed while Div A scrolls down and up. But when I scroll to the right and left, I wand Div A and Div B to move.
I noticed that Twitter uses something similar. Once you click on a tweet, the element on the right that display the tweet detail, is veridically fixed. I am not sure how they are doing it. See the second image, when scrolling down the right panel stays fixed.
Second image:
Twitter uses a css property: position: fixed; which sure is the best way to go.
This does exactly what it says it does, it fixes the position. By using the top, right, bottom and left properties you can set the exact position of your div.
Edit 13-12-11 (awesome date!)
The property position: fixed; can not influence a positioning property over one axis only. This means, that you can not scroll left or right, like you want to.
I highly suggest you should either avoid surpassing the screen width, using percentages for your element's width. You can also just stick to your javascript.
You could however go for the method I suggested at first, but change the left property using a scroll event listener so that when you scroll, the left offset is increased or decreased. Because jQuery's bad-ass cross-browser support I'd go for jQuery. I think you can do practically the same with the prototype library, but I'm not familiar with that library.
jQuery (worked in google chrome):
var offset = 400; // left offset of the fixed div (without scrolling)
$(document).scroll(function(e) {
// b is the fixed div
$('.b').css({
'left': offset - $(document).scrollLeft()
});
});
Have a look at the live demo
You might need to change the document object to another object or selector of your choice.
A whole lot of people want this, but unfortunately pure CSS does not offer a way to accomplish this very simple, very useful task. The only way that I have found is to give the div position:fixed. However, as you have found, this fixes the div on both the x and y axes.
This is a big failing in CSS, in my opinion. We really need something like CSS position:fixed-x and position:fixed-y. The only way I have found to do this is to have a piece of JavaScript code that's entered on a SetInterval( ) timeout (I use .10 second) that repositions the div on the axis that needs to change.
In your case (if I read your question correctly) you'd change the top: of DivB at each SetInterval( ) tick, moving DivB down to the position you want it in the viewport. Easy to do and it works, just a needless pain.
You might ask, and rightly, why you (and I) can't do this manipulation when the scroll event fires. The answer is that the scroll event doesn't fire in some versions of IE.
If you can make this depend upon scroll event cross-browserly, that would be a huge advance.
HTH.
This is easily done with the correct markup and CSS. You need a container (div, section, etc.) to contain your two content areas. In the following example, I exploit the way JSFiddle renders the fiddle's content, but the technique is the same outside of JSFiddle.
Live example.
First, we need the markup:
<div id="container">
<div id="divA">
<p>This div will scroll.</p>
</div>
<div id="divB">
<p>This div will not scroll.</p>
</div>
</div>
Next, the CSS:
#container {
height: 100%;
postition: relative;
width: 100%;
}
#divA {
background: #ccc;
height: 300%; /* So we can see scrolling in action */
left: 0;
position: absolute;
top: 0;
width: 25%;
}
#divB {
background: #c55;
height: 100%;
position: fixed;
right: 0;
width: 75%;
}
In this example, I take advantage of the fact that JSFiddle will create a view port of limited size. Thus, I can specify all of my sizes in percentages.
Notice that I set the container's position to relative. This is so that I can set the position model of divA and divB to "absolute" and "fixed" such that they will be positioned according to the box generated by "container". This is the key part of solving your problem.
use position:fixed as style and set a fixed width for div. also set top and left or right in pixel.

How can I make an my HTML columns adjustable width?

I have a HTML application that works with three columns, each of which is a div in a container object.
| |
A | B | C
| |
I'd like to make it such that the three columns would each be adjustable, and the text would reflow and adjust inside of them.
This works trivially with Frames (See: http://www.tizag.com/pics/htmlT/frameindex.html ), but I'd like to replicate this behavior with my Divs.
Is there a jQuery plugin to do this? The best way I can think of is to create a slider div between the contents, similar to the implementation at http://www.catchmyfame.com/2010/08/12/adjustable-columns-with-jquery/
Is there any easier/cleaner/prettier way? This seems like it has to be a pretty standard request...
A rudimentary way to set them up all the same width:
div {
float: left;
width: 33%;
height: 300px;
overflow: scroll;
}
If you want to allow the user to resize the columns with a drag-n-drop method then you'll want to look into a JS framework. Here's a jQuery example:
http://docs.jquery.com/UI/API/1.8/Resizable

Side border and dynamic content help

I have two side borders on my website, left and right side... small image about 15x15 which repeats itself down the website... When setting 100% like below, the border only goes "one screen" down (which is 100%). But my website is dynamic and the content changes... I want the border to change along with the total height of the page...
How can I do this?
Here is the css:
.bgr_right {
background-image: url(../Graphics/bgr_right.jpg);
background-repeat: repeat-y;
background-position: right;
position: absolute;
top: 0px;
height: 100%;
width: 30px;
right: 0px;
background-color: #E7F5F0;
}
Here is the HTML DIV:
<div class="bgr_right"></div>
Also, is position: absolute the right thing to have?
UPDATE:
After reading the responses, I thought there has to be a better way...
How about using javascipt...
Does anybody know if there is a way to, with javascript, get the height of the body?
then:
<div height="javascript_function()" or something...
???
Thanks again
Alternativly I'd suggest to wrap another two divs around content container and repeat the background aligning it in one div to the left and in the other to the right. I.e.:
<div id="left_wrapper" style="background: url(my_leftimage.png) y-repeat top left;">
<div id="right_wrapper" style="background: url(my_rightimage.png) y-repeat top right;">
<div id="content">hello world</div>
</div>
</div>
Then if you want it to go height 100% set the html, body and the content containers to 100% height like this in the CSS:
html, body, #content { height: 100%; }
Hope this helps :)
At the risk of angry comments and loss of reputation - use a table to contain your layout. You get the full-height borders free - they will automatically adjust to the same height as your content.
<table>
<tr>
<td class="bgr_left"></td>
<td class="content"></td>
<td class="bgr_right"></td>
</tr>
</table>
If you have a fixed-width design, you could just use one background image, either on the body or on your content container, depending on the effect you want. This image would be something like:
(left bar)-> | ([x]px space here) | <-(right bar)
With repeat-y, this would give you:
| |
| |
| |
| content here |
| |
| |
| |
Then the bars will be as high as your content. If you apply this to <body>, then it will have the height of the body.
Hope this helps.
There doesn´t seem to be a reason to use a separate div for the background as it´s empty, but it depends if the column width is fixed.
You should apply the background image to the div you want to have a background, that way you can be sure that it will continue below as the div grows.
If your column width is fixed, you
can just combine the left and right
image in a very wide image that will
only repeat vertically.
If your column width is variable,
you can have for example the left
background in the growing div and
the right one on a wrapper div that
contains the growing div.
Using the right padding you will get the effect you want.

Categories