Why is contenteditable not a style? - html

I was recently fiddling with contenteditable in a webpage and got irritated when I needed to set a large number of span tags with it (I ended up using JavaScript to do it). If only I could set it via CSS...
Does anyone know the rationale behind why contenteditable was designed as an attribute rather than a style?

Most people would argue that contentEditable defines behaviour, rather than style (which is true).
WebKit has a CSS property that is similar to contentEditable: -webkit-user-modify.

try
span {
-webkit-user-modify: read-write;
-moz-user-modify: read-write;
user-modify: read-write;
}
it worked on Firefox, Chrome. You can find more info about user-modify

The ability for the user to edit some content or not isn't anything to do with presentation.

styles are optional; you can (in theory) render every page without CSS and it should still work fine. In fact, that's what many text-only browsers, or audio-only browsers do.
contentEditable changes the behavior of elements. A browser that doesn't use style, but interprets JavaScript, should still benefit from the property.

Related

Styling shadow-dom elements in audio element on webkit / chrome

Background: I am trying to fix two annoyances in the appearance of the audio element in Chrome and while attempting to do so I came across two issues I would like to understand better. This is about Chrome 89 on MacOS. I nicely manage to style inside the audio element, using pseudo selectors. Finding out about the names of the pseudo selectors works nicely when looking inside of the shadow dom with the dom inspector. For example, the following two rules work exactly as expected:
::-webkit-media-controls-timeline {background-color:pink;}
audio::-webkit-media-controls-time-remaining-display {background-color:lightgrey;}
Question: However, two things do not work as expected and I want to understand why.
Problem 1: Styling the first letter in the remaining-display div does not work. The following rule is not effective.
audio::-webkit-media-controls-time-remaining-display:first-letter {color:white;}
This is astonishing, since the browser dispplays this
<style>div:first-letter {color:red;}</style> ... <div>e xample</div>
as expected. Why would I be unable to style the first letter? (The idea of this is to get rid of the most annoying leading / symbol in the remaining time display).
Problem 2:
Why would I be unable to style an element with a different pseudo attribute in a different part of the shadow DOM. More precisely the following rule is not effective:
::-internal-track-segment-highlight-before {background-color: blue;}
I see no difference to the other case above where the color styling worked. (The idea of this is to increase the too small contrast between two parts of the track segment.)
Add on: I managed to improved the contrast a bit using
audio::-webkit-media-controls-timeline {-webkit-filter: brightness(2.5);}
but the issue remains why the one method worked and the other did not work.
You are using Chrome, with "Show user agent shadow DOM" turned on
There are 2 types of shadowDOM
let's call it "userland" shadowDOM,
the (open or closed) shadowDOM created by a (3rd party developer) Custom Element/Web Component
This type is available since the W3C Web Components standard was implemented
"user-agent" shadowDOM created by each Browser (Vendor),
implementing input , audio , video, select etc. tags
but each Browser can have a different implementation.
This shadowDOM content can only be accessed if the Browser vendor has enabled access. (with shadowParts or related tech)
And in general it can not be accessed.
WebKit does have some pseudo selectors to change some settings
See: Is it possible to style html5 audio tag?
But they are not CSS selectors that get you full access to shadowDOM by creating complex selectors.
Some Font and Styling settings do cascade into shadowDOM only to have a consistent style in the whole page.
See: https://lamplightdev.com/blog/2019/03/26/why-is-my-web-component-inheriting-styles/
So that is why your color:red works, and :first-letter doesn't
That is why filter works; and background-color doesn't
alternative
https://github.com/dascritch/cpu-audio is a decent Web Component replacing the standard <audio> tag, that gets you styling in all browsers
Note the notation: (open) not (user-agent)
video::-webkit-media-controls-timeline {
background-color: blue !important;
}
work better for highter contrast.
(tested in video tag)

Use <div> as backup tag for HTML5 semantic elements

I plan on using some of the new HTML5 semantic elements, but it looks like some of them aren't well supported even on newer browsers (main isn't supported in IE11 as far as I can tell) is there a way to have them be treated as a <div> if they aren't supported, as the HTML5 semantic tags I plan on using are currently basically the same as divs AFAIK (header, footer, main are the ones I currently plan on using, also canvas but there isn't a good alternative tag to do what canvas does).
Currently if I use one of the unsupported tags in IE it seems to be treated as an unstyled tag but the issue is I can't set the width or height of it in css. What can I do for it to be treated as a and apply all styles that I put in css to that element using the name of the tag as the selector as though it were a <div>.
main
{
width: 100px;
}
does not work in IE11, if it was IE7 or something I wouldn't be too worried but quite a lot of people still use more updated versions of IE and I don't want the website to display improperly to them.
You need the HTML5 shim for supporting older browsers but using just the HTML5 shim does not fix IE11 see: http://jsfiddle.net/jbowyers/n3qZp/. So you also need a CSS reset that includes the 'main' element such as normalize. Or you can just add the CSS reset directly to your project as mentioned by others
main { display: block;}
The html5shiv will allow you to style the main element in IE 11 (and less). There's an explanation of what it does (actually a breakdown of its entire history) here.
Money quote:
Btw, if you want CSS rules to apply to unknown elements in IE, you
just have to do document.createElement(elementName). This somehow lets
the CSS engine know that elements with that name exist
NB. You should probably be using the shiv as a matter of course if you're using HTML5 and plan to support anything less than IE 9.
I think I have found a solution.
In my css file if I do:
main /*or any other unsupported tag that you want treated as a div*/
{
display:block;
other-property:other-value;
other-property:other-value;
...
}
It seems to act identical to a <div> tag. I haven't thoroughly tested or researched this solution (tested several attributes including color, width and text-decoration on IE11 and google chrome with tag named <asdasd> and it worked exactly like a <div>) so if anyone knows any problems with it please let me know.
I’m not sure what the question really is, but the title “Use <div> as backup tag for HTML5 semantic elements” is a good answer to the question “How can I use the HTML5 main, header etc. tags to that my page also works on browsers that do not support them?”
For example, instead of having just <main>...</main> in HTML and main { ... } in CSS, you would have
<div class=main>
<main>...</main>
</div>
in HTML and
.main { ... }
in CSS.
This may look redundant, and you get almost the same browser coverage by using polyfill like html5shiv and explicitly declaring main { display: block } if the polyfill doesn’t do that. But in this approach, you do all the styling in an old robust way and use the new elements only for their semantics. (In reality, the “semantics” means nothing, but maybe some day some programs will recognize main, article etc. and deal with them in some special way.)

Links containing a Label tag are not clickable on IE

I've come across an unusual situation with general IE compatibility.
The following link is unclickable in IE, but fine on everything else (I've tried IE8 onwards):
<label>text</label>
Whilst the above doesn't work, swapping the label for a div or a span is fine.
Is there any sensible way to make this style of markup work in IE with minimal changes. I'd like to keep the label tag if at all possible.
Doesn't using a label inside an a tag invalidate the html as a label is interactive content? You'd be better served using a span for this.
Labels are for form elements. In this context, they are being used incorrectly. Anyone using a screen reader will be confused by the markup, since upon "seeing" a label they are expecting a corresponding form element. A span element would be better suited, and would work across all browsers with minimal changes, since you're simply changing <label> for <span>.

IE6 CSS display:table fix?

I'm working on a web app... unfortunately it has to work with the worst piece of software ever written, yes ie6.
I really like the CSS display:table and display:table-cell properties, but of course it doesn't work in ie.
Has anyone found any fixes for this? I have been looking, but haven't found anything.
Conditional CSS, .htc files, javascript...anything?
I would really like to avoid making everything with floats and clears
Sorry. There isn't a fix to make IE6 support CSS display:table. The only way to acheive this layout in IE6 is to actually use <table> elements.
First question: do you really need to support IE6? If you can simply drop support for it, you'll solve yourself a whole ton of problems, including this one. Current global usage of IE6 is below 3%, and even lower in most developed countries.
If you do still need to support IE6, then your most obvious solution is simply to swallow your semantic markup pride and just use a <table> tag.
As described by #Tom, the next best solution is to write your layout using display:inline-block;.
inline-block allows you to define your elements as blocks, but still keep them in the text flow (kinda the way the <img> tag works by default). If you combine this with fixed element widths, and wapper divs around rows, you could acheive something similar to a table, although it may be hard to get it to expand dynamically with the page width.
The one big "gotcha" bug around this is that inline-block only works in IE6/7 for elements that have a default style of display:inline. In other words, it works for a <span> but not for a <div>. Not a disaster, but something to be aware of, especially since you're specifically asking about IE6 support. Other than that, the good news is that you should be able to get away with using display:inline-block without any other hacks or work-arounds.
IE does not support display:table and display:table-cell but IE7 and below do support display:inline-block. The common way to make this work is by doing the following:
display:-moz-inline-stack;
display:inline-block;
zoom:1;
*display:inline;
Keep in mind that CSS gives you a lot of positioning power and given some context of how you want your layout to look I might be able to give you a better solution.
Due to misunderstanding let me clarify the code above.
display:-moz-inline-stack; is declared for older versions of Firefox.
zoom:1; IE has a property called hasLayout, this is a way to trigger it.
*display:inline is known as a *property hack used to hide this line from all non-IE browsers
The zoom:1 and *display:inline effectively allow block level elements to behave like inline elements (so that inline-block will work in IE6+)
For more information please read:
http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/
http://foohack.com/2007/11/cross-browser-support-for-inline-block-styling/

Is it valid to set img src="about:blank"?

Background: I need to have an inline element to which I can apply width and height via CSS.
AFAIK, img is the only way to have this behavior, currently.
I would rather not have the image point to a transparent pixel GIF on the server. It may be cached, but browsers queue it nevertheless, slowing down overall page speed. Other clients might not be caching at all.
PS No, floating div is not sufficient, it behaves differently from inline elements.
EDIT Sorry, I should have inserted the term "cross browser" somewhere. It must at least be working for FF≥2, IE≥7 and current Safari.
You could use the "data:" URI scheme to embed an image.
Other replaced elements might also work. Setting display to "inline-block" might also be worth looking into.
Can you set:
display:inline-block;
width:50px;
height:10px;
IIRC, images are an "inline block" element, thus they can be rendered inline in text strings, but still have block-like properties.
I guess it will be valid in the W3C validator sense, because the validator does not check whether the link is a resource or not.
However, valid in the broader sense, I would say it is not. An src attribute is required in the IMG tag, and I would say must point to a valid image resource.
I find outis`s "data: URI" idea the best way.
If that doesn't work, a transparent image is your best bet. It's one call, it's a few bytes at best, and will be cached by most clients.
Using "about:blank" as src will cause IE to display red X-boxes. This line of CSS prevents this (in IE 8+), but it's still all a bit hacky:
img[src="about:blank"] {visibility:hidden}
You can accomplish the same thing with a tag.
<p style="height: 400px; width: 400px; background-color: #ffcccc;"> </p>
Height and width are settable. This should be across the common browsers, however I have not been able to test Safari or Chrome using it.
Use a <span> tag with a in it - totally valid - then set it's width and height in CSS, also apply display: block;
Using an empty <span> tag means it will be ignored by screen readers and it won't show up as a broken image when styles are disabled.
It'll also not use up any more bandwidth.
:-D