How to define and position elements with CSS inside other elements - html

I am working on a drag and drop query designer using HTML5 with AngularDart and CSS. For this issue all I really need to figure out is how to format the objects in HTML5 and CSS. I am running into formatting/positioning issues with the object in CSS. If you look below I have a div with the class "queryElement". The queryElementLine, queryElementHead, and queryElementBody sections of the object were already in this object and were formatting/positioning properly.
This UI allows a user to drag and drop one element onto another element. Once dropped I act upon the object to add the new element as a child, but I need to judge where in my collection of elements to add the new dropped item based on which edge of the drop zone element the new/moved element is dropped on.
I recently added divs with classed called "somethingDropZone" (left,top, right, bottom). These are objects I want to use to determine where the dragged element is dropped. I want them to mimic the top,left,right, and bottom border. I want them to show a 3px gradient border on :hover so the user can see where they will be dropping the item they are dragging. Below is the element html and images that give a better idea what I am facing and what i want to do.
This is what the element box should look like.
Here is what it looks like when I add a left border div.
Everything in the element is pushed down and the left dropzone object with its border stacks above it. What I want is to position the left dropzone inline with the other query element content.
Here is an image I created to show basically where I would like all 4 dropzones to be positioned:
What I am mostly looking for is some CSS guidance in how to make the dropzone divs float where the above image shows.
HTML Code:
<div class="queryElement"
(drop)="onDrop($event)"
(dragstart)="onDragStart($event)"
draggable="true">
<div class="queryElementLeftDropZone queryElementLeftDropZoneDragOver"></div>
<div class="queryElementTopDropZone"></div>
<div class="queryElementBottomDropZone"></div>
<div class="queryElementRightDropZone"></div>
<div class="queryElementLine"></div>
<div class="queryElementHead noselect">
<span class="idSpacer">#{{cohortQueryElement.id}}</span>
<button class="elementButton noselect" (click)="edit()"><img src="/packages/GenomicsPortal/assets/images/PNG icons/Edit.png" /></button>
<button class="elementButton noselect" (click)="delete()"><img src="/packages/GenomicsPortal/assets/images/PNG icons/Trash.png" /></button>
<button class="elementButton noselect" (click)="toggleIncludeExclude()"><img [src]="cohortQueryElement.includeExcludeImagePath"/></button>
</div>
<div class="queryElementBody"> {{cohortQueryElement.displayName}} </div>
<div class="queryElementFoot"> {{cohortQueryElement.displayData}} </div>
</div>

After giving this question some additional thought, I think I will avoid the issue altogether by not adding new objects/elements to hover at the edges. That solution seems to be causing the formatting issues.
It occured to me, rather putting objects to overlay the edges of the box, I could instead determine x,y ranges defining the top, left, bottom, and right of the existing box and then act based on dragover or drop within those x,y coords.
I will post to let you all know how that works out.

Related

How to get an element to be on top of all other elements (like the options of a select element)

I am trying to create a custom component in Angular that is similar to the select element. The problem I am facing is that when the droplist of my component opens, other elements are drawn on top of it. The problem persists even when I modify the z-index because it's in a different stacking context. However, this does not seem to be a problem that the options in the select element face. That means there must be a way to have the droplist appear on top of all other elements. Placing it in the shadow dom does not seem to help.
Edit:
Here is an example of what I am talking about. I need the foo element to be rendered on top of Layer 2 despite the parent element having a lower z-index. Notice the droplist of the dropdown is rendered on top of other elements despite having a lower z-index. Basically, I am asking if there is a way to override the z-index stacking in the same way that the dropdown option does. (Because I am trying to make a custom drop down widget).
<select style="z-index:-1;">
<option style="z-index:-1;">An Option</option>
</select>
<div style="z-index:-1;position:relative;">
<div id="foo" style="z-index:100;"></div>
</div>
<p class="text">Layer 2</p>
https://codepen.io/Bhargysaur/pen/yLzMPPd

How to put fixed element inside transformed container?

the application I write consists of many routes with transition animations between routes. It looks like:
<section class="a animated bounceUp">...</section>
<section class="b">...</section>
When I change route it will show animation and render new content - pretty simple behavior.
Today I created a new section and I need to put inside fixed filters pinned to the viewport. It should look like:
<section class="a">...</section>
<section class="b">...</section>
<section class="c animated bounceDown">
<div class="fixed-filters">...</div>
<div>...</div>
</section>
And here I met my problem. I added fixed position to div, but it doesn't work. The element hasn't fixed position.
Of course I made research about that and I found articles like:
'transform3d' not working with position: fixed children
and
https://www.achrafkassioui.com/blog/position-fixed-and-CSS-transforms/
Which says that I can't do that, because:
'transform' creates a new local coordinate system:
In the HTML namespace, any value other than none for the transform
results in the creation of both a stacking context and a containing
block. The object acts as a containing block for fixed positioned
descendants.
Is that over? Or maybe is there any solution how to do that?
I will be grateful for your help in solving this problem or finding a good workaround that anyone could use.

Prevent tabbing of elements behind an overlay

I am working on tabbing through the whole web page using the keyboard(tab key, shift+tab key) and everything is working fine and smooth. Also when i keep pressing the tab key, the focus cycles through all the elements(address bar, elements, back to address bar and so on).
Now in some cases, i have an modal and an transparent overlay on top of my content. Now when this happens, when i use tab key, i move from the left menu to the overlay and from the last focusible element on the overlay, i have to force the focus to the body element(or the address bar). So Basically when there is an overlay, i want to ignore the element below the overlay from tabbing. Is there any way i can achieve it cleanly?
I was thinking of setting tabindex=-1 for all elements under the overlay but any other better approach would be the most welcome
Thanks
This is an oldish question, but I just ran into this issue today, so I thought I'd share my solution.
As long as you know the tab order of items in your overlay, you can just add a blur event listener on the final item and use it to move the focus back to the first item in your overlay:
lastElementInOverlay.addEventListener('blur', function()
{ firstElementInOverlay.focus(); });
It strikes me that this would be easier than changing the tabIndex of all the elements under the overlay (and then having to change them back when the overlay is gone.
The 'modern/future' solution to this problem seems to be the inert attribute...
So taking the example above, it would look like this with overlay opened
<div id="menu" inert>
<a>
<a>
<a>
</div>
[...other code with tabindex]
<div id="overlay">
<a>
<a>
<a>
</div>
Now since inert is still a work in progress; you'll need to use the following polyfill (for now): https://github.com/WICG/inert
I was thinking of setting tabindex=-1 for all elements under the overlay but any other better approach would be the most welcome
This is what i usually do when fixing the tabbing of elements.
There is one other solution i can think of:
Setting the overlay tab-element lower then that of the rest.
Eg:
<div menu>
<a tabindex="10">
<a tabindex="11">
<a tabindex="12">
</div>
[...other code with tabindex > 10]
<div overlay>
<a tabindex="1">
<a tabindex="2">
<a tabindex="3">
</div>
The downside of this will be that after you have tabbed trough the overlay you will go to the menu again.
You could assign an id like "lastFocusableOverlayElement" to the last focusable HTML-element of your overlay and assign the focus to your trigger element (for example "menu-button") when leaving the last element's focus:
$('#lastFocusableOverlayElement').on('blur', function(){
if ($("body").hasClass("overlay-is-open")){
$('#toggleOverlay').focus();
}
});
In my case the last focusable element is always visible, regardless of whether the overlay is open. For this reason i needed an if query. It can be omitted if not necessary.

highlight text / tokens in input field - slack search box styles

I love the way slack did their highlight of keywords and values in their search I wanted to do something similar.
For those who don't know how it looks a screenshot :
when you inspect slack dom and css, it's something like this
<div style="position: relative;">
<input id="search-query">
<div class="highlighter_underlay">
regurlar text that doesn't match keyword:value goes here
<span class="modifier">key:</span>
<span class="keyword">value</span>
or here
<span class="ghost_text">hint</span>
</div>
</div>
So i'm positioning div over input using absolute positioning, setting .highlighter_underlay text to equal contents of value, tokenize input, adding nice styling to .modifier and .keyword - all easy and works and looks great.
But there is one thing i don't know how to deal with.
Notice that input has a fixed width, but you can enter more text into input and it will overflow and be hidden.
Question is how do you move your overlay div in sync with text input text as it has to align? Please notice that div overlay had to be moved.
It seems it's some css positioning trick, as i don't see any css properties changing when i type more text into input so i don't think it's javascript, neither i could find anything specific in their css that would do that ...
Any ideas?
Here's a link to a prototype:
http://codepen.io/anon/pen/dYZzeB
One method to move an element relative to its parent is to use the CSS combination of:
Parent element using: position: relative
Child element using: position: absolute
CODEPEN Example: This simple example illustrates the relative relationship.
In the live Slack code you referenced, the actual styling box is coming from the pseudo element ::before. When this is set absolute to its relative-set parent, it will follow the relativity of that parent -- thus enabling it to track left and right relative to the parent.

Dojox mobile back button

Please help, this is really making me go crazy.
I am somewhat new to Javascript, and am trying to work with the Dojox.mobile framework...
Basically, what I want to do is have a button, that goes to a <div> which is located before the current one when clicked. This needs to be a normal html <button> or <div>, and can't be a ul, li, heading or similiar, since it is located in the middle of the view, not on the top or any sort of border (the exact location is given in the style tag)..
I tried implementing the dojo.back framework, but I can't seem to get it right with what should load or what should go where.
I tried implementing it with the OnClick property (which is how I implement all other buttons that go forward), but it causes total overlapping between all the divs.
I tried implementing it with the moveTo property, but I think that's only available to ul and li elements, not normal buttons or list elements (and if they are available to normal divs, I have no idea how to implement them).
And I have honestly no idea what else I can do, please help!
For dojox.mobile.View, there's a function called performTransition which can switch from one view to another. Here's a quick example of something you might could use:
HTML:
<div id="first_view" data-dojo-type="dojox.mobile.View">
<p>First view you see</p>
...
</div>
<div id="second_view" data-dojo-type="dojox.mobile.View">
<p>Second view</p>
<button data-dojo-type="dojox.mobile.Button"
data-dojo-props='onClick:function(e){goBackToFirstView();}'>
Back
</button>
</div>
JavaScript:
function goBackToFirstView () {
// load the view that should be visible
var secondView = dijit.registry.byId("second_view");
// transition slides back one
secondView.performTransition("first_view", -1, "slide");
}