CodePen Blog
Chris’ Corner: User Control
Like Miriam Suzanne says:
You’re allowed to have preferences. Set your preferences.
I like the idea of controlling my own experience when browsing and using the web. Bump up that default font size, you’re worth it.
Here’s another version of control. If you publish a truncated RSS feed on your site, but the site itself has more content, I reserve the right to go fetch that content and read it through a custom RSS feed. I feel like that’s essentially the same thing as if I had an elaborate user stylesheet that I applied just to that website that made it look how I wanted it to look. It would be weird to be anti user-stylesheet.
I probably don’t take enough control over my own experience on sites, really. Sometimes it’s just a time constraint where I don’t have the spoons to do a bunch of customization. But the spoon math changes when it has to do with doing my job better.
I was thinking about this when someone poked me that an article I published had a wrong link in it. As I was writing it in WordPress, somehow I linked the link to some internal admin screen URL instead of where I was trying to link to. Worse, I bet I’ve made that same mistake 10 times this year. I don’t know what the heck the problem is (some kinda fat finger issue, probably) but the same problem is happening too much.
What can help? User stylesheets can help! I love it when CSS helps me do my job in weird subtle ways better. I’ve applied this CSS now:
That first class is just something to scope down the editor area in WordPress, then I select any links that have “wp-admin” in them, which I almost certainly do not want to be linking to, and show a visual warning. It’s a little silly, but it will literally work to stop this mistake I keep making.
I find it surprising that only Safari has entirely native support for a linking up your own user CSS, but there are ways to do it via extension or other features in all browsers.
Welp now that we’re talking about CSS I can’t help but share some of my favorite links in that area now.
Dave put his finger on an idea I’m wildly jealous of: CSS wants to be a system. Yes! It so does! CSS wants to be a system! Alone, it’s just selectors, key/value pairs, and a smattering of other features. It doesn’t tell you how to do it, it is lumber and hardware saying build me into a tower! And also: do it your way! And the people do. Some people’s personality is: I have made this system, follow me, disciples, and embrace me. Other people’s personality is: I have also made a system, it is mine, my own, my prec… please step back behind the rope.
Annnnnnd more.
* CSS Surprise Manga Lines from Alvaro are fun and weird and clever.
* Whirl: “CSS loading animations with minimal effort!” Jhey’s got 108 of them open sourced so far (like, 5 years ago, but I’m just seeing it.)
* Next-level frosted glass with
* Custom Top and Bottom CSS Container Masks from Andrew is a nice technique. I like the idea of a “safe” way to build non-rectangular containers where the content you put inside is actually placed safely.
Chris’ Corner: User Control
Like Miriam Suzanne says:
You’re allowed to have preferences. Set your preferences.
I like the idea of controlling my own experience when browsing and using the web. Bump up that default font size, you’re worth it.
Here’s another version of control. If you publish a truncated RSS feed on your site, but the site itself has more content, I reserve the right to go fetch that content and read it through a custom RSS feed. I feel like that’s essentially the same thing as if I had an elaborate user stylesheet that I applied just to that website that made it look how I wanted it to look. It would be weird to be anti user-stylesheet.
I probably don’t take enough control over my own experience on sites, really. Sometimes it’s just a time constraint where I don’t have the spoons to do a bunch of customization. But the spoon math changes when it has to do with doing my job better.
I was thinking about this when someone poked me that an article I published had a wrong link in it. As I was writing it in WordPress, somehow I linked the link to some internal admin screen URL instead of where I was trying to link to. Worse, I bet I’ve made that same mistake 10 times this year. I don’t know what the heck the problem is (some kinda fat finger issue, probably) but the same problem is happening too much.
What can help? User stylesheets can help! I love it when CSS helps me do my job in weird subtle ways better. I’ve applied this CSS now:
.editor-visual-editor a[href*="/wp-admin/"]::after {
content: " DERP!";
color: red;
} That first class is just something to scope down the editor area in WordPress, then I select any links that have “wp-admin” in them, which I almost certainly do not want to be linking to, and show a visual warning. It’s a little silly, but it will literally work to stop this mistake I keep making.
I find it surprising that only Safari has entirely native support for a linking up your own user CSS, but there are ways to do it via extension or other features in all browsers.
Welp now that we’re talking about CSS I can’t help but share some of my favorite links in that area now.
Dave put his finger on an idea I’m wildly jealous of: CSS wants to be a system. Yes! It so does! CSS wants to be a system! Alone, it’s just selectors, key/value pairs, and a smattering of other features. It doesn’t tell you how to do it, it is lumber and hardware saying build me into a tower! And also: do it your way! And the people do. Some people’s personality is: I have made this system, follow me, disciples, and embrace me. Other people’s personality is: I have also made a system, it is mine, my own, my prec… please step back behind the rope.
Annnnnnd more.
* CSS Surprise Manga Lines from Alvaro are fun and weird and clever.
* Whirl: “CSS loading animations with minimal effort!” Jhey’s got 108 of them open sourced so far (like, 5 years ago, but I’m just seeing it.)
* Next-level frosted glass with
backdrop-filter. Josh covers ideas (with credit all the way back to Jamie Gray) related to the “blur the stuff behind it” look. Yes, backdrop-filter does the heavy lifting, but there are SO MANY DETAILS to juice it up.* Custom Top and Bottom CSS Container Masks from Andrew is a nice technique. I like the idea of a “safe” way to build non-rectangular containers where the content you put inside is actually placed safely.
Breaking News: Telegram Shares User Data with U.S. Authorities
Telegram, once renowned for its staunch commitment to user privacy, has begun providing user information to U.S. law enforcement agencies. This change marks a significant shift in the platform's privacy policies, which previously limited cooperation with governments.
Key Developments:
⦁ Policy Change: Telegram now shares user data, including IP addresses and phone numbers, upon receiving valid legal requests.
⦁ Law Enforcement Requests: In 2024, Telegram fulfilled over 900 requests from U.S. authorities, affecting the data of 2,253 users.
⦁ Reason for Change: This decision follows the arrest of Telegram CEO Pavel Durov in France on charges related to facilitating illegal activities on the platform, including the spread of child pornography.
Impact on Users:
This move aims to prevent criminal activities while balancing privacy and legal obligations. However, it raises concerns among privacy advocates about potential misuse and government overreach. Telegram users are urged to stay informed and take necessary steps to protect their digital privacy, such as using end-to-end encryption features where available.
Stay updated with more tech news by following us!
#Telegram #PrivacyPolicy #UserData #LawEnforcement #DigitalPrivacy #TechNews #CyberSecurity #PavelDurov
Telegram, once renowned for its staunch commitment to user privacy, has begun providing user information to U.S. law enforcement agencies. This change marks a significant shift in the platform's privacy policies, which previously limited cooperation with governments.
Key Developments:
⦁ Policy Change: Telegram now shares user data, including IP addresses and phone numbers, upon receiving valid legal requests.
⦁ Law Enforcement Requests: In 2024, Telegram fulfilled over 900 requests from U.S. authorities, affecting the data of 2,253 users.
⦁ Reason for Change: This decision follows the arrest of Telegram CEO Pavel Durov in France on charges related to facilitating illegal activities on the platform, including the spread of child pornography.
Impact on Users:
This move aims to prevent criminal activities while balancing privacy and legal obligations. However, it raises concerns among privacy advocates about potential misuse and government overreach. Telegram users are urged to stay informed and take necessary steps to protect their digital privacy, such as using end-to-end encryption features where available.
Stay updated with more tech news by following us!
#Telegram #PrivacyPolicy #UserData #LawEnforcement #DigitalPrivacy #TechNews #CyberSecurity #PavelDurov
🌟 Exciting News! 🌟
I'm thrilled to announce the development of a new game called Crow of Legends! 🎮✨ Step into a world of adventure where you take control of a mighty crow in a thrilling quest.
Stay tuned for updates, sneak peeks, and the official release! You can play it soon at: bestpage.x10.mx/games
Your feedback and support mean the world to me! Don’t forget to share this with your friends who love gaming! 💻🕊
Follow for more updates:
@Html_codee
I'm thrilled to announce the development of a new game called Crow of Legends! 🎮✨ Step into a world of adventure where you take control of a mighty crow in a thrilling quest.
Stay tuned for updates, sneak peeks, and the official release! You can play it soon at: bestpage.x10.mx/games
Your feedback and support mean the world to me! Don’t forget to share this with your friends who love gaming! 💻🕊
Follow for more updates:
@Html_codee
<html>
<head>
<title>
Interactive Instagram-like Profile Card
</title>
<script src="https://cdn.tailwindcss.com">
</script>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet"/>
<style>
body {
font-family: 'Roboto', sans-serif;
}
</style>
</head>
<body class="bg-gray-100">
<div class="max-w-lg mx-auto mt-10 bg-white rounded-lg shadow-lg">
<div class="p-6">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img alt="Profile picture of the user" class="w-24 h-24 rounded-full border-2 border-pink-500" src="https://vision.googleapis.com/https://www.blackbox.ai/_next/image?url=https%3A%2F%2Fstorage.googleapis.com%2Fa1aa%2Fimage%2Fa52621b0-54eb-4449-95b1-b76f732104f3.jpeg&w=256&q=75/rest?version=v1"/>
<div class="ml-4">
<h2 class="text-xl font-bold">
Username
</h2>
<p class="text-gray-600">
@username
</p>
</div>
</div>
<button class="px-4 py-2 text-white bg-blue-500 rounded-full hover:bg-blue-600 focus:outline-none" id="followButton">
Follow
</button>
</div>
<div class="mt-6 flex justify-around text-center">
<div>
<span class="block text-xl font-bold">
150
</span>
<span class="text-gray-600">
Posts
</span>
</div>
<div>
<span class="block text-xl font-bold">
10k
</span>
<span class="text-gray-600">
Followers
</span>
</div>
<div>
<span class="block text-xl font-bold">
500
</span>
<span class="text-gray-600">
Following
</span>
</div>
</div>
<div class="mt-6">
<h3 class="text-lg font-bold">
Bio
</h3>
<p class="text-gray-700">
This is the user's bio. It can be a few lines long and describe the user's interests, profession, or anything else they want to share.
</p>
</div>
<div class="mt-6 grid grid-cols-3 gap-2">
<img alt="Image 1 description" class="w-full h-32 object-cover" src="https://placehold.co/100x100"/>
<img alt="Image 2 description" class="w-full h-32 object-cover" src="https://placehold.co/100x100"/>
<img alt="Image 3 description" class="w-full h-32 object-cover" src="https://placehold.co/100x100"/>
<img alt="Image 4 description" class="w-full h-32 object-cover" src="https://placehold.co/100x100"/>
<img alt="Image 5 description" class="w-full h-32 object-cover" src="https://placehold.co/100x100"/>
<img alt="Image 6 description" class="w-full h-32 object-cover" src="https://placehold.co/100x100"/>
<img alt="Image 7 description" class="w-full h-32 object-cover" src="https://placehold.co/100x100"/>
<img alt="Image 8 description" class="w-full h-32 object-cover" src="https://placehold.co/100x100"/>
<img alt="Image 9 description" class="w-full h-32 object-cover" src="https://placehold.co/100x100"/>
</div>
</div>
</div>
<script>
document.getElementById('followButton').addEventListener('click', function() {
if (this.innerText === 'Follow') {
this.innerText = 'Following';
this.classList.remove('bg-blue-500', 'hover:bg-blue-600');
this.classList.add('bg-green-500', 'hover:bg-green-600');
} else {
this.innerText = 'Follow';
this.classList.remove('bg-green-500', 'hover:bg-green-600');
this.classList.add('bg-blue-500', 'hover:bg-blue-600');
}
});
</script>
</body>
</html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>
Instagram Sign Up
</title>
<script src="https://cdn.tailwindcss.com">
</script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet"/>
</head>
<body class="bg-gray-50 flex items-center justify-center min-h-screen">
<div class="flex flex-col md:flex-row items-center justify-center w-full max-w-4xl">
<div class="hidden md:block w-1/2">
<img alt="A mobile phone displaying Instagram screenshots" class="w-full h-auto" src="https://www.instagram.com/static/images/homepage/screenshots/screenshot1-2x.jpg/9144d667382d.jpg"/>
</div>
<div class="w-full md:w-1/2 bg-white p-8 rounded-lg shadow-md">
<div class="flex justify-center mb-6">
<img alt="Instagram logo" class="h-12" src="https://upload.wikimedia.org/wikipedia/commons/a/a5/Instagram_icon.png"/>
</div>
<p class="text-center text-gray-500 mb-6">
Sign up to see photos and videos from your friends.
</p>
<button class="w-full bg-blue-500 text-white py-2 rounded-lg mb-4 flex items-center justify-center">
<i class="fab fa-facebook-square mr-2">
</i>
Log in with Facebook
</button>
<div class="flex items-center justify-center mb-4">
<div class="border-t border-gray-300 w-1/4">
</div>
<span class="px-4 text-gray-500">
OR
</span>
<div class="border-t border-gray-300 w-1/4">
</div>
</div>
<form class="space-y-4" id="signup-form">
<input class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" id="email" placeholder="Mobile Number or Email" type="text"/>
<input class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" id="full-name" placeholder="Full Name" type="text"/>
<input class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" id="username" placeholder="Username" type="text"/>
<input class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" id="password" placeholder="Password" type="password"/>
<button class="w-full bg-blue-500 text-white py-2 rounded-lg" type="submit">
Sign up
</button>
</form>
<p class="text-center text-gray-500 text-sm mt-4">
By signing up, you agree to our Terms, Data Policy and Cookies Policy.
</p>
</div>
<div class="w-full md:w-1/2 bg-white p-8 rounded-lg shadow-md mt-4 md:mt-0">
<p class="text-center text-gray-500">
Have an account?
<a class="text-blue-500" href="#">
Log in
</a>
</p>
</div>
</div>
<script>
document.getElementById('signup-form').addEventListener('submit', function(event) {
event.preventDefault();
const email = document.getElementById('email').value;
const fullName = document.getElementById('full-name').value;
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
if (!email || !fullName || !username || !password) {
alert('Please fill in all fields.');
return;
}
const data = {
email: email,
fullName: fullName,
username: username,
password: password
};
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => {
alert('Sign up successful!');
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
});
</script>
</body>
</html>
CodePen Blog
Chris’ Corner: HTML
HTML is fun to think about. The old classic battle of “HTML is a programming language” has surfaced in the pages of none other than WIRED magazine. I love this argument, not even for it’s merit, but for the absolutely certainty that you will get people coming out of the woodwork to tell you that HTML, is not, in fact, a programming language. Each of them will have their own exotic and deeply personal reasons why. I honestly don’t even care or believe their to be any truth to be found in the debate, but I find it fascinating as a social experiment. It’s like cracking an IE 6 “joke” at a conference. You will get laughs.
I wrote a guest blog post Relatively New Things You Should Know about HTML Heading Into 2025 at the start of the year here which had me thinking about it anyway. So here’s more!
You know there are those
And they work fine. Or… mostly fine. They work if there is an email client registered on the device. That’s generally the case, but it’s not 100%. And there are more much more esoteric ones, as Brian Kardell writes:
Over 30% of websites include at least one
A
Every once in a while I get excited about the prospect of writing HTML email with just regular ol’ semantic HTML that you’d write anywhere else. And to be fair: some people absolutely do that and it’s interesting to follow those developments. The last time I tried to get away with “no tables”, the #1 thing that stops me is that you can’t get a reasonable width and centered layout without them in old Outlook. Oh well, that’s the job sometimes.
Ambiguity. That’s one thing that there is plenty of in HTML and I suspect people’s different brains handle it quite differently. Some people try something and it if works they are pleased with that and move on. “Works” being a bit subjective of course, since works on the exact browser you’re using at the time as a developer isn’t necessarily reflective of all users. Some people absolutely fret over the correct usage of HTML in all sorts of situations. That’s my kinda people.
In Stephanie Eckles’ A Call for Consensus on HTML Semantics she lists all sorts of these ambiguities, honing in on particularly tricky ones where there are certainly multiple ways to approach it.
Should testimonials be in a
While I’m OK with the freedom and some degree of ambiguity, I like to sweat the semantics and kinda do wish there were just emphatically right answers sometimes.
Wanna know why hitting an exact markup pattern matters sometimes? Aside from good accessibility and potentially some SEO concern, sometimes you get good bonus behavior. Simon Willison blogged about Footnotes that work in RSS readers, which is one such situa[...]
Chris’ Corner: HTML
HTML is fun to think about. The old classic battle of “HTML is a programming language” has surfaced in the pages of none other than WIRED magazine. I love this argument, not even for it’s merit, but for the absolutely certainty that you will get people coming out of the woodwork to tell you that HTML, is not, in fact, a programming language. Each of them will have their own exotic and deeply personal reasons why. I honestly don’t even care or believe their to be any truth to be found in the debate, but I find it fascinating as a social experiment. It’s like cracking an IE 6 “joke” at a conference. You will get laughs.
I wrote a guest blog post Relatively New Things You Should Know about HTML Heading Into 2025 at the start of the year here which had me thinking about it anyway. So here’s more!
You know there are those
mailto: “protocol” style links you can use, like: Email Chris And they work fine. Or… mostly fine. They work if there is an email client registered on the device. That’s generally the case, but it’s not 100%. And there are more much more esoteric ones, as Brian Kardell writes:
Over 30% of websites include at least one
mailto: link. Almost as many sites include a tel: link. There’s plenty of webcal: and fax:. geo: is used on over 20,300 sites. sms: is used on 42,600+ websites.A
tel: link on my Mac tries to open FaceTime. What does it do on a computer with no calling capability at all, like my daughter’s Fire tablet thingy? Nothing, probably. Just like clicking on a skype: link on my computer here, which doesn’t have Skype installed does: nothing. A semantic HTML link element that looks and clicks like any other link that does nothing is, well, it’s not good. Brian spells out a situation where it’s extra not good, where a link could say like “Call Pizza Parlor” with the actual phone number buried behind the scenes in HTML, whereas if it was just a phone number, mobile browser that support it would automatically turn it into a clickable link, which is surely better.Every once in a while I get excited about the prospect of writing HTML email with just regular ol’ semantic HTML that you’d write anywhere else. And to be fair: some people absolutely do that and it’s interesting to follow those developments. The last time I tried to get away with “no tables”, the #1 thing that stops me is that you can’t get a reasonable width and centered layout without them in old Outlook. Oh well, that’s the job sometimes.
Ambiguity. That’s one thing that there is plenty of in HTML and I suspect people’s different brains handle it quite differently. Some people try something and it if works they are pleased with that and move on. “Works” being a bit subjective of course, since works on the exact browser you’re using at the time as a developer isn’t necessarily reflective of all users. Some people absolutely fret over the correct usage of HTML in all sorts of situations. That’s my kinda people.
In Stephanie Eckles’ A Call for Consensus on HTML Semantics she lists all sorts of these ambiguities, honing in on particularly tricky ones where there are certainly multiple ways to approach it.
Should testimonials be in a
figure or a blockquote or… both? (Honestly, when the heck should we even use figure or blockquote in general… does anyone really know? 😅)While I’m OK with the freedom and some degree of ambiguity, I like to sweat the semantics and kinda do wish there were just emphatically right answers sometimes.
Wanna know why hitting an exact markup pattern matters sometimes? Aside from good accessibility and potentially some SEO concern, sometimes you get good bonus behavior. Simon Willison blogged about Footnotes that work in RSS readers, which is one such situa[...]
Html codes
CodePen Blog Chris’ Corner: HTML HTML is fun to think about. The old classic battle of “HTML is a programming language” has surfaced in the pages of none other than WIRED magazine. I love this argument, not even for it’s merit, but for the absolutely certainty…
tion, building on some thoughts and light research I had done. This is pretty niche, but if you do footnotes just exactly so you’ll get very nice hover behavior in NetNewsWire for footnotes, which happens to be an RSS reader that I like.
They talk about paving the cowpaths in web standards. Meaning standardizing ideas when it’s obvious authors are doing it a bunch. I, for one, have certainly seen “spoilers” implemented quite a bit in different ways. Tracy Durnell wonders if we should just add it to HTML directly.
They talk about paving the cowpaths in web standards. Meaning standardizing ideas when it’s obvious authors are doing it a bunch. I, for one, have certainly seen “spoilers” implemented quite a bit in different ways. Tracy Durnell wonders if we should just add it to HTML directly.
<html>
<head>
<title>AI Image Background Remover</title>
<script src="https://registry.npmmirror.com/vue/3.3.11/files/dist/vue.global.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"></link>
<style>
.image-container {
position: relative;
width: 300px;
height: 300px;
}
.image-container img {
width: 100%;
height: 100%;
object-fit: cover;
}
.image-container .overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
color: white;
font-size: 1.5rem;
opacity: 0;
transition: opacity 0.3s;
}
.image-container:hover .overlay {
opacity: 1;
}
</style>
</head>
<body class="bg-gray-100">
<div id="app" class="min-h-screen flex flex-col items-center justify-center p-4">
<h1 class="text-3xl font-bold mb-6">AI Image Background Remover</h1>
<div class="w-full max-w-md bg-white p-6 rounded-lg shadow-md">
<input type="file" @change="onFileChange" class="mb-4 w-full p-2 border rounded" />
<div v-if="image" class="image-container mb-4">
<img :src="image" alt="Uploaded image with background to be removed" />
<div class="overlay" v-if="loading">
<i class="fas fa-spinner fa-spin"></i>
</div>
</div>
<button @click="removeBackground" class="w-full bg-blue-500 text-white py-2 rounded hover:bg-blue-600" :disabled="!image || loading">
Remove Background
</button>
<div v-if="resultImage" class="mt-4">
<h2 class="text-xl font-semibold mb-2">Result:</h2>
<div class="image-container">
<img :src="resultImage" alt="Image with background removed" />
</div>
</div>
</div>
</div>
<script>
const { createApp, ref } = Vue;
createApp({
setup() {
const image = ref(null);
const resultImage = ref(null);
const loading = ref(false);
const onFileChange = (e) => {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (event) => {
image.value = event.target.result;
};
reader.readAsDataURL(file);
}
};
const removeBackground = async () => {
if (!image.value) return;
loading.value = true;
try {
// Simulate an API call to remove the background
await new Promise((resolve) => setTimeout(resolve, 2000));
// For demonstration, we just use the same image as the result
resultImage.value = image.value;
} catch (error) {
console.error("Error removing background:", error);
} finally {
loading.value = false;
}
};
return {
image,
resultImage,
loading,
onFileChange,
removeBackground
};
}
}).mount('#app');
</script>
</body>
</html>
<html>
<head>
<title>Image Background Remover</title>
<script src="https://registry.npmmirror.com/vue/3.3.11/files/dist/vue.global.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"></link>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Roboto', sans-serif;
}
</style>
</head>
<body class="bg-gray-100">
<div id="app" class="min-h-screen flex flex-col items-center justify-center p-4">
<div class="bg-white shadow-md rounded-lg p-6 w-full max-w-md">
<h1 class="text-2xl font-bold mb-4 text-center">Image Background Remover</h1>
<input type="file" @change="onFileChange" class="mb-4 w-full p-2 border rounded" />
<div v-if="image" class="mb-4">
<img :src="image" alt="Uploaded image for background removal" class="w-full rounded" />
</div>
<button @click="removeBackground" class="w-full bg-blue-500 text-white py-2 rounded hover:bg-blue-600">
Remove Background
</button>
<div v-if="resultImage" class="mt-4">
<h2 class="text-xl font-bold mb-2 text-center">Result</h2>
<img :src="resultImage" alt="Image with background removed" class="w-full rounded" />
</div>
</div>
</div>
<script>
const { createApp, ref } = Vue;
createApp({
setup() {
const image = ref(null);
const resultImage = ref(null);
const onFileChange = (e) => {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (event) => {
image.value = event.target.result;
};
reader.readAsDataURL(file);
}
};
const removeBackground = async () => {
if (!image.value) return;
const formData = new FormData();
formData.append('image_file', dataURLtoBlob(image.value));
formData.append('size', 'auto');
try {
const response = await fetch('https://api.remove.bg/v1.0/removebg', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY_HERE'
},
body: formData
});
if (!response.ok) {
throw new Error('Failed to remove background');
}
const blob = await response.blob();
resultImage.value = URL.createObjectURL(blob);
} catch (error) {
console.error(error);
}
};
const dataURLtoBlob = (dataurl) => {
const arr = dataurl.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
};
return {
image,
resultImage,
onFileChange,
removeBackground
};
}
}).mount('#app');
</script>
</body>
</html>
👍1
CodePen Blog
Chris’ Corner: JavaScript Ecosystem Tools
I love a good exposé on how a front-end team operates. Like what technology they use, why, and how, particularly when there are pain points and journeys through them. Jim Simon of Reddit wrote one a bit ago about their teams build process. They were using something Rollup based and getting 2-minute build times and spent quite a bit of time and effort switching to Vite and now are getting sub-1-second build times. I don’t know if “wow Vite is fast” is the right read here though, as they lost type checking entirely. Vite means esbuild for TypeScript which just strips types, meaning no build process (locally, in CI, or otherwise) will catch errors. That seems like a massive deal to me as it opens the door to all contributions having TypeScript errors. I admit I’m fascinated by the approach though, it’s kinda like treating TypeScript as a local-only linter. Sure, VS Code complains and gives you red squiggles, but nothing else will, so use that information as you will. Very mixed feelings.
Vite always seems to be front and center in conversations about the JavaScript ecosystem these days. The tooling section of this year’s JavaScript Rising Stars:
Vite has been the big winner again this year, renewing for the second time its State of JS awards as the most adopted and loved technology. It’s rare to have both high usage and retention, let alone maintain it. We are eagerly waiting to see how the new void(0) company will impact the Vite ecosystem next year!
(Interesting how it’s actually Biome that gained the most stars this year and has large goals about being the toolchain for the web, like Vite)
Vite actually has the bucks now to make a real run at it. It’s always nail biting and fascinating to see money being thrown around at front-end open source, as a strong business model around all that is hard to find.
Maybe there is an enterprise story to capture? Somehow I can see that more easily. I would guess that’s where the new venture vlt is seeing potential. npm, now being owned by Microsoft, certainly had a story there that investors probably liked to see, so maybe vlt can do it again but better. It’s the “you’ve got their data” thing that adds up to me. Not that I love it, I just get it. Vite might have your stack, but we write checks to infrastructure companies.
That tinge of worry extends to Bun and Deno too. I think they can survive decently on momentum of developers being excited about the speed and features. I wouldn’t say I’ve got a full grasp on it, but I’ve seen some developers be pretty disillusioned or at least trepidatious with Deno and their package registry JSR. But Deno has products! They have enterprise consulting and various hosting. Data and product, I think that is all very smart. Mabe void(0) can find a product play in there. This all reminds me of XState / Stately which took a bit of funding, does open source, and productizes some of what they do. Their new Store library is getting lots of attention which is good for the gander.
To be clear, I’m rooting for all of these companies. They are small and only lightly funded companies, just like CodePen, trying to make tools to make web development better. 💜
Chris’ Corner: JavaScript Ecosystem Tools
I love a good exposé on how a front-end team operates. Like what technology they use, why, and how, particularly when there are pain points and journeys through them. Jim Simon of Reddit wrote one a bit ago about their teams build process. They were using something Rollup based and getting 2-minute build times and spent quite a bit of time and effort switching to Vite and now are getting sub-1-second build times. I don’t know if “wow Vite is fast” is the right read here though, as they lost type checking entirely. Vite means esbuild for TypeScript which just strips types, meaning no build process (locally, in CI, or otherwise) will catch errors. That seems like a massive deal to me as it opens the door to all contributions having TypeScript errors. I admit I’m fascinated by the approach though, it’s kinda like treating TypeScript as a local-only linter. Sure, VS Code complains and gives you red squiggles, but nothing else will, so use that information as you will. Very mixed feelings.
Vite always seems to be front and center in conversations about the JavaScript ecosystem these days. The tooling section of this year’s JavaScript Rising Stars:
Vite has been the big winner again this year, renewing for the second time its State of JS awards as the most adopted and loved technology. It’s rare to have both high usage and retention, let alone maintain it. We are eagerly waiting to see how the new void(0) company will impact the Vite ecosystem next year!
(Interesting how it’s actually Biome that gained the most stars this year and has large goals about being the toolchain for the web, like Vite)
Vite actually has the bucks now to make a real run at it. It’s always nail biting and fascinating to see money being thrown around at front-end open source, as a strong business model around all that is hard to find.
Maybe there is an enterprise story to capture? Somehow I can see that more easily. I would guess that’s where the new venture vlt is seeing potential. npm, now being owned by Microsoft, certainly had a story there that investors probably liked to see, so maybe vlt can do it again but better. It’s the “you’ve got their data” thing that adds up to me. Not that I love it, I just get it. Vite might have your stack, but we write checks to infrastructure companies.
That tinge of worry extends to Bun and Deno too. I think they can survive decently on momentum of developers being excited about the speed and features. I wouldn’t say I’ve got a full grasp on it, but I’ve seen some developers be pretty disillusioned or at least trepidatious with Deno and their package registry JSR. But Deno has products! They have enterprise consulting and various hosting. Data and product, I think that is all very smart. Mabe void(0) can find a product play in there. This all reminds me of XState / Stately which took a bit of funding, does open source, and productizes some of what they do. Their new Store library is getting lots of attention which is good for the gander.
To be clear, I’m rooting for all of these companies. They are small and only lightly funded companies, just like CodePen, trying to make tools to make web development better. 💜
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Compass App</title>
<script src="https://registry.npmmirror.com/vue/3.3.11/files/dist/vue.global.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"></link>
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
body {
font-family: 'Roboto', sans-serif;
}
.compass {
width: 300px;
height: 300px;
border: 10px solid #4A5568;
border-radius: 50%;
position: relative;
margin: 0 auto;
}
.needle {
width: 10px;
height: 150px;
background: #E53E3E;
position: absolute;
top: 50%;
left: 50%;
transform-origin: bottom center;
transform: translate(-50%, -100%);
}
.center {
width: 20px;
height: 20px;
background: #4A5568;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
</head>
<body class="bg-gray-100 flex items-center justify-center h-screen">
<div id="app">
<div class="text-center mb-8">
<h1 class="text-4xl font-bold mb-4">Compass App</h1>
<p class="text-lg text-gray-700">Find your direction with this simple compass app.</p>
</div>
<div v-if="hasMagnetometer" class="compass">
<div class="needle" :style="{ transform: `translate(-50%, -100%) rotate(${heading}deg)` }"></div>
<div class="center"></div>
</div>
<div v-else class="text-center text-red-500">
<p class="text-lg">Magnetometer not supported on your device.</p>
</div>
<div class="text-center mt-8" v-if="hasMagnetometer">
<p class="text-lg text-gray-700">Current Heading: {{ heading.toFixed(2) }}°</p>
</div>
</div>
<script>
const { createApp, ref, onMounted } = Vue
createApp({
setup() {
const heading = ref(0)
const hasMagnetometer = ref(false)
const updateHeading = (event) => {
heading.value = event.alpha
}
onMounted(() => {
if (window.DeviceOrientationEvent) {
window.addEventListener('deviceorientation', updateHeading, true)
if (window.DeviceOrientationEvent.requestPermission) {
window.DeviceOrientationEvent.requestPermission()
.then(permissionState => {
if (permissionState === 'granted') {
hasMagnetometer.value = true
} else {
alert('Permission to access device orientation was denied.')
}
})
.catch(console.error)
} else {
hasMagnetometer.value = true
}
} else {
alert('Device orientation not supported on your device.')
}
})
return {
heading,
hasMagnetometer
}
}
}).mount('#app')
</script>
</body>
</html>