Handle editable element behind another element - javascript

I am working on a project where it implements an email editor, something like Gmail editor. It has "Recipients and Subject" always on top and the scrollable editor area below it. So, what I want to achieve is:
Let the top part always stay on top at fixed position, even we are scrolling the editor content below
If the content in the editor is too long, scrolling the page down should move the top content behind the top part. At this point, if we keep pressing "Up" key, it should bring the top hidden content back, instead of moving the cursor up.
I have the gif below to explain it better hopefully:
I am able to achieve the first one by using sticky property, but I cannot do the 2nd one. If I type long content inside the editor area, make it partially hidden by the top part, then if I keep pressing "up", it will eventually move the cursor into the top area, thus hiding the cursor, and I am unable to bring the top hidden content back using "Up" key.
div.sticky {
position: -webkit-sticky;
position: sticky;
top: 10px;
background-color: yellow;
padding: 50px;
font-size: 20px;
}
<html>
<div class="sticky">I will stick to the screen when you reach my scroll position</div>
<div contenteditable="true">
</div>
</html>

Utilizing the sticky div as a container for text might help, I also wrote a small helper function for breaks to test the scrolling feature:
div.sticky {
position: -webkit-sticky;
position: sticky;
top: 10px;
background-color: yellow;
padding: 50px;
font-size: 20px;
}
<div class="sticky">
<input placeholder="Recipients">
<br>
<input placeholder="Subject">
</div>
<div contenteditable="true">
<script>
for(var x=0;x<=100;x++){
document.write("<br>") }
</script>
<h1>test</h1>
</html>

Related

How do I get text to appear over a div

Good morning. I am currently working on a final project for my Unix class and it trying to implement some of the stuff learnt through building a web game. One feature that I want to incorporate is the ability to add text over a div as shown in the picture. How would I go about that?
Try including some of your own source code next time, just so we get an idea of what you're having issues with.
But to put text over, try using position: relative, inside a div with a background image of what you want.
Eg.
.parent {
background-image:url("https://picsum.photos/200/300");
width: 800px;
height: 800px;
}
.text {
position: relative;
top: 20px;
left: 40px; /*edit top, left, right, and bottom to change position*/
font-weight: bold;
}
<body>
<div class="parent">
<p class="text">TEXT!</p>
</div>
</body>
If you can't use a background image, try using absolute positioning.
Here's a great tutorial for that: https://www.youtube.com/watch?v=P6UgYq3J3Qs

How do I prevent scrolling the window/body "through" a modal div?

Here is a simplified version of my layout:
<body>
[... a bunch of content ...]
<div id="modal-overlay">
</div>
</body>
body contains enough content that the entire page scrolls.
#modal-overlay is styled like this:
#modal-overlay {
display: none;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
In response to a user action, I'll display the #modal-overlay by setting display: block;
The #modal-overlay then fills the entire viewport.
Here's the trouble...
SOMETIMES, when you swipe vertically on the the #modal-overlay - its content scrolls as it should.
However, SOMETIMES, the body scrolls instead, and the content in #modal-overlay doesn't scroll at all. It's as if I'm scrolling body through the #modal-overlay, which is exactly what I don't want.
In fact - it seems totally random whether #modal-overlay or body scrolls in response to the swipe gesture.
I've read about a few hacks (e.g., applying overflow:hidden to the body but I don't want to do that, since it loses the correct scroll position, and causes other problems as well.) I also would like to have a solution that works with any number of nested layers. I'm really trying to prevent scrolling through the uppermost layer, not fiddling with the underlying layers.
This is particularly problematic on iOS, since scrolling the body reduces the height the browser chrome, which expands the viewport, which messes with the layout of the #modal-overlay, since it's sized to fill the viewport. Aaargh.
Thanks in advance for any advice or guidance!
I haven't tried to achieve this on ios, but you can at least give a try using slimscroll jquery plugin if you are dealing with multiple layers and prevent scrolling of other layers.
Hope it helps
Body should be overflow-hidden and
add dynamically position: absolute; width: 100%; height: 100% CSS properties to other content wrapper (content container inside the body) in the body when modal open.
When open the Modal
<style>
.modal-open {
overflow: hidden;
}
.modal-open .container {
position: absolute;
width: 100%;
height: 100%;
}
</style>
<body class="modal-open">
<section class="container">
Site content will be here
</section>
<div class="modal">
Modal content will be here
</div>
</body>
Add this "modal-open" class dynamically when open the modal and remove it when it close.
Since your modal-overlay covers the body 100%, I believe adding position:fixed to body when you display the #modal-overlay will fix your issue.

Emulating `position: fixed;` with javascript, but without it being jumpy, laggy, or having "hickups"

I'm trying to emulate position: fixed; using javascript, the reason being that the element has to be inside a scrollable div (overflow-scroll-y), and position: fixed; only works relative to the window scroll, not an elements scroll, though normally in a case like this I could fix it by using position: absolute; and everything would just work, but the scollable div / container element needs to have perspective: 1px; which brakes the position: absolute; adjustment, so back to just js emulation.
Now it works, with javascript, but all too often the element in question lags a bit behind the scroll, creating a kind of "jumpy" feeling (it's especially bad on Firefox), that is say it's fixed at the top of the element, if the user scrolls it's suppose to be exactly at the top always, but in reality it sometimes goes a bit (or allot) too high or low, depending on the scrolling direction, and then snaps in place again, this snapping or jumpy effect is undesirable, and is not present in cases where you can fix the element using either position: fixed; or position: absolute;.
I've made a jsFiddle Example, if you don't notice the undesirable effect in your browser you can try uncommenting the increaseLag function, on my computer the lag is clearly visible on Firefox but not as noticeable on Chrome unless I enable the increaseLag function (I'm running Ubuntu).
How could one tackle this? Is there perhaps a pure css solution I'm missing or an alternative js route?
My current buggy solution uses a scroll event on the container element which updates the top css property of the "fixed" element relative to the updated scroll position.
$("#container_element").scroll(function() {
//increaseLag(this);
var scrollTop = $(this).scrollTop();
$(".fixed_emulation").css("top", scrollTop+"px");
});
#container_element {
width: 100%;
height: 100%;
overflow-y: scroll;
perspective: 1px;
}
.fixed_emulation {
background-color: #000;
color: #FFF;
position: absolute;
top: 0;
width: 100%;
}
<div id="container_element">
<div class="fixed_emulation"> :) </div>
<p>Text text text. Text text. Text.</p>
<p>Text text text. Text text. Text.</p>
<p>Text text text. Text text. Text.</p>
...
</div>

Defined clickable region while disabling links within?

I have a site where people can embed instagram videos. I have these show up as thumbnails, and I would like to have an overlay popup (containing the full size video) when they click on the thumbnail. Unfortunately, instagram's embed code comes with built in links and when clicked the video simply plays at the small size.
So my question is: How do I create an invisible overlaying region+link that will ignore the links of the underlying content? (I have the popups coded and working properly, just need to figure out how to disable the links)
Thanks!
You can put a transparent div on top of the links you want to disable and give it a higher z-index.
#links {
position: absolute;
z-index: 999; /* simulating that the target has a manually given z-index*/
}
#maskDiv{
background: rgba(255,255,255,0.6); /* keeping it partially visible to demontrate it's there*/
width: 200px;
height: 42px;
position: absolute;
top: 40px;
z-index:1000; /* needs to be higher than the target div */
}
<div id="links">
A functional link<br />
Another functional link<br />
A link masked by a div<br />
Another<br />
Last one is functional<br />
</div>
<div id="maskDiv"></div>

Need a fixed positioned div inside an absolute positioned div

I'm using the Snap.js plugin - (it allows you to create scrolling side drawers/panels).
It works by creating 3 absolutely positioned divs, one of which contains main content.
Is there a way to position a div fixed to the top of the window when it is itself inside the absolutely positioned div.
At the moment i'm just getting the fixed div to pin to the top of the absolutely positioned div, rather than to the top of the browser. When I scroll, the div remains fixed to the top of the main content, but not the window.
For example:
<div style="position:absolute;">
<div style="position:fixed;top:0">
<!-- some content which needs to be pinned to top of window -->
</div>
</div>
At the moment i'm using javascript to track the scroll offset and manually adjust the top position of the child div, which is not ideal for performance.
Any help appreciated!
I've made a fiddle showing my javascript workaround - it jitters when scrolling in internet explorer, any ideas.
<div id="displayed-content" class="snap-content scrollable">
<div><!-- regular content --></div>
<div><!-- fixed content --></div>
<div><!-- footer content --></div>
</div>
http://jsfiddle.net/bxRVT/
I am guessing a bit about what you are trying to do, but you might be looking for something like this:
<div class="local-wrap">
<div class="fixed">
Some content which needs to be pinned to top of window
</div>
<div class="port">
Regular content...
</div>
</div>
and apply the following CSS:
.local-wrap {
position: relative;
}
.local-wrap .fixed {
position: absolute;
top: 0;
left: 0;
background-color: lightgray;
width: 100%;
height: 5.00em;
}
.local-wrap .port {
position: relative;
top: 5.00em;
min-height: 10em;
height: 15em;
overflow: auto;
border: 1px solid gray;
border-width: 0 1px 1px 1px;
}
Demo fiddle: http://jsfiddle.net/audetwebdesign/pTJbW/
Essentially, to get a fixed block with respect to a block element, you need to use absolute positioning. Fixed positioning is always with respect to the root element or view port, so position: fixed won't help you.
What I have done is define a .local-wrap container, with two child blocks, one which is
positioned absolutely to the top of .local-wrap and the other in regular flow. I used position: relative to position it below .fixed, but a top margin would have also worked.
I fixed some heights to demonstrate scrolling content within the local window/port, but that can be changed depending on your design and application.
Disclaimer
I am not familiar with snap.js so there may be other considerations to consider.
Comment on CSS3 Transform and Fixed Elements
According to the CSS3 specs, if you apply a transform to an element, call it div.transformed, then div.transformed creates a new stacking context and serves as a containing block for any fixed position child elements that it contains, which is why in your scenario, the fixed position context does not stay at top of the window.
For reference, see Mozilla Developer Network -> CSS Reference -> Transform

Categories

Resources