I am developing Custom Elements for supported browsers only
Looking for a not too complex Custom Elements feature detection method,
I came up with:
<STYLE onload="if('customElements' in window)this.innerHTML=''">
body::before {
font-size: 2em;
color: red;
content: 'This Browser does NOT support modern W3C WebComponents (Custom Elements v1)';
}
</STYLE>
I am not 100% sure; this approach might flash the text (very very briefly)
Question: Is there a more elegant solution to do Custom Element feature detection?
qomponents
Protect the CSS by using a class or something else then have the JS code add the needed class if the condition is right:
<script>
if(!('customElements' in window)) {
document.body.classList.add('no-web-components');
}
</script>
<style>
body.no-web-components::before {
font-size: 2em;
color: red;
content: 'This Browser does NOT support modern W3C WebComponents (Custom Elements v1)';
}
</style>
Also, if you plan to do this you might want to also provide a link to a page showing them where to download a better browser.
Related
I want to apply a number of CSS rules to different selectors, without creating additional selectors. In SCSS, this would be typically done with a mixin, eg:
#mixin gradient-text {
color: transparent;
background-clip: text;
-webkit-background-clip: text;
background-image: linear-gradient(
350deg,
var(--dark-blue),
var(--teal),
var(--bright-green)
);
}
Reading around the internet, there's lots of references to making mixins with the CSS apply syntax, but
https://caniuse.com/sr_css-apply mentions:
#apply was briefly supported behind a flag in Chromium but has since been abandoned in favor of the ::part() selector.
Reading about CSS part though it seems like it's not possible to use CSS part without modifying my HTML and using web components, which have their own issues.
Is it possible to do a mixin in CSS, without modifying my HTML or JS, using part?
According to the MDN article you linked to, ::part can only match elements within a shadow tree. Additionally, the spec for the ::part states
The ::part() pseudo-element only matches anything when the originating element is a shadow host.
Thus, if you wanted to leverage this pseudo-element for CSS mixins, you'd be better working with (developing) a native web component library. You may be able to use the corresponding part HTML attribute outside of the Shadow DOM to implement CSS mixins depending on your requirements.
When in doubt the best thing is to experiment. Here is an example of using ::part() and part (HTML attr) inside and outside of a shadow DOM. Best to test browser support on part as it is a relatively new technology. Moreover, seems there is still ongoing questions about how multiple ident's should be supported, if at all.
customElements.define('custom-thing', class CustomThing extends HTMLElement {
constructor() {
super()
const root = this.attachShadow({ mode: 'closed'})
root.append(document.getElementById('custom').content.cloneNode(true))
}
})
[part~="a"] {
color: red;
}
[part~="b"] {
padding: 20px;
background: gray;
}
p::part(a) {
color: blue !important;
}
custom-thing::part(a) {
color: green;
}
custom-thing::part(a)::after {
content: 'A';
}
custom-thing::part(b) {
color: orange;
}
custom-thing::part(a b) {
/* does multiple ident values work? */
color: blue;
}
<p part="a b">part</p>
<template id="custom">
<style>
p[part="a"] {
color: aqua;
}
</style>
<p part="a">part a</p>
<p part="b">part b</p>
<p part="a b">part a b</p>
</template>
<custom-thing></custom-thing>
I haven't found any resources on how to do that. Something as simple as changing the color of the player would be nice to have :)
Yes: you can hide the built-in browser UI (by removing the controls attribute from audio) and instead build your own interface and control the playback using Javascript (source):
<audio id="player" src="vincent.mp3"></audio>
<div>
<button onclick="document.getElementById('player').play()">Play</button>
<button onclick="document.getElementById('player').pause()">Pause</button>
<button onclick="document.getElementById('player').volume += 0.1">Vol +</button>
<button onclick="document.getElementById('player').volume -= 0.1">Vol -</button>
</div>
You can then style the elements however you wish using CSS.
MDN HTMLAudioElement API reference
<audio>
audio::-webkit-media-controls-panel
audio::-webkit-media-controls-mute-button
audio::-webkit-media-controls-play-button
audio::-webkit-media-controls-timeline-container
audio::-webkit-media-controls-current-time-display
audio::-webkit-media-controls-time-remaining-display
audio::-webkit-media-controls-timeline
audio::-webkit-media-controls-volume-slider-container
audio::-webkit-media-controls-volume-slider
audio::-webkit-media-controls-seek-back-button
audio::-webkit-media-controls-seek-forward-button
audio::-webkit-media-controls-fullscreen-button
audio::-webkit-media-controls-rewind-button
audio::-webkit-media-controls-return-to-realtime-button
audio::-webkit-media-controls-toggle-closed-captions-button
REFERENCE: https://chromium.googlesource.com/chromium/blink/+/72fef91ac1ef679207f51def8133b336a6f6588f/Source/core/css/mediaControls.css?autodive=0%2F%2F%2F
Yes! The HTML5 audio tag with the "controls" attribute uses the browser's default player. You can customize it to your liking by not using the browser controls, but rolling your own controls and talking to the audio API via javascript.
Luckily, other people have already done this. My favorite player right now is jPlayer, it is very stylable and works great. Check it out.
some color tunings
audio {
filter: sepia(20%) saturate(70%) grayscale(1) contrast(99%) invert(12%);
width: 200px;
height: 25px;
}
The appearance of the tag is browser-dependent, but you can hide it, build your own interface and control the playback using Javascript.
Ken had it right as well.
a css tag:
audio {
}
will get you some results. seems it doesnt want the player any height above or below 25px but the width can be shortened or lengthened to an extent.
this was good enough for me; see this example (warning, audio plays automatically): www.thenewyorkerdeliinc.com
Missing the most important one IMO the container for the controls ::-webkit-media-controls-enclosure:
&::-webkit-media-controls-enclosure {
border-radius: 5px;
background-color: green;
}
To change just the colour of the player, simply address the audio tag in your css file, for instance on one of my sites the player became invisible (white on white) so I added:
audio {
background-color: #95B9C7;
}
This changed the player to light blue.
Yes, it's possible, from #Fábio Zangirolami answer
audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel {
background-color: red;
}
If you are using Chrome, turned on "Show user agent shadow DOM" in Chrome Dev Tool settings
Now you'll able to see all the pseudos
audio::-webkit-media-controls-panel
audio::-webkit-media-controls-mute-button
audio::-webkit-media-controls-play-button
...
and now you can style them
audio::-webkit-media-controls-mute-button {
display: none;
}
I did some customizations on the Audio component. Here is what i did.
audio {
/*border-radius: 90px;*/
width: 250px;
height: 45px;
margin-top: 5px;
margin-bottom: 5px;
}
audio::-webkit-media-controls-mute-button {
display: none !important;
}
audio::-webkit-media-controls-volume-slider {
display: none !important;
}
audio::-webkit-media-controls-volume-control-container.closed {
display: none !important;
}
audio::-webkit-media-controls-volume-control-container{
display: none !important;
}
I found that these customizations only works for Edge and Chrome. Not Firefox..
You can use HTMLMediaElement Api to create your own audioplayer with html/css. It is likely the only option. Because the default player can't be styled.
If you want to style the browsers standard music player in the CSS:
audio {
enter code here;
}
I currently am styling my social sharing buttons using groupings (all Facebook buttons have a set style, all Twitter buttons do, etc.). Currently, I achieve this using a massive grouping of YUI's for each button type - this makes creating new sharing buttons extremely tedious, as I have to inspect each button to find its ID. Below is the code that stylizes my Facebook share buttons. The format is identical for my other button types, just with different YUIs - woefully lengthy. However, my code is functional as is:
#block-yui_3_17_2_1_1486492076694_136568, #block-yui_3_17_2_1_1486492076694_229456, #block-yui_3_17_2_1_1486492076694_301518, #block-yui_3_17_2_1_1486492076694_346464, #block-yui_3_17_2_1_1486492076694_390386, #block-yui_3_17_2_1_1486497764071_38998, #block-yui_3_17_2_1_1486497764071_84939, #block-yui_3_17_2_1_1486497764071_127888, #block-yui_3_17_2_1_1486497764071_167750, #block-yui_3_17_2_1_1486497764071_210706, #block-yui_3_17_2_1_1486762828716_16671, #block-yui_3_17_2_1_1487613145787_165402, #block-yui_3_17_2_1_1488578082993_168899, #block-yui_3_17_2_1_1489175439402_256947, #block-yui_3_17_2_1_1489873739917_158023, #block-yui_3_17_2_1_1490053051323_201623, #block-yui_3_17_2_1_1490837162453_152647, #block-yui_3_17_2_1_1491429139219_249912, #block-yui_3_17_2_1_1491948942477_176351 {
display: inline-block;
padding-bottom: 0;
padding-top: 0;
}
Ideally, I'd like to target each button type using their respective classes to REALLY consolidate the amount of code I have written (and make future additions much more efficient). I've tried everything I could think of, but nothing seems to work.
I'm currently working on the Squarespace platform.
Your problem might be because of Squarespace's default styles. When targeting elements, CSS prefers the more precise selector:
.social-icon {
background-color: red;
/* Less preferred */
}
html body div.social-area img.social-icon {
background-color: blue;
/* More preferred */
}
You can override this by using !important:
.social-icon {
background-color: red !important;
/* More preferred */
}
html body div.social-area img.social-icon {
background-color: blue;
/* Less preferred */
}
so when you style your social icons, use !important to override Squarespace's default styles.
.social-icon {
display: inline-block !important;
padding-bottom: 0 !important;
padding-top: 0 !important;
}
Hope this helps!
I have tried to use display: run-in in order to create a semantic and nice-looking metadata name-value list, liks this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Run-in description list test</title>
<style>
dt {
font-weight: bold;
display: run-in;
}
dt:after {
content: ": "
}
</style>
</head>
<body>
<dl>
<dt>Subject</dt>
<dd>A Question</dd>
<dt>From</dt>
<dd>Mr Smith</dd>
<dt>Time</dt>
<dd>2013-08-05</dd>
</dl>
</body>
</html>
The expected result is
Subject: A Question
From: Mr Smith
Time: 2013-08-05
You can watch it live. (Actually, the idea to use display: run-in was given to me by Ian Hickson, after I started nagging about the di element from XHTML 2.0. One alternative is to use float, but that comes with a number of difficulties.)
Until recently, this worked wonderfully in every modern browser except Firefox (that is, it worked perfectly in Internet Explorer, Google Chrome, Opera, and Safari (I think)). But very recently I discovered that it doesn't work in Google Chrome anymore.
Question: Has Google Chrome dropped support for display: run-in? Is there an alternative that works the same way?
I'm not aware of any change to Chrome's support of display:run-in but the setting has always seemed unloved.
Hixie has been consistently opposed to <di> and I kind of understand why. HTML is a semantic language and the semantics are fully defined by dl/dt/dd. The only practical problems are presentational, and that makes it a CSS problem, not an HTML one.
Unfortunately, then current state of CSS doesn't seem up to the job. For dl/dt/dd, and for many similar problems, we really need a mechanism for wrapping groups of elements in a pseudo element which could then perform the role of the <di>.
Obviously, there is no current setting that does what display:run-in is supposed to do. Having said that, in your specific test case, you could achieve the same effect with this CSS:
dt {
font-weight: bold;
display: inline;
}
dt:after {
content: ": ";
}
dd {
display: inline;
margin:0;
}
dd:after {
content:'\0A';
white-space:pre;
}
I'd like to offer a different, more explicit approach to the solution. One that can be extended to a more general case of missing display:run-in behavior.
I.e. I'm using h4->p flow-in transition to compose a nicely formatted list of item properties:
h4 {
font-weight: bold;
display: inline;
}
h4::after {
content: ": ";
}
h4 + p {
display: inline;
}
h4 + p::after {
content: '\0A';
display: block;
}
Here, I'm using "immediate sibling" (+) CSS selector to select p elements immediately preceded by h4 elements. If h4 is followed by any other element, it will be displayed following the normal flow.
An alternate selector ~ will select not one but all elements of the said type, which is not what usually expected from run-in behavior, and will also extend to all tags of the same type in current scope regardless of the other intermixed tags, which could break the layout completely.
So I am aware of this option: Page numbers with CSS/HTML.
It seems by far to be the best way to add page numbers to a print version of a page, but I can't get any variation of this to work anywhere. I have tried on my Windows 7 machine in Chrome, Firefox, and IE9. Based on some of the links it looks like this may be supported in more proprietary software like Prince XML. Is this supported by web browsers for print versions?
I have tried making just a blank html file and in the head adding this between two style tags:
#page {
#bottom-right {
content: counter(page) " of " counter(pages);
}
}
I have also simplified it even to just use content: "TEXT"; to see if I can get something to show up. Is this supported anywhere? By 'this' I'm specifically meaning the #page and #bottom-right tags, since I have gotten content to work many times.
I've been trying to implement paged media as well and have found, according to this Wikipedia page, that there's no browser support for margin boxes as yet. No wonder it wouldn't work!
http://en.wikipedia.org/wiki/Comparison_of_layout_engines_(Cascading_Style_Sheets)
See the table, Grammar and Rules, margin boxes section. Margin boxes are what's needed for page numbering as well as running headers and footers. Getting this implemented would save me the overhead of having to convert the printed media to PDF.
Not using #page, but I have gotten pure CSS page numbers to work in Firefox 20:
http://jsfiddle.net/okohll/QnFKZ/
To print, right click in the results frame (bottom right) and select
This Frame -> Print Frame...
The CSS is
#content {
display: table;
}
#pageFooter {
display: table-footer-group;
}
#pageFooter:after {
counter-increment: page;
content: counter(page);
}
and the HTML is
<div id="content">
<div id="pageFooter">Page </div>
multi-page content here...
</div>
This does not seem to work anymore. Appears it only worked for a short time and browser support was removed!
Counters have to be reset before they can be used, according to https://developer.mozilla.org/en-US/docs/CSS/Counters.
You can set your starting number to whatever, the default is 0.
Example:
#page {
counter-increment: page;
counter-reset: page 1;
#top-right {
content: "Page " counter(page) " of " counter(pages);
}
}
... in theory. In real world only PrinceXML supports this.
Via Mozilla, (Printing a document)
This puts a header and footer on each printed page. This works well in Mozilla, but not quite so well in IE and Chrome.
<!DOCTYPE html>
<html>
<head>
<title>Print sample</title>
<link rel="stylesheet" href="style4.css">
</head>
<body>
<h1>Section A</h1>
<p>This is the first section...</p>
<h1>Section B</h1>
<p>This is the second section...</p>
<div id="print-head">
Heading for paged media
</div>
<div id="print-foot">
Page:
</div>
</body>
</html>
The CSS:
/*** Print sample ***/
/* defaults for screen */
#print-head,
#print-foot {
display: none;
}
/* print only */
#media print {
h1 {
page-break-before: always;
padding-top: 2em;
}
h1:first-child {
page-break-before: avoid;
counter-reset: page;
}
#print-head {
display: block;
position: fixed;
top: 0pt;
left:0pt;
right: 0pt;
font-size: 200%;
text-align: center;
}
#print-foot {
display: block;
position: fixed;
bottom: 0pt;
right: 0pt;
font-size: 200%;
}
#print-foot:after {
content: counter(page);
counter-increment: page;
}
If you are looking to add page numbers when printing under Chrome/Chromium, one easy solution is to use Paged.js.
This JS library takes your HTML/CSS and cuts it into pages, ready to print as a book, that you will preview in your browser. It makes the #page and most the CSS3 specifications work for Chrome.
Solution 1 (easy) if you are OK with cutting your view into pages, ready to print
Just add their CDN in the head tag of your page :
<link href="path/to/file/interface.css" rel="stylesheet" type="text/css">
You can then add page numbers by using the automated counter page. Example :
HTML to put anywhere you want to display the current page number:
<div class="page-number"></div>
CSS to make the number appear in the div :
.page-number{
content: counter(page)
}
The library also allows to easily manage page margins, footers, headers, etc.
Solution 2 (trickier) if you want to show numbers (and page breaks) only when printing
In this case, you need to apply the Paged.js CDN only when printing the document.
One way I can think of would be to add a print me button that fires Javascript to :
add the CDN to the page
and then execute window.print(); to launch the printing prompt of the navigator