Span elements with contenteditable don't lose focus naturally, unlike div elements - html

JsFiddle: http://jsfiddle.net/sharat87/qWCQT/
As you can (or can't) see in the jsfiddle above, when you click below a div element with contenteditable, it loses focus, and rightfully so. But when you do the same thing with a span element with contenteditable, it doesn't lose focus. Also, div element with the style display: inline-block behaves exactly like the span element in this scenario.
In my app's layout, I need the contenteditable element to display as an inline-block. But it should lose focus when clicked on the empty space given below, which is explicitly provided for losing focus and a context specific purpose. I don't want the contenteditable element to retain focus.
Any way around this, short of handling the click and blur-ing the contenteditable element through javascript?

I've just added style/display property with JavaScript depending on Browser and it worked
window.onload=function(){
var ua=navigator.userAgent;
var spans=document.getElementsByTagName('span');
for(i=0;i<spans.length;i++)
{
if(spans[i].className=='content')
{
if(ua.indexOf('MSIE')!=-1) spans[i].style.display='inline-block';
else spans[i].style.display='inline-table';
}
}
};
Tested in Chrome, FF, IE8 and Opera. An example here.

Related

Remove HTML element completely just by using CSS?

Just like removeAttribute in JavaScript, after which the element won't be visible in the source.
You cannot remove an element from the DOM tree using CSS. You can only prevent it from being rendered in the layout with display: none; doing so does not prevent it from responding to events or cause it to be ignored by CSS selectors such as + and :nth-child(). You won't be able to interact with an element that's not there so you wouldn't be able to trigger events the usual way, but its "essence" remains, so to speak.
Its not possible with CSS.
Even if you use display:none, the element will be still in DOM tree.
CSS is for styling not for DOM manipulation. Use JavaScript for that.
display: none;
'Unlike the visibility property, which leaves an element in normal document flow,display: none removes the element completely from the document. It does not take up any space, even though the HTML for it is still in the source code. This is because it is, indeed, removed from the document flow. For all intents and purposes, the item is gone. This can be a good thing or a bad thing, depending on what your intentions are. It can also be damaging to your page if you misuse this property!'
https://www.lifewire.com/display-none-vs-visibility-hidden-3466884
You can use display: none to hide an element but it will still be on the DOM.
You can also use visibility: hidden and it will also still be on the DOM but the DOM will reflect the same vertical flow even though the element is hidden. In other words if the element is a block, a block space will still be reserved for the hidden element. And with display: none the space will also be removed along with the element as it is hidden.
Unless you use JavaScript, with CSS you are only changing the visibility of a DOM element that is existent on the DOM. Which can absolutely serve your purpose depending on what you are trying to do.
If you need more help, just comment with more detail and I'd be glad to help.
You actually can. Not directly in CSS but in combination with Javascript/jQuery you could.
In HTML give a class of "removeFromDom" to the Elements you want to have removed.
<p class="removeFromDom">your text here</p>
In CSS you add these Lines to make it invisible, if JS is not working.
.removeFromDom { display:none !important; visibility:hidden !important; }
In a jQuery file, that you load on any site, create this function::
$(document).ready(function() {
$(".removeFromDom").remove();
});
Et voila.. your jQuery file removes your Items from the DOM. I wouldn't recommend it for security reasons if there is a link nobody should be able to see anytime..

WCAG accessibility issue with nested elements

I've grid with several boxes in (<div>). Each box has inside a list with couple/ several links (simple ul li list with <a> elements). This link list is hidden, it shows only on hover.
It works really fine, but I have accessibility issue, namely, I can't get into any list element with "tab" key (box <div> works ok, it get focus, so the list is showing up), it is just skipping to next box element. I've tried with adding tabindex on each box and each list element inside, but it seems that this is not the solution.
Is there any CSS/ HTML solution for that? I can of course write simple JS, that will check where is focus and if focus has parent with focus option, but I would like to avoid it if possible.
How did you hide the link list? Using display: none or using visibility: hidden. (And that you apply this only to the list elements or also to the div? From your description, I guess it applies only to the list elements.) Content that is hidden using display: none is not keyboard accessible.
In order to make the list appear on hover, are you using a JavaScript event handler or CSS? If you are using JavaScript, you probably need to add an event listener that responds to keyboard events (e.g. onfocus, but as mentioned above, content hidden with display: none won't receive focus). In CSS, I always recommend adding the :focus pseudo-class whenever :hover is used (unless you want different styles for these things).
You may need to write some JavaScript that toggles the visibility of the lists when a parent div receives focus. (If you have tabindex on the div elements, as you say, they should already be able to receive focus.)

HTML element which defaults to display:inline-block?

<div> defaults to block
<span> defaults to inline
Is there one that defaults to inline-block?
If not, what special tag name would be appropriate for me to apply 'inline-block' using CSS?
Or should I stick to using a class?
From what I can tell the <img> tag is the only inline-block by default. To be on the safe side I would recommend a class, you never know when changing all elements of a certain type will come back to bite you. Or, you could always make up your own tag and assign display:inline-block; to it. This way you aren't changing the default functionality of standard elements...
EDIT
It also appears that button, textarea, input, and select elements are also inline-block
Sources:
According to this img is inline-block http://dev.w3.org/html5/markup/img.html#img-display
And here claims that button, textarea, etc. are as well: http://www.w3.org/TR/CSS2/sample.html
EDIT #2
While the source above claims that img tags are inline-block it seems (thanks to Alohci) that they are just inline http://jsfiddle.net/AQ2yp/
The following were tested in Firefox:
button is inline-block: http://jsfiddle.net/GLS4P/
textarea is inline: http://jsfiddle.net/235vc/
input is inline: http://jsfiddle.net/RFKe8/
select is inline-block: http://jsfiddle.net/5B4Gs/
Is there one that defaults to inline-block?
Strictly speaking, no there isn't. The W3 HTML specifications do not ever specify default CSS property values for any elements. They do provide a "default style sheet" for HTML 4, but developers are only encouraged to use it - it is not a requirement or any sort of mandate. The HTML 5 specifications indicate "typical default display properties" but, again, those are not required (also keep in mind that HTML 5 is still a working draft anyways).
So that leaves all default values up to the browser and how the developers actually feel elements should be displayed to a user. No one can guarantee that a specific element will display as inline-block or any other way in someone's browser. You should always explicitly set that if you want it to happen. Don't rely on "defaults."
If not, what special tag name would be appropriate for me to apply 'inline-block' using CSS? Or should I stick to using a class?
This is up to you and how you are designing your pages. You should always use elements that are semantically appropriate to the content contained within them. If the element will always be used in a context which will require inline-block display, by all means set it to that in your style sheet. Otherwise, you will have to resort to classes or more specific selectors in order to make your elements display properly.
Here is a Fiddle that gets the default display value for a majority of HTML tags.
Fiddle
In chrome, the default inline-block elements are: "INPUT", "BUTTON", "TEXTAREA", "SELECT"
My solution to this is declaring what I call a slice.
CSS
sl {
display: inline-block;
}
Usage
<sl>inline block stuff</sl>
You can check my codepen with all HTML elements and their display property by default. Some tags are syntax-broken, but it does not matter for our purpose.
Currently, there are 5 elements with display: inline-block in FF :
<button>
<select>
<meter>
<progress>
<marquee>
And additional 2 (including 5 above) in Chrome:
textarea
input
In principle, it depends on the browser what the default value for the display property is for each element. Even HTML5 drafts do not prescribe what values must be used, though it presents “expected rendering” of elements in terms of CSS.
According the default style sheet for HTML in the CSS 2.1 specification, the elements that have display: inline-block by default are button, input, select, and textarea. Browsers use such settings, except that in Firefox, this only applies to button and select.
In the Rendering section of HTML5 CR, the meter and progress elements are additionally describes as having inline block as “expected rendering”, and browsers that have implemented these elements appear to behave that way. The keygen element is also described as being an inline block, but Firefox does not do that (it implemented keygen internally as select in the DOM); IE does not support keygen at all; Chrome implements it as suggested.
Since all of these elements have rather specialized meanings, functionality, and rendering idiosyncracies, none of them is adequate for general use as an element that is an inline block by default and may have various meanings. What you can use for such an element is normally span or div, depending on whether you prefer inline or block as the default rendering.
Now you can create a Custom Element (for example: <inline-block> or whatever) that will have its CSS property display set to inline-block by default.
customElements.define( 'inline-block', class extends HTMLElement {
constructor() {
super()
this.attachShadow( { mode: 'open' } )
.innerHTML = `<style> :host { display: inline-block } </style>
<slot></slot>`
}
} )
#hw { background-color: lightblue }
<inline-block id="hw">Hello World</inline-block>
button, textarea, input, and select default to inline-block.
In the event you would want to inline-block a div you'd give it a class name.
.inline-block {
display: inline-block
}
Then...
<div class="inline-block"></div>
CORRECTION
I was mistaken about img. It seems it defaults to inline and not inline-block
This isn't really a true answer to the question right now, but with enough support, it may someday be.
<seg> short for "segment". As in, segments of a line.
with the polyfill:
<style> seg { display: inline-block; } </style>
It really would be nice if there was an official one, but there is not, so here is the best (IMO) suggested name for such an element that I know of.
YES there is an element that defaults to inline.
The answer is the span element.
<span>

CSS :active selector eater

I have an <img> element within a <div> element. I want the entire div (including the image) to scale down 10% (using transform) whenever the <div> is being clicked on. I have gotten it to work, but with one small issue: if the user clicks the image inside the div, nothing happens, whereas if the user clicks the background of the div, it works.
Essentially, how can I get the :active selector of .MyDiv:hover:active { /*scaling logic here*/ } to also work when children of MyDiv are clicked.
All help is greatly appreciated and I always accept an answer!
The :active pseudo-class and the div element
First things first, I'm pretty sure in a div element shouldn't have an activation state in the first place.
If we read through the user action pseudo-classes :hover, :active, and :focus section of the Selectors Level 3 W3C Recommendation, we find this:
The :active pseudo-class applies while an element is being activated by the user. For example, between the times the user presses the mouse button and releases it. On systems with more than one mouse button, :active applies only to the primary or primary activation button (typically the "left" mouse button), and any aliases thereof.
Now if we head over to the Interactive Content section of the HTML5 W3C Editor's Draft, we find this:
Certain elements in HTML have an activation behavior, which means that the user can activate them.
The user agent should allow the user to manually trigger elements that have an activation behavior, for instance using keyboard or voice input, or through mouse clicks. When the user triggers an element with a defined activation behavior in a manner other than clicking it, the default action of the interaction event must be to run synthetic click activation steps on the element.
I mention the HTML5 Editor's Draft over the HTML401 Recommendation as the HTML401 document doesn't go into great detail about activation states or user interaction. It does however mention activation on elements like the a element, but doesn't mention anything about it when defining the div element.
The div element doesn't have an "activation state" defined in the HTML5 recommendation. It has no Interactive Content category (unlike the a element) and doesn't state that an active state can be applied to it.
A Workaround
As discussed above, the div element shouldn't accept an :active state. For this reason I'm going to modify the HTML to use an element which does. For this, I'm using the a element:
<a href="javascript: void(0)">
<img />
</a>
Now this alone doesn't fix the IE issue. If you see this JSFiddle example, when clicking on the img element the a container isn't given an active state. So what can we do to fix this? Instead of just using :hover:active, I'm also going to use :hover:focus:
a:hover:active,
a:hover:focus {
outline: 0; /* Reset the default anchor tag focus style. */
background: #f00;
}
This gives us similar functionality on IE and all other browsers, as can be seen in this JSFiddle demo.
Two (potentially undesirable) side effects
The problem with this approach is that the element will retain its focussed state and you can now achieve this effect by accessing the element using your keyboard's tab key. Whenever you hover over the element in its focussed state, its style will change. It's not up to me to decide whether this is an undesirable side effect, however.
Your element is now a link. The href property is required in order for the element to be focussed in the first place.
Extra styling
As we're now using an a element instead of a div element, so we'll need to reset any browser default styles which distinguish your element as a link. For this we can simply:
a {
color: #000; /* Reset the color to black. */
cursor: default; /* Reset the cursor to default. */
text-decoration: none; /* Remove the underline. */
}
a img {
border: none; /* Remove border from image. */
}
Final JSFiddle demo.

<br> is inserted into contenteditable html element if left empty

I have a <div contenteditable="true"></div> and when I enter some content into it, then delete these content, it seems like the browser is inserting a <br> element automatically into this element.
Does anyone has any experience with this? Know how to fix it?
Use SPAN element as your contenteditable element instead of DIV element.
Please read complete.
Q. Why the idea works?
A. Span is an inline element and Div is a block element. Block elements when empty, by default, will have zero dimensions(if no padding is applied to the block element). In contrast, empty inline elements tend to maintain their height and width becomes zero.
Hence, we just need to provide proper width to this Span(or any inline element), but, an inline element won't take width as a property and therefore we need to specify the display of this inline element as inline-block or block.
I have extensively used this idea for creating online-editors. Hope this helps.
NOTE: On changing display of an inline element to block/inline-block, doesn't mean the nature of element has changed. It is still an inline element, so an inline element will never be able to hold a block element inside it.
I ran into this issue before developing a feature for a web app. It's a default behavior for browsers. It's the same as a line break for text editors. Best way to handle it is to run a RegEx on the content when submitting/grabbing it to remove the tags, and then blanking it when no text is available.
I typically use the <br> tags to figure out where my line breaks are. Some browsers use <p> tags, so be sure to cross-browser test it.
Another way around this problem is to change the behavior of how the white space is handled inside the element. Use CSS:
white-space: pre-wrap;
Check out this link for both the solutions.
I was running with same problem when i make a element content editable i figure out a is inserted at the point i make element contenteditable at same time i remove breaks from the element. That perfectly worked for me.
myselect.attr('contenteditable', 'true');
myselect.find('br').remove();
This issue happened to me when the callback of $(window).KeyUp event returned no value.
Once applying "return true" in the registered callback the contenteditable div stopped applying unnecessary br tags.
This seems to work fine for me. If you want to remove the whitespace you can use:
str = $('div[contenteditable="true"]');
str.replace(/ /gi, '');
If you want to remove the <br> you can use:
str = $('div[contenteditable="true"]');
str.replace(/<br>/gi, '');
I was finally able to reproduce this. No matter what type of element is, contenteditable element will be inserted into a <br> element when all element node in it is empty(textContent==='')
Here provide a stable example which can reproduce this:
<p
style={{ padding: 10 }}
contentEditable tabIndex={1}>
<span></span>
{"123"}
<span></span>
</p>
Change element type from p to span can not solve the problem.
So the suggestion is check empty element and remove it in advance.