Add-to-Calendar Button UI Widget
It’s pretty easy to use. Here’s me using the library off of CDNs for both the JavaScript and CSS:
Let’s do a thought dump!
The configuration as “a big chunk of JSON sitting in the HTML as a string” is a little weird to me.
I see the hack where it uses display: none;
on the parent to hide that text from rendering, but I think I like the setup where that’s put into a tag much better.
The fallback for these, assuming JavaScript doesn’t load or execute correctly, is nothing.
I’m torn there. Maybe it’s fine? This seems like bonus functionality anyway. And it’s presumably sitting next to actual content about the event that a user could add to their calendar however they want. I certainly wouldn’t want to see non-interactive text saying “Add to Calendar” because that’s worse than nothing. But maybe there could be some kind of generically useful hyperlink that can act as the fallback?
An add-to-calendar button seems like a good use case for a web component.
Why not an element? That way, the script and styles could be isolated and probably a bit safer for general usage. But how do you do JSON config for a web component? Maybe every single property becomes an attribute? Maybe something like:
The biggest problem to address up front, though, is that it looks like the interactive element is a
with all JavaScript handlers.
You can’t Tab to it at all, so there is no way to activate it. There are no CSS states — it’s all classes updated by JavaScript. I’d definitely get this thing updated to be a
. And maybe it’s good timing to make use of a
element for the options and use dialog
A useful little UI widget thingy here from Jens Kuerschner. Click the add-to-calendar button, get a list of calendar apps, the user selects which one they actually use, and they get what they need for that calendar. Could be a specialized URL they get sent to, or even an .ics
file that gets downloaded.
It’s pretty easy to use. Here’s me using the library off of CDNs for both the JavaScript and CSS:
Let’s do a thought dump!
The configuration as “a big chunk of JSON sitting in the HTML as a string” is a little weird to me.
I see the hack where it uses display: none;
on the parent to hide that text from rendering, but I think I like the setup where that’s put into a
tag much better.
The fallback for these, assuming JavaScript doesn’t load or execute correctly, is nothing.
I’m torn there. Maybe it’s fine? This seems like bonus functionality anyway. And it’s presumably sitting next to actual content about the event that a user could add to their calendar however they want. I certainly wouldn’t want to see non-interactive text saying “Add to Calendar” because that’s worse than nothing. But maybe there could be some kind of generically useful hyperlink that can act as the fallback?
An add-to-calendar button seems like a good use case for a web component.
Why not an
element? That way, the script and styles could be isolated and probably a bit safer for general usage. But how do you do JSON config for a web component? Maybe every single property becomes an attribute? Maybe something like:
The biggest problem to address up front, though, is that it looks like the interactive element is a
with all JavaScript handlers.
You can’t Tab to it at all, so there is no way to activate it. There are no CSS states — it’s all classes updated by JavaScript. I’d definitely get this thing updated to be a
. And maybe it’s good timing to make use of a
element for the options and use dialog::backdrop
for that fancy backdrop-filter
background.
Just some constructive criticism, Jens — keep on keepin’ on.
To Shared Link — Permalink on CSS-Tricks
Add-to-Calendar Button UI Widget originally published on CSS-Tricks. You should get the newsletter.
You can’t Tab to it at all, so there is no way to activate it. There are no CSS states — it’s all classes updated by JavaScript. I’d definitely get this thing updated to be a . And maybe it’s good timing to make use of a
element for the options and use
dialog
A useful little UI widget thingy here from Jens Kuerschner. Click the add-to-calendar button, get a list of calendar apps, the user selects which one they actually use, and they get what they need for that calendar. Could be a specialized URL they get sent to, or even an .ics
file that gets downloaded.
It’s pretty easy to use. Here’s me using the library off of CDNs for both the JavaScript and CSS:
Let’s do a thought dump!
The configuration as “a big chunk of JSON sitting in the HTML as a string” is a little weird to me.
I see the hack where it uses display: none;
on the parent to hide that text from rendering, but I think I like the setup where that’s put into a tag much better.
The fallback for these, assuming JavaScript doesn’t load or execute correctly, is nothing.
I’m torn there. Maybe it’s fine? This seems like bonus functionality anyway. And it’s presumably sitting next to actual content about the event that a user could add to their calendar however they want. I certainly wouldn’t want to see non-interactive text saying “Add to Calendar” because that’s worse than nothing. But maybe there could be some kind of generically useful hyperlink that can act as the fallback?
An add-to-calendar button seems like a good use case for a web component.
Why not an element? That way, the script and styles could be isolated and probably a bit safer for general usage. But how do you do JSON config for a web component? Maybe every single property becomes an attribute? Maybe something like:
The biggest problem to address up front, though, is that it looks like the interactive element is a
with all JavaScript handlers.
You can’t Tab to it at all, so there is no way to activate it. There are no CSS states — it’s all classes updated by JavaScript. I’d definitely get this thing updated to be a
. And maybe it’s good timing to make use of a
element for the options and use dialog::backdrop
for that fancy backdrop-filter
background.
Just some constructive criticism, Jens — keep on keepin’ on.
To Shared Link — Permalink on CSS-Tricks
Add-to-Calendar Button UI Widget originally published on CSS-Tricks. You should get the newsletter.
You can’t Tab to it at all, so there is no way to activate it. There are no CSS states — it’s all classes updated by JavaScript. I’d definitely get this thing updated to be a . And maybe it’s good timing to make use of a
element for the options and use
dialog::backdrop
for that fancy backdrop-filter
background.
Just some constructive criticism, Jens — keep on keepin’ on.
To Shared Link — Permalink on CSS-Tricks
Add-to-Calendar Button UI Widget originally published on CSS-Tricks. You should get the newsletter.
An Auto-Filling CSS Grid With Max Columns of a Minimum Size
Within Drupal 10 core, we’re implementing a new auto-filling CSS Grid technique that I think is cool enough to share with the world.
The requirements are:
- The user specifies a maximum number of columns. This is the auto-filling grid’s “natural” state.
- If a grid cell goes under a user-specified width, the auto-filling grid will readjust itself and decrease the number of columns.
- The grid cells should always stretch to fit the auto-filling grid container’s width, no matter the column count.
- All of this should work independent of viewport width and should not require JavaScript.
The auto-filling CSS Grid in action
Here’s how the resulting auto-filling CSS grid behaves when it is compressed by the draggable div element to its left.
Here’s the code
If you’re not looking for the theory behind the auto-filling grid, and just want to copy/paste code, here you go!
.grid-container {
/**
* User input values.
*/
--grid-layout-gap: 10px;
--grid-column-count: 4;
--grid-item--min-width: 100px;
/**
* Calculated values.
*/
--gap-count: calc(var(--grid-column-count) - 1);
--total-gap-width: calc(var(--gap-count) * var(--grid-layout-gap));
--grid-item--max-width: calc((100% - var(--total-gap-width)) / var(--grid-column-count));
display: grid;
grid-template-columns: repeat(auto-fill, minmax(max(var(--grid-item--min-width), var(--grid-item--max-width)), 1fr));
grid-gap: var(--grid-layout-gap);
}
Theory and tools behind the auto-filling CSS Grid
The code above uses several modern CSS tools including CSS Grid’s repeat()
, auto-fill()
, and minmax()
functions, as well as the CSS max()
, and calc()
functions. Here’s how it works.
CSS Grid’s auto-fill()
function
The key to all of this is auto-fill()
. We need each row to fill up with as many columns as possible. For more info on auto-fill
, check out Sara Soueidan’s awesome article on the difference between auto-fill
and auto-fit
, which includes this helpful video showing how it works.
But how to we make sure that it doesn’t fill in too many columns?
The CSS max()
function
That’s where the max()
function comes in! We want each grid cell’s width to max out at a certain percentage, say 25%
for a four-column grid. But, we can’t have it go below the user-specified minimum width.
So, assuming a four-column grid and minimum cell width of 100px
, the max()
function would look something like: max(25%, 100px)
.
However, the 25%
value is still not quite correct because it doesn’t take the grid gaps into account. What we really need is something like this instead:
max(calc(25% - <grid-gap-for-one-cell>), 100px)
We can calc()
-ulate this in CSS! (Who says CSS isn’t programming?)
--gap-count: calc(var(--grid-column-count) - 1);
--total-gap-width: calc(var(--gap-count) * var(--grid-layout-gap));
--grid-item--max-width: calc((100% - var(--total-gap-width)) / var(--grid-column-count));
Now we have another key to making this work! This will tell the grid cell to go to its maximum width — which takes into account the user-specified columns) — but will never go under 100px
.
max(100px, var(--grid-item--max-width))
Learn more about the max()
function with Chris Coyier’s article on the CSS min()
,max()
, and clamp()
functions.
CSS Grid’s minmax()
function
We’re getting close, but there’s one key ingredient that’s missing: The grid doesn’t always stretch to its parent’s container’s width.
This is exactly what the minmax()
function is designed to do. The following CSS will set the minimum width to the , and if it has room, it’ll stretch all the cells out equally to fit the parent’s width!
minmax(<grid-item-width>, 1fr)
Let’s put it all together and make some magic!
Using the tools above, we can put together this magic bit of code that does exactly what we want!
--gap-count: calc(var(--grid-column-count) - 1);
--total-gap-width: calc(var(--gap-count) * var(--grid-layout-gap));
--grid-item--max-width: calc((100% - var(--total-gap-width)) / var(--grid-column-count));
grid-template-columns: repeat(auto-fill, minmax(max(var(--grid-item--min-width), var(--grid-item--max-width)), 1fr));
CSS is fun!
CSS has really come a long way. I had a lot of fun working on this, and I’m so happy that use-cases like this are now possible without the use of JavaScript.
Special thanks to Andy Blum, who suggested auto-fill()
over auto-fit()
. Also, an extremely special thanks to all of the implementors and spec writers who make advanced functions like this standardized and possible.
An Auto-Filling CSS Grid With Max Columns of a Minimum Size originally published on CSS-Tricks. You should get the newsletter.
Have You Tried Adobe Creative Cloud Express Yet?
Adobe has launched Creative Cloud Express to help anyone make beautiful, stand-out content for the web.
Unlike Adobe’s other products that need a little training and practice to make the most of, Creative Cloud Express is aimed at those with no prior design experience as part of Adobe’s mission to enable creativity for all.
Creative Cloud Express is a series of web, and mobile apps (iOS and Android), that uses a templating system to allow anyone to create social media posts, logos, ads, and more. Simple to use, Creative Cloud Express uses guided tools that hold the user’s hand throughout the process, making it easy to achieve beautiful results with no previous experience.
Creative Cloud Express makes producing creative work a viable option for anybody, regardless of experience. However, it is most suited to social media posting — even though it’s possible, it’s unlikely anyone is seriously going to use Creative Cloud Express to design a logo, given the extensive design insights needed to approach that task.
Creative Cloud Express is great for anyone who wants to dip their toe into Adobe’s product range but isn’t ready for the full Create Cloud Suite of tools. However, it’s really beneficial to companies whose design teams are tied up producing assets for the marketing department. It’s perfectly suited to marketing teams that need to output a lot of professional-standard design assets quickly; designers can make brand assets once and leave the marketers to create the content they need, safe in the knowledge that they’ll end up with professional-looking results regardless of skill.
Adobe describes Creative Cloud Express as being “template-first,” meaning that the starting point for your design will be one of the thousands of professionally designed templates included in the app. Once you have your starting point, you can add your images, content, and videos using a simple drag and drop interaction. In addition, creative Cloud Express has thousands of high-end illustrations, brushes, stickers, and fonts. Creative Cloud Express even gives you access to the entire Adobe Stock photo collection. So, even if you don’t have an extensive set of company assets ready to go, you can still create something truly unique.
Professional designers will also benefit from Creative Cloud Express thanks to the tight syncing with the Creative Cloud Suite. You can quickly toggle between rich and straightforward tools, allowing you to take advantage of powerful apps when needed and fall back on fast automation when suitable.
Powered by Sensei, Adobe’s proprietary AI and machine-learning technology — the same tech that powers design-app giants like Adobe Photoshop and Adobe Premiere Pro — Creative Cloud Express takes the hard work out of producing design assets with quick actions. For example, you can remove the background from photos, trim or merge videos, and export PDFs, all in a few clicks.
One of the must-have features of any design app these days is collaboration, and Creative Cloud Express has it built into the core experience. Adobe’s Shared Libraries, Shared Templates, and Shared Brands are all built-in so that teams can work seamlessly together.
Creative Cloud Express is already an impressive tool, but it’s just the beginning for Adobe. Future updates will include even tighter integration with Creative Cloud apps, more quick actions, and new templates. Adobe plans to release new features every week, making for an exciting learning curve.
Creative Cloud Express is all about enabling creativity and helping those professionals that haven’t previously thought of themselves as designers to build a career as part of the creator economy.
Creative Cloud Express is free on the web at adobe.com/express and can be downloaded for free from the Apple App Store or Android Store. Premium features can be added for $9.99 per month.
The post Have You Tried Adobe Creative Cloud Express Yet? first appeared on Webdesigner Depot.
Proven Reasons Why Domain Name is Important for SEO and Marketing Strategies
Every company needs a domain name for its internet presence. Think about it: a phone number, a street address, and an email address are all part of how your customers find you when they want to contact you.
What’s the best domain name for your business?
A domain name has many benefits. It helps with search engine optimization (SEO) and online marketing by giving your website or blog a memorable URL that can be linked across social media platforms like Facebook and Twitter.
A good domain name also increases customer trust in your company because it appears more professional. Plus, it’s easier to remember than an IP address!
SEO and marketing are the new languages of business. But without an effective domain name, it can be really difficult for your website to rank at the top of search engines.
Creating a memorable domain is crucial to your success. What if your domain name is hard to pronounce? Or what if it has some misspellings? These are just some of the problems that you might encounter when trying to create the perfect domain name for your business.
Domain names are so important for SEO and marketing strategies. It’s a big part of what you need to do to be successful. But why is the domain name so important? How does it work?
This blog post will answer any questions you may have about domain names and reveal their importance to the success of your business.
What is a Domain Name?
In technical terms, a domain name is a website address, such as www.google.com or www.linkedin.com, that uniquely identifies an online location on the World Wide Web.
Simply put, a domain name is like the address of your website. It’s what people type into their browser to get to you.
You want your website address to be easy for people to remember and find.
A good domain name will help you rank higher in search engine results pages (SERPS) and get more traffic.
When choosing your domain name, think about what it means for your company and pick something that represents you or your brand well but makes it easy for people to remember where they found you when they decide to visit again later on!
Choosing the perfect domain name is not an easy task. You need to take your brand into account, as well as your customers and what they are looking for. But once you find the perfect name, it will be worth it.
A good domain name can make or break your online identity, branding, and marketing campaigns.
With these benefits, you must do some research on how to choose a domain name for your business or personal ventures so that you get the best possible results for your marketing strategy.
The Importance of Domain Names
Domain names are important for many different reasons. A domain name can help you rank higher on search engines like Google, Yahoo!, and Bing.
It can also help you generate more traffic to your website. This is because of the domain name’s direct correlation with keywords.
If you want your website to rank high on search engines, then you must choose your domain name wisely. You want to pick a name that has relevant keywords so people will be able to find you when they search for those topics.
For example, if your business was an online flower shop called “Pretty Petals,” then www.prettypetalsflowershop.com would be a good domain name because the words “flower” and “shop” are in it.
Those words are relevant to flowers and florists, which is what this company sells! That means more people will be able to find this website through Google or other search engines.
As for marketing, having a strong domain name helps with conversion rates as customers trust brands with easy-to-remember domains more than they trust brands without them.
The Good Web Presence
With a great domain name comes a great web presence. You owe it to your business and your customers to have a superb web design to justify being on top.
However, spending all that time and energy picking the right name takes a toll on a business. The best option would be to outsource. Have a custom web design company do a custom web design that you will love.
Some things you can do on your own, but others, like web design, you should leave to the professionals to make sure your website is the star of the show!
Tips on How to Pick a Domain Name
Keyword domains significantly restrict your options unless you’re launching a new website or altering the domain name to something different for branding purposes.
The domain name you choose is a permanent part of your organization, and if you make a mistake, you may be unable to expand or change direction if your company evolves.
Choosing a domain name carefully is essential so that you don’t limit yourself excessively. You wouldn’t want to restrict yourself to a single idea.
If you haven’t done keyword research to determine what people are looking for, try to refrain from buying a keyword domain at random, as it might be a complete waste of money.
Instead, with minimal research, try to incorporate as many keywords as you can in the domain name, making sure not to overdo it. Google likes to penalize keyword stuffing.
However, if you are still unsure how to pick a name, here are some useful guidelines:
- Keep it short: You want to be able to remember the domain name without needing to type it in again.
- Make it easy: Make sure your domain name is easy to spell and is not too long (try not to go over ten words).
- Keep it unique: Don’t use any common words or names in your domain name. This will make your website easier for people to find when they’re searching online.
- Avoid hyphens: If you need a hyphenated word, try using an underscore (_) instead, or just divide the word into two parts and add them together. For example, “surf_board” becomes “surfboard”
How Does Your Domain Name Affect Your SEO?
If you want your website to rank higher on search engines, then you need to make sure that the domain name is optimized for SEO.
Understanding the domain name’s basic anatomy and how each portion contributes to SEO is essential.
Optimizing the root domain – the component of the domain before the extension – is the next step once you’ve selected a respectable registrar and a trustworthy hosting provider.
Start by identifying your most important keywords. Incorporate a relevant term into your domain name if it feels appropriate to do so. The search engines will be able to better associate your business with your specialization if this is done.
If you want your domain to stand out and be remembered, you should avoid using digits and special characters.
Purchasing a domain name like www.Google.com will help your website rank higher than if you had purchased www.Google1.com or www.Google2.com. This will result in more page views and more traffic coming to your site.
How Does Your Domain Name Affect Marketing Strategies?
Your domain name is important for your marketing and SEO strategies. Domain names affect where customers find you on the web, how customers interact with you on the web, and how customers feel about you and your brand.
If all of these elements are not working well together, your domain name could be hurting your business more than helping it.
If people are unable to easily find you on the web, they’ll never make it to your site or business even if they wanted to. This would be bad for SEO because fewer people will see your site in search engines.
If people are having trouble finding your site or interacting with it, they won’t want to visit again later because there was a difficult experience the first time around.
And finally, if people don’t think well of you or feel good about coming back to visit again later because of your domain name – that’s also not good for business!
Making Use of the Domain Name for Anchor Texts
To improve your search engine optimization efforts, you must build a diverse backlink portfolio of URLs pointing back to your website from other websites.
Guest posting on other authority sites in your field might help you attain your goal, so consider doing so.
Having said that, you should bear in mind that having the correct domain name and extension may help you develop rich anchor texts that will genuinely urge people to click on them and visit your website.
This will also inform Google that you have something truly useful to offer the online public.
Conclusion
A domain name is the web address of your website. It is important because it is what people will type in to get to your site.
It is vital to make sure you have the correct domain name to help your site rank higher in search engine rankings and be found by more people.
It’s also good to use relevant keywords that people search for in your domain name to help it rank higher in search engines.
You can be as specific as you want or opt to use just the area name and expertise so that you don’t put any constraints on your business as it grows and changes.
The post Proven Reasons Why Domain Name is Important for SEO and Marketing Strategies appeared first on noupe.
GSAP Flip Plugin for Animation
Greensock made the GSAP Flip plugin free in the 3.9 release. FLIP is an animation concept that helps make super performance state-change animations. Ryan Mulligan has a good blog post:
FLIP, coined by Paul Lewis, is an acronym for First, Last, Invert, and Play. The Flip plugin harnesses this technique so that web developers can effortlessly and smoothly transition elements between states.
Examples using the GSAP Flip plugin
Taking advantage of FLIP “by hand” is certainly possible, but tricky. It’s an absolutely perfect thing for an animation library to do for us. Greenstock nailed it, as Ryan says:
1. Get the current state
2. Make your state changes
3. CallFlip.from(state, options)
Deliciously simple. Ryan made an “add to cart” effect with it:
I used it just the other day to make a “mini photo gallery” that could rotate which image was the big one on top:
Which, coincidently, is exactly why I ended up blogging “How to Cycle Through Classes on an HTML Element” the other day.
To Shared Link — Permalink on CSS-Tricks
GSAP Flip Plugin for Animation originally published on CSS-Tricks. You should get the newsletter.
6 Creative Ideas for CSS Link Hover Effects
Creating CSS link hover effects can add a bit of flair to an otherwise bland webpage. If you’ve ever found yourself stumped trying to make a slick hover effect, then I have six CSS effects for you to take and use for your next project.
Let’s get right to it!
I know we’re talking about :hover
and all, but it can sometimes (but maybe not always) be a good idea lump :focus
in as well, as not all interactions are directly from a mouse, but perhaps a tap or keystroke.
The Sliding Highlight Link Hover Effect
This effect applies a box shadow to the inline link, altering the color of the link text in the process. We start with padding all around the link, then add a negative margin of the same value to prevent the padding from disrupting the text flow.
We will use box-shadow
instead of the background property since it allows us to transition.
a {
box-shadow: inset 0 0 0 0 #54b3d6;
color: #54b3d6;
margin: 0 -.25rem;
padding: 0 .25rem;
transition: color .3s ease-in-out, box-shadow .3s ease-in-out;
}
a:hover {
box-shadow: inset 100px 0 0 0 #54b3d6;
color: white;
}
The Text Swappin’ Link Hover Effect
Here’s a fun one where we swap the text of the link with some other text on hover. Hover over the text and the linked text slides out as new text slides in.
Easier to show than tell.
There’s quite a bit of trickery happening in this link hover effect. But the magic sauce is using a data-attribute to define the text that slides in and call it with the content
property of the link’s ::after
pseudo-element.
First off, the HTML markup:
<p>Hover <a href="#" data-replace="get a link"><span>get a link</span></a></p>
That’s a lot of inline markup, but you’re looking at a paragraph tag that contains a link and a span.
Let’s give link some base styles. We need to give it relative positioning to hold the pseudo-elements — which will be absolutely positioned — in place, make sure it’s displayed as inline-block
to get box element styling affordances, and hide any overflow the pseudo-elements might cause.
a {
overflow: hidden;
position: relative;
display: inline-block;
}
The ::before
and ::after
pseudo-elements should have some absolute positioning so they stack with the actual link. We’ll make sure they are set to the link’s full width with a zero offset in the left position, setting them up for some sliding action.
a::before,
a::after {
content: '';
position: absolute;
width: 100%;
left: 0;
}
The ::after
pseudo-element gets the content from the link’s data-attribute that’s in the HTML markup:
a::after {
content: attr(data-replace);
}
Now we can transform: translate3d()
the ::after
pseudo-element element to the right by 200%. We move it back into position on :hover
. While we’re at it, we can give this a zero offset n the top
direction. This’ll be important later when we use the ::before
pseudo-element like an underline below the text.
a::after {
content: attr(data-replace);
top: 0;
transform-origin: 100% 50%;
transform: translate3d(200%, 0, 0);
}
a:hover::after,
a:focus::after {
transform: translate3d(0, 0, 0);
}
We’re also going to transform: scale()
the ::before
pseudo-element so it’s hidden by default, then scale it back up on :hover
. We’ll make it small, like 2px
in height, and pin it to the bottom
so it looks like an underline on the text that swaps in with ::after
.
a::before {
background-color: #54b3d6;
height: 2px;
bottom: 0;
transform-origin: 100% 50%;
transform: scaleX(0);
}
a:hover::before,
a:focus::before {
transform-origin: 0% 50%;
transform: scaleX(1);
}
The rest is all preference! We drop in a transition
on the transform
effects, some colors, and whatnot to get the full effect. Those values are totally up to you.
View full CSS
a {
overflow: hidden;
position: relative;
display: inline-block;
}
a::before,
a::after {
content: '';
position: absolute;
width: 100%;
left: 0;
}
a::before {
background-color: #54b3d6;
height: 2px;
bottom: 0;
transform-origin: 100% 50%;
transform: scaleX(0);
transition: transform .3s cubic-bezier(0.76, 0, 0.24, 1);
}
a::after {
content: attr(data-replace);
height: 100%;
top: 0;
transform-origin: 100% 50%;
transform: translate3d(200%, 0, 0);
transition: transform .3s cubic-bezier(0.76, 0, 0.24, 1);
color: #54b3d6;
}
a:hover::before {
transform-origin: 0% 50%;
transform: scaleX(1);
}
a:hover::after {
transform: translate3d(0, 0, 0);
}
a span {
display: inline-block;
transition: transform .3s cubic-bezier(0.76, 0, 0.24, 1);
}
a:hover span {
transform: translate3d(-200%, 0, 0);
}
The Growing Background Link Hover Effect
This is a pretty popular effect I’ve seen used in quite a few places. The idea is that you use the link’s ::before
pseudo-element as a thick underline that sits slightly behind the actual text of the link. Then, on hover, the pseudo-element expands to cover the whole thing.
OK, some base styles for the link. We want no text-decoration
since ::before
will act like one, then some relative positioning to hold ::before
in place when we give that absolute positioning.
a {
text-decoration: none;
position: relative;
}
Now let’s set up ::before
by making it something like 8px
tall so it looks like a thick underline. We’ll also give it absolute positioning so we have control to make it the full width of the actual link while offsetting it so it’s at the left
and is just a smidge off the bottom
so it looks like it’s subtly highlighting the link. May as well give it z-index: -1
so we’re assured it sits behind the link.
a::before {
content: '';
background-color: hsla(196, 61%, 58%, .75);
position: absolute;
left: 0;
bottom: 3px;
width: 100%;
height: 8px;
z-index: -1;
}
Nice, nice. Let’s make it appear as though ::before
is growing when the link is hovered. All we need is to change the height from 3px
to 100%
. Notice that I’m also dropping the bottom
offset back to zero so the background covers more space when it grows.
a:hover::before {
bottom: 0;
height: 100%;
}
Now for slight transition on those changes:
a::before {
content: '';
background-color: hsla(196, 61%, 58%, .75);
position: absolute;
left: 0;
bottom: 3px;
width: 100%;
height: 8px;
z-index: -1;
transition: all .3s ease-in-out;
}
View full CSS
a {
text-decoration: none;
color: #18272F;
font-weight: 700;
position: relative;
}
a::before {
content: '';
background-color: hsla(196, 61%, 58%, .75);
position: absolute;
left: 0;
bottom: 3px;
width: 100%;
height: 8px;
z-index: -1;
transition: all .3s ease-in-out;
}
a:hover::before {
bottom: 0;
height: 100%;
}
The Right-to-Left Color Swap Link Hover Effect
I personally like using this effect for links in a navigation. The link starts in one color without an underline. Then, on hover, a new color slides in from the right while an underline slides in from the left.
Neat, right? There’s a lot of motion happening in there, so you might consider the accessibility implications and wrap it all in a prefers-reduced-motion
query to replace it with something more subtle for those with motion sensitivities.
Here’s how it works. We give the link a linear background gradient with a hard stop between two colors at the halfway mark.
a {
background-image: linear-gradient(
to right,
#54b3d6,
#54b3d6 50%,
#000 50%
);
}
We make the background double the link’s width, or 200%
, and position it all the way over to the left. That way, it’s like only one of the gradients two colors is showing.
a {
background-image: linear-gradient(
to right,
#54b3d6,
#54b3d6 50%,
#000 50%
);
background-size: 200% 100%;
background-position: -100%;
}
The magic happens when we reach for a couple of non-standard -webkit-
prefixed properties. One strips the color out of the text to make it transparent. The other clips the background gradient to the text so it appears the text is actually the color of the background.
a {
background-image: linear-gradient(
to right,
#54b3d6,
#54b3d6 50%,
#000 50%
);
background-size: 200% 100%;
background-position: -100%;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
Still with me? Now let’s make the link’s faux underline by putting ::before
to use. We’ll give it the same color we gave the on the hidden portion of the link’s background gradient and position it under the actual link so it looks like a proper text-decoration: underline
.
a:before {
content: '';
background: #54b3d6;
display: block;
position: absolute;
bottom: -3px;
left: 0;
width: 0;
height: 3px;
}
On hover, we slide ::before
into place, coming in from the left:
a:hover {
background-position: 0;
}
Now, this is a little tricky. On hover, we make the link’s ::before
pseudo-element 100% of the link’s width. If we were to apply this directly to the link’s hover, we’d make the link itself full-width, which moves it around the screen. Yikes!
a:hover::before {
width: 100%;
}
Add a little transition to smooth things out:
a {
background-image: linear-gradient(
to right,
#54b3d6,
#54b3d6 50%,
#000 50%
);
background-size: 200% 100%;
background-position: -100%;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
transition: all 0.3s ease-in-out;
}
View full CSS
a {
background-image: linear-gradient(
to right,
#54b3d6,
#54b3d6 50%,
#000 50%
);
background-size: 200% 100%;
background-position: -100%;
display: inline-block;
padding: 5px 0;
position: relative;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
transition: all 0.3s ease-in-out;
}
a:before {
content: '';
background: #54b3d6;
display: block;
position: absolute;
bottom: -3px;
left: 0;
width: 0;
height: 3px;
transition: all 0.3s ease-in-out;
}
a:hover {
background-position: 0;
}
a:hover::before {
width:100%;
}
The Rainbow Underline Link Hover Effect
We can’t do text-decoration-color: rainbow
, but we can fake it with a little background
magic mixed with linear gradients.
First, we remove the link’s text-decoration
:
a {
text-decoration: none;
}
Now for those gradients. We chain two linear gradients together on the same background
property. One gradient is the initial color before hover. The second is the rainbow on hover.
a {
background:
linear-gradient(
to right,
rgba(100, 200, 200, 1),
rgba(100, 200, 200, 1)
),
linear-gradient(
to right,
rgba(255, 0, 0, 1),
rgba(255, 0, 180, 1),
rgba(0, 100, 200, 1)
);
}
Let’s make the background size a mere 3px
tall so it looks like, you know, an underline. We can size both gradients together on the background-size
property so that the initial gradient is full width and 3px
tall, and the rainbow is zero width.
a {
background:
linear-gradient(
to right,
rgba(100, 200, 200, 1),
rgba(100, 200, 200, 1)
),
linear-gradient(
to right,
rgba(255, 0, 0, 1),
rgba(255, 0, 180, 1),
rgba(0, 100, 200, 1)
);
background-size: 100% 3px, 0 3px;
}
Now we can position the background gradients — at the same time on the background-position
property — so that the first gradient is fully in view and the rainbow is pushed out of view. Oh, and let’s make sure the background isn’t repeating while we’re at it.
a {
background:
linear-gradient(
to right,
rgba(100, 200, 200, 1),
rgba(100, 200, 200, 1)
),
linear-gradient(
to right,
rgba(255, 0, 0, 1),
rgba(255, 0, 180, 1),
rgba(0, 100, 200, 1)
);
background-size: 100% 3px, 0 3px;
background-position: 100% 100%, 0 100%;
background-repeat: no-repeat;
}
Let’s update the background-size
on hover so that the gradients swap values:
a:hover {
background-size: 0 3px, 100% 3px;
}
And, finally, a little transition when the hover takes place:
a {
background:
linear-gradient(
to right,
rgba(100, 200, 200, 1),
rgba(100, 200, 200, 1)
),
linear-gradient(
to right,
rgba(255, 0, 0, 1),
rgba(255, 0, 180, 1),
rgba(0, 100, 200, 1)
);
background-size: 100% 3px, 0 3px;
background-position: 100% 100%, 0 100%;
background-repeat: no-repeat;
transition: background-size 400ms;
}
Voilà!
The Passing Underline Link Hover Effect
Geoff Graham actually covered this same one recently when he dissected Adam Argyle’s slick hover effect. In his demo, a background color enters from the left behind the link, then exits to the right on mouse out.
My version pares down the background so it’s more of an underline.
a {
position: relative;
}
a::before {
content: '';
position: absolute;
width: 100%;
height: 4px;
border-radius: 4px;
background-color: #18272F;
bottom: 0;
left: 0;
transform-origin: right;
transform: scaleX(0);
transition: transform .3s ease-in-out;
}
a:hover::before {
transform-origin: left;
transform: scaleX(1);
}
That’s not the only way to accomplish this! Here’s another one by Justin Wong using background
instead:
Geoff also has a roundup of CSS link hover effects, ranging from neat to downright absurd. Worth checking out!
Have a blast linking!
There are a lot of options when it comes to creating your own hover effect for in-line links with CSS. You can even play with these effects and create something new. I hope you liked the article. Keep experimenting!
6 Creative Ideas for CSS Link Hover Effects originally published on CSS-Tricks. You should get the newsletter.
Why are hyperlinks blue?
Last year, Elise Blanchard did some great historical research and discovered that blue hyperlinks replaced black hyperlinks in 1993. They’ve been blue for so long now that the general advice I always hear is to keep them that way. There is powerful societal muscle memory for “blue text is a clickable link.”
BUT WHY?!
On a hot tip, Elise kept digging and published a follow-up and identified the source of blue hyperlinks:
[…] it is Prof. Ben Shneiderman whom we can thank for the modern blue hyperlink.
But it didn’t start on the web. It was more about operating systems in the very early 1990s that started using blue for interactive components and highlighted text.
The decision to make hyperlinks blue in Mosaic, and the reason why we see it happening in Cello at the same time, is that by 1993, blue was becoming the industry standard for interaction for hypertext. It had been eight years since the initial research on blue as a hyperlink color. This data had been shared, presented at conferences, and printed in industry magazines. Hypertext went on to be discussed in multiple forums. Diverse teams’ research came to the same conclusion – color mattered. If it didn’t inspire Marc Andreessen and Eric Bina directly, it inspired those around them and those in their industry.
Because research:
[…] the blue hyperlink was indeed inspired by the research done at the University of Maryland.
To Shared Link — Permalink on CSS-Tricks
Why are hyperlinks blue? originally published on CSS-Tricks. You should get the newsletter.
Getting Started With the File System Access API
The File System Access API is a web API that allows read and write access to a user’s local files. It unlocks new capabilities to build powerful web applications, such as text editors or IDEs, image editing tools, improved import/export, all in the frontend. Let’s look into how to get started using this API.
Reading files with the File System Access API
Before diving into the code required to read a file from the user’s system, an important detail to keep in mind is that calling the File System Access API needs to be done by a user gesture, in a secure context. In the following example, we’ll use a click event.
Reading from a single file
Reading data from a file can be done in less than 10 lines of code. Here’s an example code sample:
let fileHandle;
document.querySelector(".pick-file").onclick = async () => {
[fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();
const content = await file.text();
return content;
};
Let’s imagine we have a button in our HTML with the class .pick-file
. When clicking on this button, we launch the file picker by calling window.showOpenFilePicker()
, and we store the result from this query in a variable called fileHandle
.
What we get back from calling showOpenFilePicker()
is an array of FileSystemFileHandle
objects representing each file we selected. As this example is for a single file, we destructure the result. I’ll show how to select multiple files a bit later.
These objects contain a kind
and name
property. If you were to use console.log(fileHandle)
, you would see the following object:
FileSystemFileHandle {kind: 'file', name: 'data.txt'}
The kind
can either be file
or directory
.
On fileHandle
, we can then call the getFile()
method to get details about our file. Calling this method returns an object with a few properties, including a timestamp of when the file was last modified, the name of the file, its size, and type.
Finally, we can call text()
on the file to get its content.
Reading from multiple files
To read from multiple files, we need to pass an options
object to showOpenFilePicker()
.
For example:
let fileHandles;
const options = {
multiple: true,
};
document.querySelector(".pick-file").onclick = async () => {
fileHandles = await window.showOpenFilePicker(options);
// The rest of the code will be shown below
};
By default, the multiple
property is set to false
. Other options can be used to indicate the types of files that can be selected.
For example, if we only wanted to accept .jpeg
files, the options object would include the following:
const options = {
types: [
{
description: "Images",
accept: {
"image/jpeg": ".jpeg",
},
},
],
excludeAcceptAllOption: true,
};
In this example, fileHandles
is an array containing multiple files, so getting their content would be done in the following way:
let fileHandles;
const options = {
multiple: true,
};
document.querySelector(".pick-file").onclick = async () => {
fileHandles = await window.showOpenFilePicker(options);
const allContent = await Promise.all(
fileHandles.map(async (fileHandle) => {
const file = await fileHandle.getFile();
const content = await file.text();
return content;
})
);
console.log(allContent);
};
Writing to a file with the File System Access API
The File System Access API also allows you to write content to files. First, let’s look into how to save a new file.
Writing to a new file
Writing to a new file can also be done in a very short amount of code!
document.querySelector(".save-file").onclick = async () => {
const options = {
types: [
{
description: "Test files",
accept: {
"text/plain": [".txt"],
},
},
],
};
const handle = await window.showSaveFilePicker(options);
const writable = await handle.createWritable();
await writable.write("Hello World");
await writable.close();
return handle;
};
If we imagine a second button with the class save-file
, on click, we open the file picker with the method showSaveFilePicker()
and we pass in an option
object containing the type of file to be saved, here a .txt
file.
Calling this method will also return a FileSystemFileHandle
object like in the first section. On this object, we can call the createWritable()
method that will return a FileSystemWritableFileStream
object. We can then write some content to this stream with the write()
method in which we need to pass the content.
Finally, we need to call the close()
method to close the file and finish writing the content to disk.
If you wanted to write some HTML code to a file for example, you would only need to change what’s in the options
object to accept "text/html": [".html"]
and pass some HTML content to the write()
method.
Editing an existing file
If you’d like to import a file and edit it with the File System Access API, an example code sample would look like:
let fileHandle;
document.querySelector(".pick-file").onclick = async () => {
[fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();
const writable = await fileHandle.createWritable();
await writable.write("This is a new line");
await writable.close();
};
If you’ve been following the rest of this post, you might recognize that we start with the showOpenFilePicker()
and getFile()
methods to read a file and we then use createWritable()
, write()
and close()
to write to that same file.
If the file you’re importing already has content, this code sample will replace the current content with the new one passed into the write()
method.
Additional File System Access API features
Without going into too much detail, the File System Access API also lets you list files in directories and delete files or directories.
Read directories
Reading directories can be done with a tiny bit of code:
document.querySelector(".read-dir").onclick = async () => {
const directoryHandle = await window.showDirectoryPicker();
for await (const entry of directoryHandle.values()) {
console.log(entry.kind, entry.name);
}
};
If we add a new button with the class .read-dir
, on click, calling the showDirectoryPicker()
method will open the file picker and, when selecting a directory on your computer, this code will list the files found in that directory.
Delete files
Deleting a file in a directory can be done with the following code sample:
document.querySelector(".pick-file").onclick = async () => {
const [fileHandle] = await window.showOpenFilePicker();
await fileHandle.remove();
};
If you want to delete a folder, you only need to make a small change to the code sample above:
document.querySelector(".read-dir").onclick = async () => {
const directoryHandle = await window.showDirectoryPicker();
await directoryHandle.remove();
};
Finally, if you want to remove a specific file when selecting a folder, you could write it like this:
// Delete a single file named data.txt in the selected folder
document.querySelector(".pick-folder").onclick = async () => {
const directoryHandle = await window.showDirectoryPicker();
await directoryHandle.removeEntry("data.txt");
};
And if you want to remove an entire folder, you would need the following lines:
// Recursively delete the folder named "data"
document.querySelector(".pick-folder").onclick = async () => {
const directoryHandle = await window.showDirectoryPicker();
await directoryHandle.removeEntry('data', { recursive: true });
};
File System Access API browser support
At the moment, IE and Firefox don’t seem to be supporting the File System Access API. However, there exists a ponyfill called browser-fs-access.
This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.
Desktop
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
101 | No | No | 98 | TP |
Mobile / Tablet
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
No | No | No | 15.4 |
Wrapping up
If you’d like to try the File System Access API, check out this live demo text editor built by Google engineers. Otherwise, if you’d like to learn more about this API and all its features, here are some resources:
- File System Access API (W3C Specification)
- File System Access API (MDN)
- Contrast Ratio Range, replaceAll Method, Native File System API (Šime Vidas)
- The File System Access API: simplifying access to local files (web.dev)
- Reading and writing files and directories with the browser-fs-access library (web.dev)
- browser-fs-access repo (GitHub)
Getting Started With the File System Access API originally published on CSS-Tricks. You should get the newsletter.
20 Best New Websites, February 2022
Welcome to the latest edition of our top 20 sites of the month. In this February’s collection, the overall feel is lighthearted and optimistic, as we are seeing the positivity of a new year persisting across the web.
There is a continued inclination towards warmth and personableness and away from a more corporate, impersonal feel. We see this most in the color palettes used and in the use of illustrations as accents to add character and charm. Of course, as always, type plays a big part too. Enjoy!
Woset
Woset has a simple aesthetic and features a charming illustration style on this site for its creative toys. The interactive ‘play’ section is a nice touch.
Graza
This site for Graza olive oil has a fun feel, with comic style illustration and bright splashes of color while making a serious sales pitch.
KeepGrading
KeepGrading is a post-production color studio. Their portfolio site showcases a lot of work but keeps it well organized and pleasing to navigate.
Englobe
By using soft colors and slightly rounded type, Englobe has managed to portray a warm, friendly, and human aspect with this website, despite being a huge company.
Filtro
Filtro’s design is about as basic as it gets, and yet it has a certain charm to it.
Behold
Behold is a wildlife camera that is currently in development. This landing page does an excellent job of creating interest with just enough information.
Akua
Some rather sweet illustration work creates a good balance with technical information on this site for Akua kelp burgers.
National Museum of Mexican Art
A color scheme of warm, earthy tones and a carefully thought-out type pairing create an inviting presence for the National Museum of Mexican Art.
Ubac
This site for Ubac trainers feels clean and modern with some nice and mostly functional, scroll-activated animation.
Funny Water
The background gradient is really nicely done on Funny Water’s otherwise very minimal site.
DA
DA is a strategic branding, design, and advertising studio, and this site is a good, polished example of a site for such an agency. What stands out is the clever menu text.
Phil’s Finest
Phil’s Finest makes good use of color, oversized type, and occasional illustration mixed in among the well-styled photography.
Vaayu
Grey and black are enlivened by neon yellow in Vaayu’s minimalist, single-page presentation.
Emi Ozaki
Artist and illustrator Emi Ozaki has created a stylized phone interface for her portfolio site, which showcases her illustration aesthetic.
Engineered Floors
The home page scrolling is the centerpiece of Engineered Floors’ site, and it works especially well on mobile.
Hartzler Dairy
Hartzler Dairy goes for a nostalgic feel to match the company’s classic mid-20th century style branding.
Chubby Snacks
Chubby Snacks is PB&J in your pocket; it sells itself! Having said that, the site is pretty appealing in its own right.
Branded
Market research company Branded goes down the flat design road for this site, which could feel a little dated but actually works quite nicely here.
SOS Foods
SOS Foods is an excellent example of a responsible/sustainable goods site, with a design aesthetic aimed at the ethical consumer.
Crystal Construction Engineering
Some nice use of masonry-style layout and overlapping elements create space, but also a pleasing flow in this site for Crystal Construction Engineering.
The post 20 Best New Websites, February 2022 first appeared on Webdesigner Depot.
Popular Design News of the Week: February 7, 2022 – February 13, 2022
Every day design fans submit incredible industry stories to our sister site, Webdesigner News. Our colleagues sift through it, selecting the very best stories from the design, UX, tech, and development worlds and posting them live on the site.
The best way to keep up with the most important stories for web professionals is to subscribe to Webdesigner News or check out the site regularly. However, in case you missed a day this week, here’s a handy compilation of the top curated stories from the last seven days. Enjoy!”
4 Examples of Headless WordPress ECommerce Websites
Laravel 9 is Now Released
Free Web Development Courses for Beginners
15 Best New Fonts, February 2022
Illustrator Tutorial: Sketch to Vector Character Illustration
Replace JavaScript Dialogs with the New HTML Dialog Element
Pixel Editor – Generate Dynamic Pixel Grid
ToolJet – Open-source Low-code Platform to Build Internal Tools
Why do We Round Corners?
Design Memes!
9 Web Design Trends to Watch in 2022 [Infographic]
Top 10 Graphic Design Trends to Inspire your Work in 2022
The post Popular Design News of the Week: February 7, 2022 – February 13, 2022 first appeared on Webdesigner Depot.