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.
Related
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.
Problem
If I keep my label element (and from what I've read, every input element should have a label element, even if you're not using it, for disabled users), my search box corners on the left-hand side aren't being rounded.
Also, you can tell (if you look close enough) that my search button on the right side isn't aligning perfectly with the rest of the search bar.
Delete the entire label element, and it looks perfectly fine. However, I want to make sure I am practicing good coding manners/behaviors.
How can I make my search bar look the way it looks when you delete the label element, while still using the label element?
Troubleshooting
I have tried using CSS to style the entire bar, to no avail.
I have tried placing the input element, the button element, and the
span element inside of the label element to no avail.
My Code
JSFiddle
I see bootstrap targeting class names based on first or last child.
.input-group .form-control:not(:first-child):not(:last-child), .input-group-addon:not(:first-child):not(:last-child), .input-group-btn:not(:first-child):not(:last-child)
and
.input-group .form-control:not(:first-child):not(:last-child), .input-group-addon:not(:first-child):not(:last-child), .input-group-btn:not(:first-child):not(:last-child)
which appear to be in the _border-radius.scss. Im not totally sure why they are doing this but I did see that is was what was needed to add the border. So basically, the element you needed to have a border-radius, only receives those styles if its the first element.
Just switch:
<input class="form-control" id="search-bar" placeholder="This bar has rounded corners only on the right side.">
<label for="search-bar" class="sr-only"></label>
Kindly use below css to apply left rounded corner.
#search-bar{
border-bottom-left-radius: 5px;
border-top-left-radius: 5px;
}
I wanted to create a box that you could click on and be forwarded to "#" so I thought this would be a good idea:
But unfortuneatly areamaps couldn't be used in div or p tags :/
Anyone have an idea what a good solution would be?
This is not php related, because its happening in the navigator.
Use javascript instead :
<div style='background:url(image.jpg)' onclick='function(){document.location.replace="#"}'> </div>
You could create tags inside the div. You can give these subtags and id or you apply the style in the tag's style attribute. Set the tags style to display:block and position the link via position:absolute or position:relative and the attributes top:5px and left:5px. Set width and height and top and left appropriately.
I'm working with an <input> field and I'd like to style part of the field as the user's typing in a different color. For example, let's say the <input> has a style declaration of color: red; and I want to change part of it to color: blue;. Is there any way this is possible?
If there isn't (as I suspect), any creative ideas on how I can simulate this effect while still preserving semantic mark-up?
Your suspicions are correct: styles will apply to the whole input only.
As styles can apply to the entirety of an element only, a solution will require at least one element per required colour.
Consider the division of the input field with respect to the point at which the user is making changes. There are three sections of the input:
that before the point at which changes are being applied
that after the point at which changes are being applied
that at the point the changes are being applied
You cannot achieve this with a single input element. And as the point at which the changes are being applied can change, the portions of the 'input' wrapped by the three elements will also change. JavaScript is required for a solution.
You should initially include a regular input element and forgo any of the required colouring. Use JavaScript to replace the input with a suitable container element. This can be styled to mimic an input element.
As changes occur, use JavaScript to identify the above-mentioned three divisions. Wrap them in suitable elements (spans would be ideal) and colour as needed.
Consider the following starting point for the generated replacement markup:
<div class="input">
<span class="nonEdited before">foo</span>
<span class="edited">fizz</span>
<span class="nonEdited after">bar</span>
</div>
Use click, keydown and keyup events to figure out the three divisions for the input and to apply wrap the three portions of the faked input as required.
As others have said, you can't do this with styles and static markup.
You could probably do it with a Flash-based form.
But, if I had to this, I'd use jQuery to overlay divs, with the colorized text, atop the <input>.
Algorithm:
Use a normal <input> with whatever default styles are desired. The contents of this input will never change except by user action.
jQuery monitors that <input>. When it detects trigger word(s), it adds a <div> after the input and fills it with the trigger word(s) -- styled as desired. Probably one <div> per word or phrase is best.
jQuery then positions the new <div>, absolutely, directly over the trigger word(s).
Getting the trigger word(s) offset within the <input> might not even be necessary, because the previous words could also be in the overlay <div> -- either styled defaultly or with visibility: hidden.
But, if only the trigger word(s) are desired in the overlay, then using a fixed-width font, like Courier, will help with the sub-positioning.
Take care that the overlay does not interfere with the user trying to mouse or key to certain parts of the <input>. IE, probably don't want to cover any more of the <input> than necessary, and set a click() handler to relay focus.
Alternate, user friendly and simpler approach:
Rather than try to do funky, non-user-expected things to the input, take a page from Jakob Nielsen and from sites like StackOverflow.
Just have a plain ol' <input>, but underneath it, show the formatted text as it comes in.
You can achieve this with (a lot of effort and) a div with the contentEditable attribute present. This is how most web-based WYSIWYG editors achieve rich formatting of inputs. See here for more info: http://ajaxian.com/archives/on-browser-wysiwyg
You can keep differently styled divs side by side in a container overlapped by a transparent input. Modify the widths of the styled divs on the basis of your input entry.
For example, to color input background for leading and trailing spaces:
<div class="bckg-container">
<div id="bckg-leading" class="bckg spaces">
</div>
<div id="bckg-middle" class="bckg">
</div>
<div id="bckg-trailing" class="bckg spaces">
</div>
<br style="clear: left;" />
</div>
<input id="inpt" type="text" placeholder="Add leading/trailing spaces" maxlength="20" />
The three divs inside the container will change their width with input change.
Check the working example in jsfiddle http://jsfiddle.net/TalhaAwan/ywyw4qq5/
You might be able to do it with some edit in place javascript (if it's not possible in pure html/css):
http://www.appelsiini.net/projects/jeditable/default.html
That jQuery plugin doesn't use html input fields so it could be possible to style different parts of the input. It has a couple of hooks for callbacks which you could use to style the input. Hope that helps as an idea.
You can have a label mocking that input and the real input to be hidden, then you can do a lot of things beteen label tags (e.g. colored spans).
I'm new to html, and use hebrew a lot. I came across this problem, which makes me think I'm misunderstanding something.
As for as I know, the element has no effect, but it does allow adding style.
However, trying to do this:
<span dir="rtl"> some text that should be rtl'ed </span>
Doesn't seem to work for me (the dir has no effect).
Using a <div dir="rtl">, on the other hand, works fine.
So.. why isn't the <span> working? As far as my understanding goes, I'm using <span> for exactly its purpose: adding styling. It works fine when I use it to add color... why not for this?
Thanks for any insights!
Edan
P.S. After some testing, I also discovered that if I surround the text with <p> (inside the <span>), then the dir does take effect. But in that case, why wouldn't I just use <p dir="rtl">... the whole idea is that I don't want any elements, just to style something.
dir has an effect on a span, but a span will not be aligned to the right as you expect, only its content.
You will see the effect for span if you end it with a dot - the dot will be placed on the left side, and not on the right.
Div is a display:block element, meaning it fills the whole width - that's why text can be aligned in it. Span is display:inline, so it's sitting in the text, similar to a letter (in a simplistic way).
(by the way - it's considered invalid to have a block element inside an inline element)
Here's a working demo. Notice the last div is far on the right:
Test right to left, div and span: <br />
<span>(span) Hello World!</span> <br />
<span dir='rtl'>(span rtl) Hello World!</span>
<div>(div) Hello World!</div>
<div dir='rtl'>(div rtl) Hello World!</div>
The difference is that span is an inline element, and dir doesn't apply to inline elements (the same way height and position don't). The reason it works with div and so on is that those are block elements. So you'll want to use a block element for setting your text direction.