I'm trying to use a contenteditable span. But if, as the user, I delete all the text within the span, the span disappears and is no longer editable (still in the DOM though). How do I prevent this?
I'm seeing this problem in both Chrome and FF.
Here's what I've tried:
<div class="subgroup" contenteditable="false" style="border: 1px solid red;">
<span class="header editable" contenteditable="true">initial contents</span>
</div>
I put contenteditable="false" on the parent element based on this answer from 2015, but the result is the same whether or not that attribute is present on the parent.
Of course, I could have JS intercept keypresses to prevent the user from completely clearing the contents, but that's a bad UX. I'd much prefer a pure HTML solution in any event.
In writing up this question, I discovered a solution. For others who might need it: put a border on the span.
But there, as suggested by #G-Cyrillus, a better solution is to add padding to the span when the node is empty:
<style>
.subgroup span:empty { padding-right:1em;}
</style>
<div class="subgroup" contenteditable="false" style="border: 1px solid red;">
<span class="header editable" contenteditable="true">initial contents</span>
</div>
Anyone have a better solution?
Related
I have used the <hr> tag to separate the rows, which is showing double lines in outlook emails.
But I want just a single line to be displayed. How can I rectify this?
I have used the following code
<hr style="border:none;border-bottom:1px solid #0a0a0a;box-shadow:none;margin-bottom:0;">
All answers appreciated.
Adding outline:none; might remove the double line issue in outlook emails.
<hr style="border:none;outline:none;border-bottom:1px solid #0a0a0a;box-shadow:none;margin-bottom:0;"/>
Or, you can remove outlines, borders and give a height and background color as:
<hr style="border:none;outline:none;height:1px;background:#0a0a0a;box-shadow:none;margin-bottom:0;"/>
You can use a different way.
<div style="border-top: 1px dotted #999999;"> </div>
For best cross-email compatibility, I use border. You can do that on the <td>, or other block level element like <p>.
Here, I'd use a paragraph like so:
`<p style="border-top:1px solid #0a0a0a;line-height: 0;font-size:0;margin:10px 0;"> </p>`
Adjust the margin to what you need. The line-height and font-size are needed so that there is not an additional space caused by the "text" (non-breaking space).
<div style="height: 100px; border: solid; border-width: 2px; border-color: #000">
Box 1
<p>A</p>
</div>
I want to convert the div into a link. Note that div includes an anchor tag. What is the best way to do it.
Following code doesn't work. But that's the rough idea to my problem.
<a href="/x">
<div>
Box 1
<p>A
</p>
</div>
</a>
The a element may be wrapped around entire paragraphs, lists, tables, and so forth, even entire sections, so long as there is no interactive content within (e.g. buttons or other links).— W3C Documentation
The anchor element may not contain any interactive content. This includes other anchors. This is one of the more strict rules too. It not only goes against spec, but it completely breaks functionality in major browsers. Chrome alone parses your example to include four links!
You'll need a preprocessing language to alter the markup (server side language or javascript on the front end manipulating ajax return data), or you'll just have to manually change the HTML. Either way, in the end, you'll need to switch that inner anchor out with a span or some other non-interactive element.
I have found a useful jsfiddle for you that uses <a class='default-link' href='javascript:void(0)' onclick='window.location = "http://www.google.com"'</a> for the actual <div>'s link, and then has independent links within this.
Click here to see the jsfiddle
You can simply add display: block; and use the height you need it will do the trick !
DEMO
or you can use inline javascript as that
<div style="height: 100px; border: solid; border-width: 2px; border-color: #000; cursor: pointer;" onclick="window.location='/a'">
Box 1
<p>A
</p>
</div>
The following code is worked for me. But I don't know it's a valid one even with HTML5.
<a style="display:block" href="/a">
<div style="border: solid; border-width: 1px; border-color: #FFF">
<div>
<h3>Heading</h3>
</div>
B
C
</div>
</a>
I tried to style a fieldset element with display: flex and display: inline-flex.
However, it didn't work: flex behaved like block, and inline-flex behaved like inline-block.
This happens both on Firefox and Chrome, but strangely it works on IE.
Is it a bug? I couldn't find that fieldset should have any special behavior, neither in HTML5 nor in CSS Flexible Box Layout specs.
fieldset, div {
display: flex;
border: 1px solid;
}
<fieldset>
<p>foo</p>
<p>bar</p>
</fieldset>
<div>
<p>foo</p>
<p>bar</p>
</div>
According to Bug 984869 - display: flex doesn't work for button elements,
<button> is not implementable (by browsers) in pure CSS, so they are a
bit of a black box, from the perspective of CSS. This means that they
don't necessarily react in the same way that e.g. a <div> would.
This isn't specific to flexbox -- e.g. we don't render scrollbars if
you put overflow:scroll on a button, and we don't render it as a
table if you put display:table on it.
Stepping back even further, this isn't specific to <button>. Consider
<fieldset> and <table> which also have special rendering behavior:
data:text/html,<fieldset style="display:flex"><div>abc</div><div>def</div>
In these cases, Chrome agrees with us and disregards the flex
display mode. (as revealed by the fact that "abc" and "def" end up
being stacked vertically). The fact that they happen to do what you're
expecting on <button style="display:flex"> is likely just due to an
implementation detail.
In Gecko's button implementation, we hardcode <button> (and
<fieldset>, and <table>) as having a specific frame class (and hence,
a specific way of laying out the child elements), regardless of the
display property.
If you want to reliably have the children reliably arranged in a
particular layout mode in a cross-browser fashion, your best bet is to
use a wrapper-div inside the button, just as you would need to inside
of a <table> or a <fieldset>.
Therefore, that bug was marked as "resolved invalid".
There is also Bug 1047590 - display: flex; doesn't work in <fieldset>, currently "unconfirmed".
Good news: Firefox 46+ implements Flexbox for <fieldset>. See bug 1230207.
I find out this might be a bug on Chrome and Firefox where legend and fieldset are replaced elements.
Bugs Reported:
Bug Chrome (fixed since v86)
Bug Firefox (fixed since v46)
A possible Workaround:
A possible workaround would be using <div role="group"> in HTML, and applying in CSS div[role='group'] as selector.
UPDATE
In Chrome version 83 button can work with the display: inline-grid/grid/inline-flex/flex, you can see the demo below:
button {
display: inline-flex;
height: 2rem;
align-items: flex-end;
width: 4rem;
-webkit-appearance: none;
justify-content: flex-end;
}
<!--
The align-items keyword should fail in Chrome 81 or earlier, but work in Chrome 83 or later. To see the error, the button needs styles that make it more of an extrinsic container. In other words, it needs a height or width set.
-->
<button>Hi</button>
<input type="button" value="Hi">
Please star the Chrome bug to increase bug priority
This is a bug in Chrome. Please add a star to this issue to increase it's priority to be fixed:
https://bugs.chromium.org/p/chromium/issues/detail?id=375693
In the mean time, I created these three Code Pen examples to show how to work around the issue. They are built using CSS Grid for the examples but the same techniques can be used for flexbox.
Using aria-labelledby instead of legend
This is the more propper way to deal with the problem. The downside is that you have to deal with generating unique IDs applied to every fake legend element.
https://codepen.io/daniel-tonon/pen/vaaGzZ
<style>
.flex-container {
display: flex;
}
</style>
<fieldset aria-labelledby="fake-legend">
<div class="flex-container">
<div class="flex-child" id="fake-legend">
I am as good accessibilty wise as a real legend
</div>
...
</div>
</fieldset>
Using role="group" and aria-labelledby instead of fieldset and legend
If you need the flex-container to be able to stretch to the height of a sibling element and then also pass that stretch onto its children, you will need to use role="group" instead of <fieldset>
https://codepen.io/daniel-tonon/pen/BayRjGz
<style>
.flex-container {
display: flex;
}
</style>
<div role="group" class="flex-container" aria-labelledby="fake-legend">
<div class="flex-child" id="fake-legend">
I am as good accessibilty wise as a real legend
</div>
...
</div>
Creating a fake duplicate legend for styling purposes
This is a far more hacky way to do it. It is still just as accessible but you don't have to deal with IDs when doing it this way. The main down side is that there is going to be duplicate content between the real legend element and the fake legend element.
https://codepen.io/daniel-tonon/pen/zLLqjY
<style>
.screen-reader-only {
position: absolute;
opacity: 0;
pointer-events: none;
}
.flex-container {
display: flex;
}
</style>
<fieldset>
<legend class="screen-reader-only">
I am a real screen-reader accessible legend element
</legend>
<div class="flex-container">
<div class="flex-child" aria-hidden="true">
I am a fake legend purely for styling purposes
</div>
...
</div>
</fieldset>
Legend MUST be a direct decendent
When you are first trying to fix this yourself, you will probably try doing this:
<!-- DO NOT DO THIS! -->
<fieldset>
<div class="flex-container">
<legend class="flex-child">
Broken semantics legend text
</legend>
...
</div>
</fieldset>
You will discover it works, and then you will probably move on without giving it a second thought.
The problem is that putting a div wrapper between the fieldset and the legend breaks the relationship between the two elements. This breaks the semantics of fieldset/legend.
So by doing this, you have defeated the whole purpose of using fieldset/legend in the first place.
Also, there isn't much point in using a fieldset if you don't give that fieldset a legend.
In my experience, I've found that neither <fieldset>, nor <button>, nor <textarea> can properly use display:flex or inherited properties.
As others have already mentioned, bugs have been reported. If you want to use flexbox to control ordering (e.g. order:2), then you'd need to wrap the element in a div. If you want flexbox to control actual layout and dimensions, then you may want to consider using a div, instead of the input control (Which stinks, I know).
<div role="group">
<p>foo</p>
<p>bar</p>
</div>
<div>
<p>foo</p>
<p>bar</p>
</div>
Might need to use role-group because firefox, chrome and i think safari have a bug with fieldsets apparently. Then the selector in the CSS would simply be
div[role='group'], div {
display: flex;
border: 1px solid;
}
Edit: Here are some issues that other people are experiencing as well.
Issue 375693
Issue 262679
you can put additional div in <fieldset> with the following props:
flex-inner-wrapper {
display: inherit;
flex-flow: inherit;
justify-content: inherit;
align-items: inherit;
}
To answer the original question: yes, it is a bug, but it wasn't well-defined at the time the question was asked.
Now the rendering for fieldset is better defined: https://html.spec.whatwg.org/multipage/rendering.html#the-fieldset-and-legend-elements
In Firefox and Safari, flexbox on fieldset now works. It doesn't yet in Chromium. (See https://bugs.chromium.org/p/chromium/issues/detail?id=375693 )
Also see https://blog.whatwg.org/the-state-of-fieldset-interoperability for improvements made in the specification in 2018.
I am having code like this
<div style="background-color: greenyellow; color: black">
<span style="padding-left:20%">T1</span>
<span style="padding-right:10%">2</span>
</div>
currently it is showing like this.
here padding right is not working. it should be such that 2 should be having 10% padded from right of this div.
Is there any other style tag which can do give such padding from right.
by default, inline elements are rendered left to right aligned, unless you specify float property for them.
That means, in a given horizontal line, first span T1 will be rendered adjacent to the left border of the parent and then span 2 will be rendered adjacent to span T1.
so, your padding-right is never being utilized, as the last span is already far away from right border, unless you make it to move right either by float:right or giving it a margin
try this:
<div style="background-color: greenyellow; color: black">
<span style="padding-left:20%">T1</span>
<span style=" float:right; padding-right:10%;">2</span>
</div>
see this fiddle
This will give the desired effect
<span style="float:right; margin-right:10%">2</span>
Use this:-
<span style="float:right; padding-right:10%">2</span>
Good explanation by above contributors, but you can also try this:
<div style="background-color: greenyellow; color: black">
<span style="padding-left:20%">T1</span>
<span style="padding-right:10%;padding-left:60%">2</span>
</div>
Infact, this is about how you take the structure of your CSS, if we consider Left to Right precedence which Manish mentioned, we can also adjust our requirement by inserting a left padding of 60%.
So, this problem can be solved in both ways, if you want to adjust something in between "T1" and "2" you should use mine one, otherwise both are fine.
Hope you got it.
I have a <div> and I want to put the text 10px from bottom border of the `. However, it doesn't work for me. Following is the code.
<div id="title" style="height:35px;border-bottom:thin solid rgb(65,31,30);margin-left:14px;padding-bottom:10px;font-size:18px;font-weight:thicker">Hello, world!
</div>
remove your height:35px style. that contradicts what you are trying to do. it has a 35px height plus an additional 10px bottom padding.
check out this jsFiddle. i hope it makes sense to you.
I have experiences with this sort of stuff in the past. This is just the case in some browsers and especially if you had overflow-y: scroll; enabled in the style. Your syntax looks good and I have tried it. even with or without that semi-colon at the end, it would still work fine since you are styling it inside the div as an attribute itself.
The way I see it if this is not your entire code please be aware of overflow: scroll; it code be overwriting your style.
or try running it with other browsers.
or you could restructure your code to make sure the padding works like this:
<div id="title" style="height:35px;margin-left:14px;font-size:18px;font-weight:thicker">Hello, world!<div style="border-bottom:thin solid rgb(65,31,30);padding:10px"> </div>
</div>:
by just adding another div within that div