A design portfolio is an excellent way to demonstrate your skills as a freelancer. As a web designer, you compete with millions of other web designers. Therefore, you must have a strong portfolio to land a high-paying web designing job in such a competitive space. A strong portfolio sets you apart from others. Having no clients, however, can make it challenging to get your portfolio noticed and build up any momentum.
People typically build portfolios from projects they do for clients. Hence, it seems unlikely for a new web designer without clients to have a strong portfolio. However, it’s attainable. You can build a design portfolio with no clients, and you’ll find out how in this post.
What Makes A Good Design Portfolio?
A good portfolio should display your best work, as most clients want to see your best. However, your best work may not be client work. In addition, what’s more, important than displaying your best work is showing your versatility.
Being a versatile web designer will land you more jobs than being an expert in just one type of web design. Notably, you don’t need to have many clients to be versatile in web design. Instead, you become versatile by taking on different projects.
A good design portfolio should include professional recommendations. Testimonials from previous clients are valuable here, but anyone can recommend you. It could be a web designer friend, collaborator, or even your tutor.
Furthermore, a good portfolio should feature non-client work; even if you have thousands of past clients, featuring personal projects is still ideal. It shows your growth as a web designer isn’t limited to what clients ask you to do.
Many other factors constitute a good portfolio, but these points are the most important regarding showing your skill. You can build a portfolio that includes them even if you have no clients.
How To Build A Design Portfolio With Zero Clients
You can try all or some of these methods to build a design portfolio if you have no clients.
1. Take On Design Challenges
A simple way to build a strong web design portfolio is by competing in challenges. It’s helpful whether you have clients or not.
Winning a design challenge is like finishing at the top of the class. It demonstrates that you’re the best web designer in the room and the type of web designer clients want to hire. Generally, taking on design challenges will help sharpen your skills.
You can partake in competitions arranged by renowned web design communities. You can find such competitions on websites like 99designs and Design Crowd. More often than not, winning a web design challenge will land you a job.
2. Carry Out Personal Projects
Carrying out personal projects is similar to competing in challenges. However, in this case, you’re challenging yourself.
Have you ever had a unique idea for a website? Don’t wait until a client asks you to build such a website. Instead, you can begin the project on your own. Then, if you succeed, you can proudly display the project in your portfolio.
When you get clients, you wouldn’t need to convince them that you can handle such tasks; the personal project is a testament to it.
You can carry out as many personal projects as you envisage, no matter how simple or complex. Furthermore, you don’t always have to complete them. Even failed personal projects can be part of your portfolio.
3. Clone Websites
When most clients contact you, they’ll want you to create a website similar to some existing website. You can give yourself a head start by cloning some popular websites and featuring the projects in a portfolio.
Your ability to build a replica of a professional website from scratch shows expertise. In addition, you most likely won’t get a 100% match with the original version. Your version may have improvements that subsequent clients would appreciate.
Furthermore, some website designers specialize in cloning. Suppose you plan to provide such services to clients. In that case, displaying your previously cloned website projects is all you need to create a strong portfolio.
4. Create Websites for Family and Friends
Your family and friends are potential clients. Hence, you can offer to build websites for them, even if it is for free. Afterward, you should include the work in your portfolio.
If your friend or relative has an offline business, for example, you could offer to build a website to give them an online presence.
Even if they eventually don’t use the website, you can include it as a demo project in your portfolio.
5. Get Inspiration From Others
You’re not the only web designer with no clients who wants to build a strong portfolio. Therefore, you can draw inspiration from others.
Dribbble, the social networking platform for designers, is among the best options you have. Dribbble allows you to find thousands of new and veteran web designers with varying portfolios.
You can scan the portfolios, examine the content, and try to replicate what you can in yours. Furthermore, you can even build a portfolio directly on Dribbble.
Bottom Line
Not having clients shouldn’t discourage you as a new web designer. You can still build a strong design portfolio with the methods discussed in this article.
After creating your portfolio, you can then use it to secure jobs. Subsequently, you can update the portfolio with your best client work.
In my previous post we looked at Shoelace, which is a component library with a full suite of UX components that are beautiful, accessible, and — perhaps unexpectedly — built with Web Components. This means they can be used with any JavaScript framework. While React’s Web Component interoperability is, at present, less than ideal, there are workarounds.
But one serious shortcoming of Web Components is their current lack of support for server-side rendering (SSR). There is something called the Declarative Shadow DOM (DSD) in the works, but current support for it is pretty minimal, and it actually requires buy-in from your web server to emit special markup for the DSD. There’s currently work being done for Next.js that I look forward to seeing. But for this post, we’ll look at how to manage Web Components from any SSR framework, like Next.js, today.
We’ll wind up doing a non-trivial amount of manual work, and slightly hurting our page’s startup performance in the process. We’ll then look at how to minimize these performance costs. But make no mistake: this solution is not without tradeoffs, so don’t expect otherwise. Always measure and profile.
The problem
Before we dive in, let’s take a moment and actually explain the problem. Why don’t Web Components work well with server-side rendering?
Application frameworks like Next.js take React code and run it through an API to essentially “stringify” it, meaning it turns your components into plain HTML. So the React component tree will render on the server hosting the web app, and that HTML will be sent down with the rest of the web app’s HTML document to your user’s browser. Along with this HTML are some tags that load React, along with the code for all your React components. When a browser processes these tags, React will re-render the component tree, and match things up with the SSR’d HTML that was sent down. At this point, all of the effects will start running, the event handlers will wire up, and the state will actually… contain state. It’s at this point that the web app becomes interactive. The process of re-processing your component tree on the client, and wiring everything up is called hydration.
So, what does this have to do with Web Components? Well, when you render something, say the same Shoelace component we visited last time:
<sl-tab-group ref="{tabsRef}">
<sl-tab slot="nav" panel="general"> General </sl-tab>
<sl-tab slot="nav" panel="custom"> Custom </sl-tab>
<sl-tab slot="nav" panel="advanced"> Advanced </sl-tab>
<sl-tab slot="nav" panel="disabled" disabled> Disabled </sl-tab>
<sl-tab-panel name="general">This is the general tab panel.</sl-tab-panel>
<sl-tab-panel name="custom">This is the custom tab panel.</sl-tab-panel>
<sl-tab-panel name="advanced">This is the advanced tab panel.</sl-tab-panel>
<sl-tab-panel name="disabled">This is a disabled tab panel.</sl-tab-panel>
</sl-tab-group>
…React (or honestly any JavaScript framework) will see those tags and simply pass them along. React (or Svelte, or Solid) are not responsible for turning those tags into nicely-formatted tabs. The code for that is tucked away inside of whatever code you have that defines those Web Components. In our case, that code is in the Shoelace library, but the code can be anywhere. What’s important is when the code runs.
Normally, the code registering these Web Components will be pulled into your application’s normal code via a JavaScript import. That means this code will wind up in your JavaScript bundle and execute during hydration which means that, between your user first seeing the SSR’d HTML and hydration happening, these tabs (or any Web Component for that matter) will not render the correct content. Then, when hydration happens, the proper content will display, likely causing the content around these Web Components to move around and fit the properly formatted content. This is known as a flash of unstyled content, or FOUC. In theory, you could stick markup in between all of those tags to match the finished output, but this is all but impossible in practice, especially for a third-party component library like Shoelace.
Moving our Web Component registration code
So the problem is that the code to make Web Components do what they need to do won’t actually run until hydration occurs. For this post, we’ll look at running that code sooner; immediately, in fact. We’ll look at custom bundling our Web Component code, and manually adding a script directly to our document’s so it runs immediately, and blocks the rest of the document until it does. This is normally a terrible thing to do. The whole point of server-side rendering is to not block our page from processing until our JavaScript has processed. But once done, it means that, as the document is initially rendering our HTML from the server, the Web Components will be registered and will both immediately and synchronously emit the right content.
In our case, we’re just looking to run our Web Component registration code in a blocking script. This code isn’t huge, and we’ll look to significantly lessen the performance hit by adding some cache headers to help with subsequent visits. This isn’t a perfect solution. The first time a user browses your page will always block while that script file is loaded. Subsequent visits will cache nicely, but this tradeoff might not be feasible for you — e-commerce, anyone? Anyway, profile, measure, and make the right decision for your app. Besides, in the future it’s entirely possible Next.js will fully support DSD and Web Components.
Getting started
All of the code we’ll be looking at is in this GitHub repo and deployed here with Vercel. The web app renders some Shoelace components along with text that changes color and content upon hydration. You should be able to see the text change to “Hydrated,” with the Shoelace components already rendering properly.
Custom bundling Web Component code
Our first step is to create a single JavaScript module that imports all of our Web Component definitions. For the Shoelace components I’m using, my code looks like this:
It loads the definitions for the and components, and overrides some default animations for the dialog. Simple enough. But the interesting piece here is getting this code into our application. We cannot simply import this module. If we did that, it’d get bundled into our normal JavaScript bundles and run during hydration. This would cause the FOUC we’re trying to avoid.
While Next.js does have a number of webpack hooks to custom bundle things, I’ll use Vite instead. First, install it with npm i vite and then create a vite.config.js file. Mine looks like this:
This will build a bundle file with our Web Component definitions in the shoelace-dir folder. Let’s move it over to the public folder so that Next.js will serve it. And we should also keep track of the exact name of the file, with the hash on the end of it. Here’s a Node script that moves the file and writes a JavaScript module that exports a simple constant with the name of the bundle file (this will come in handy shortly):
And that should work! Our Shoelace registration will load in a blocking script and be available immediately as our page processes the initial HTML.
Improving performance
We could leave things as they are but let’s add caching for our Shoelace bundle. We’ll tell Next.js to make these Shoelace bundles cacheable by adding the following entry to our Next.js config file:
Now, on subsequent browses to our site, we see the Shoelace bundle caching nicely!
If our Shoelace bundle ever changes, the file name will change (via the :hash portion from the source property above), the browser will find that it does not have that file cached, and will simply request it fresh from the network.
Wrapping up
This may have seemed like a lot of manual work; and it was. It’s unfortunate Web Components don’t offer better out-of-the-box support for server-side rendering.
But we shouldn’t forget the benefits they provide: it’s nice being able to use quality UX components that aren’t tied to a specific framework. It’s aldo nice being able to experiment with brand new frameworks, like Solid, without needing to find (or hack together) some sort of tab, modal, autocomplete, or whatever component.
Fluid typography is getting a lot more popular, especially since the clamp() math function is available in every evergreen browser. But if we’re honest, it’s still a lot of mathematics to achieve this. You can use tools such as utopia.fyi, which are fantastic. But in large projects, it can get messy pretty fast. I’m a big fan of readable and maintainable code and always want to see what my code is doing at a glance. I’m sure there are many more of you like that, so instead of adding a full clamp() function inside of our code, maybe we can make this a bit more readable with Sass.
Why Should We Use Fluid Typography?
Usually, when designing for different screen sizes, we use media queries to determine the font size of our typographic elements. Although this usually gives enough control for the more conventional devices, it doesn’t cover all of the screen sizes.
By using fluid typography, we can make the typography scale more logically between all sorts of different devices.
This is now possible in all evergreen browsers because of the clamp() function in CSS. It is perfect for the job and reduces our media query writing, thus saving us a bit of file size along the way.
How Exactly Does This clamp() Function Work For Typography?
This takes into account three numbers: a minimum bound, preferred value, and a maximum bound. By using rem values, we can increase the accessibility a bit, but it’s still not 100% foolproof, especially for external browser tools.
However, there is a bit of a problem. When you read those clamp functions inside your CSS, it’s still hard to see exactly what is happening. Just imagine a file full of font sizes that look like this:
clamp(1.44rem, 3.44vw + 0.75rem, 2.81rem)
But with a little help from the sass function, we can make these font sizes much more readable.
What Do We Want To Achieve With This Simple Sass Function?
In short, we want to do something like this: We have a minimum font size, from the moment our breakpoint is larger than 400px, we want it to scale it to our biggest font size until the maximum breakpoint is reached.
The minimum and maximum font sizes are covered quite easily. If we want a minimum font size of 16px (or 1rem) and a maximum font size of 32px (or 2rem), we already have the two parts of our clamp function:
clamp(1rem, [?], 2rem)
Creating A Basic Automated Fluid Function
This is where things get tricky, and I suggest you follow the article by Adrian Bece, who gives a great in-depth explanation of the math behind this.
Let’s get ready to do some mathematics for this to happen in Sass, so let’s create our fluid-typography.scss function file and start by adding sass:math and the function with the values we’ll need:
In most cases, we will be using a viewport width when it comes to fluid typography, so this makes a good default. However, there are some cases, especially when using the clamp() function for vertical spacing, where you want to use a viewport height instead of width. When this is desired, we can change the outputted unit and use a minimum and maximum breakpoint for the height:
Updating The Function To Make The Calculations Feel More Natural
We got what we need, but let’s be honest, most of the time, we are implementing a design, and it doesn’t feel natural to pass our viewports as rems. So, let’s update this function to use pixels as a viewport measurement. While we’re at it, let’s update the font sizes so we can use pixel values for everything. We will still convert them to rem units since those are better for accessibility.
First, we’ll need an extra function to calculate our rem values based on a pixel input.
Note: This won’t work if you change your base rem value.
At first glance, this seems perfect, but mostly that’s because I’ve been using very simple values. For example, when clamping to a maximum value of 31px instead of 32px, our rem values won’t be so rounded, and our output will get a bit messy.
If you’re like me and find this a bit messy as well, we could round our values a little bit to increase readability and save some bytes in our final CSS file. Also, it might get a bit tedious if we always have to add the viewport, so why not add some defaults in our function?
Rounding Our Values And Adding Some Defaults
Let’s start by adding a rounding function to our Sass file. This will take any input and round it to a specific amount of decimals:
Now we can update our output values with rounded numbers. Update the function accordingly. I would suggest setting at least two decimals for the output values for the most consistent results:
A Final Note: Be A Happy Clamper For All users Out There
If you followed this little tutorial and were amazed by it, you might want to add this clamp() method for everything, but there is an important side note when it comes to accessibility.
Note: When you use vw units or limit how large text can get with clamp(), there is a chance a user may be unable to scale the text to 200% of its original size.
We can use this method today because of the great browser support. By being smart on the usage, I’m sure it can be a beautiful addition to your upcoming project or as an upgrade to a previous one.
Shutterstock is a renowned global marketplace for designers and creators to sell royalty-free images, footage, illustrations, and vector graphics. With a huge contribution all over the world, its library of more than 200 million stock photos, illustrations, and vectors make Shutterstock one of the best vector websites to find design elements in the creative community.
But as the stock image market grows, there are more and more websites and platforms that also provide high-quality and even free images. It’s no doubt that when it comes to design, having more options, and more inspiration is never wrong. In this post, I am going to list the 10 best vector websites to find and download free illustrations as Shutterstock alternatives.
Shutterstock: Pros and Cons
There are many advantages of Shutterstock that we can mention, including:
High-quality and various resources of many kinds (images, videos, sound effects, music, templates)
Enhanced licenses are also provided to use the content for distribution to a large audience or on merchandise. (of course, except editorials)
AI-powered search with truly impressive results
However, together with some pros above come several cons that we might want to search for other platforms instead.
Difficult for beginners or amateurs: so many choices regarding types of resources and packs of subscriptions make it more difficult to use, especially for those who are not really Internet masters. I believe that even for those who are experienced, it takes time to read and fully understand their licenses and other useful guides.
Too expensive: subscriptions come with limited numbers of image downloads monthly and enhanced licenses do cost an arm and a leg even for single users.
In terms of simplicity and affordable pricing, I suggest the 10 following best vector websites and platforms as Shutterstock alternatives.
illustAC
Compared to Shutterstock, illustAC has some advantages below.
Simple to use: this is about illustrations and vector graphics – no other distractions. You visit the site, start searching for the illustrations you want and download them. You need to sign up or log in to download, but no card info is required when onboarding as free users.
Simple and affordable subscription packs: Monthly for 12.2$ and Annually for 132$
NO download limits: unlimited download times for premium users
NO attribution required
Other advantages:
Bulk download for premium users: from search result pages, you can choose file types you like, add them up to the download folder and download up to 10 files at a time.
License for commercial uses at a reasonable price: offer an Extra license at 29.99$ per license to cover the usage of the images as the main element for products that will be sold to multiple clients. No limitation in the number of distributions and time of use.
Download one format at a time: Shutterstock and some other platforms will let you download all files in a pack. Usually, it’s not really necessary to download such heavy files. On illustAC, we can choose what type of file format we want to download. You DON’T need to unzip or check any licenses within – SIMPLE and EASY in a single click.
Unique content: illustAC offers various types of free vectors including brushes, templates, graphic backgrounds, etc. But the truly special one is that you can find real Japanese tastes here, from sushi illustrations to bold Japanese decor patterns that you can see from nowhere else.
Freepik
Compared to Shutterstock, Freepik has some advantages below.
Simple and affordable subscription packs: Monthly for 15EUR (~14.72$) and Annually for 108EUR (105.98$)
Free downloads both for guests and free users: you don’t need to sign up or log in to download images you like. Guests can also download up to 3 free illustrations per day. If you want more, free users can download up to 10 images, and premium users for 100 downloads a day.
Trendy and up-to-date content: just like Shutterstock, Freepik is a house of millions of creators around the world, you can always find trendy content there.
Other embedded platforms for UI designs: Flaticons and Storyset are two other platforms from Freepik where you can find and download free icons and illustrations for user interface design
Vecteezy
Compared to Shutterstock, Vecteezy has some advantages below.
Simple and affordable subscription packs: Monthly for 15$ and Annually for 108$
Free downloads for both guests and free users: you can download a lot of free content on Vecteezy with download limits of 3 images for guests and unlimited for free users. Of course, attributions are required in this case, just the same as Freepik. Pro content can only be downloaded when upgrading.
Licenses are easy to understand and compare: Vecteezy doesn’t challenge users with difficult terms when it comes to licensing explanation and comparison. It won’t take long to fully understand what they offer.
IconScout
IconScout is all about illustrations of all types (flat illustrations, icons, 3D illustrations, and animations). Compared to Shutterstock, it has some advantages below.
Simple and easy navigation: if you want to search for illustrations, IconScout is easy to navigate.
Simple licenses to understand and compare: IconScout provides 2 kinds of licenses (digital license and physical unlimited license) which are clearly explained and compared in simple words.
Free assets to download with attribution
Affordable subscription packs (annually only, no monthly packs): Yearly for all assets will cost 179.99$ and for icons only will cost 155.99$.
Manypixels
Manypixels is a platform providing design solutions for businesses, entrepreneurs to cooperatives. Together with design services, it also shares free illustrations and free icons resources to download.
Although these libraries are limited in the number of content available, compared to Shutterstock, it still has some advantages below.
The content is all FREE for commercial and personal uses: you don’t need to pay to download illustrations and icons on Manypixels. You can
NO download limits: you can download any content you like without sign-up / log-in and no limits.
NO attribution required
Drawkit
Drawkit is also another platform that offers both free and premium illustrations and icons. It is a good alternative for Shutterstock in terms of good pricing, free downloads, and simple licensing.
Good pricing: Premium content is offered by different themes. You can pay for each pack you like.
Simple licensing: Drawkit’s license is easy to understand (not for merchandise or included in digital design templates, for example)
Other Open Sources and CC0 Platforms
The websites below surpass Shutterstock in terms of no download limits, simple licenses, and no requirement for attribution.
NO download limits: you can download whatever you like with no limitation (but of course, there are fewer options to choose from, and most of them are suitable for UI design)
FREE for all non-commercial or commercial uses EXCEPT redistribution
NO attribution required
However, the number of resources available on these websites and platforms is limited. If you want to have a wide range of free illustration options, you’d better try the stock and royalty-free illustrations platforms mentioned above.
Conclusion
Here we’ve mentioned the top Shutterstock alternative vector sites to download free illustrations. Each of these sites has its own usage guides, licenses, and type of resources. Before downloading the images, make sure to check out their terms and conditions to avoid any unwanted copyright infringement.
We hope that with the list of best vector websites above, you can save time and costs when you need to find illustrations and vector graphics for your next projects.
AI-powered marketing automation is here to stay. AI reduces menial tasks, frees up time for generating new business, and allows companies to further personalized messaging to effectively move users through the funnel – without sacrificing time. To that end, AI-powered marketing automation is growing quickly, with 79% of companies applying this technology to many of their marketing tasks.
Yet, with all this acknowledged, there’s a misconception that to maximize the efficiency of your business you must implement AI-powered marketing automation in all tasks.
This way of thinking often comes at the expense of manual processes that work just fine. Some manual tasks may be more reasonable or cost-effective for new businesses with small teams – or low-effort manual processes make sense to keep workflows simple and manageable.
This article explores why some processes can stay manual – and why others are best suited to be automated.
The Benefits of AI In Marketing Automation
We know that automating daily tasks, specifically within sales and marketing, improves day-to-day workload. Marketing automation has positively affected lead generation, overhead costs, and conversion increases.
As per recent studies, 80% of users who strategically implement marketing automation tools saw an increase in lead generation, and 77% of users saw an increase in conversions.
For example, posting on social media doesn’t need to be a manual task anymore – tools like Buffer, Hootsuite, and Later make it easy to schedule posts.
Yet, designing posts and cultivating a personalized social media strategy is a critical manual task that AI and marketing automation can’t replace. Relevant, targeted messaging is much more likely to encourage users to move through the sales funnel, and AI can’t replace a copywriter skilled in brand voice. But, AI can move the messaging through systematic processes more effectively.
Thoughtfully integrated automation can provide robust data about the actions customers take on your website. AI marketing automation, when done correctly, uses predetermined workflows in conjunction with this data to improve the customer experience. Using data to improve the customer experience could look like a targeted email that follows an abandoned cart or relevant ad content that showcases products or services previously viewed.
Marketing automation makes it easy to position marketing collateral where it makes the most sense within an individual’s buyer journey. However, of course, it entirely depends on the existing workflows within the system. AI marketing automation will only do what you tell it to do – but it will do it well.
Avoid AI In Marketing Automation for Automation’s Sake
Too often, businesses eliminate effective manual processes in a quest to automate everything for the sake of digital transformation. AI in marketing has changed how we work, and it’s understandable to want to be at the forefront of technology.
Automation tools can undoubtedly make some processes more efficient, by adding a level of precision to those tasks more difficult or time-consuming for humans to carry out. Some of these tools help copywriters become more productive. Some create variations of advertising copy from scratch given a few parameters so you have a wealth of choices when building out advertising campaigns. Others help marketers optimize their budgets and make the right spending decisions based on their resources and goals.
Even so, there’s a time and place. Some manual processes can work in tandem with automated ones, which improves efficiency across the board. An excellent example of this is automated copywriting tools like Jasper.ai or Jarvis. These AI-based marketing automation tools can get a copywriter started during those moments when the page is blank and a deadline looms. But, having a real person proof or edit that copy to catch the nuances of voice, tone, and brand language is a necessary manual task. AI is close, but not quite there.
The most important thing is finding a balance right for your situation.
Understanding When Automation Makes Sense, and When It Does Not
Finding the processes that can benefit from automation involves clear strategic thinking and drilling down on every facet of your business, from marketing to hiring to accounting.
Without a doubt, many areas of your business will require some kind of operational process improvement, most easily taken care of by automation, but usually not in its entirety.
For example, accounting processes will still require a fair degree of manual input, so integrating an automation software that complements both manual and automated processes is essential.
Here are some clarifying questions to ask yourself when considering marketing automation using AI:
Does the task require strategy? Emotion, creativity, higher intelligence, and nuance are all things automation cannot replace. If the task requires any of these but is time-consuming otherwise, try to see if you can automate the lesser portions of the task.
Is the task repetitive? If the task is repetitive, such as data entry, this can easily lead to fatigue and feelings of burnout. Automation can help alleviate time spent doing mundane tasks.
Does it free up your schedule? If automation frees up your calendar to complete your other tasks more efficiently, this is one of the prime benefits – use it!
Is there a high potential for human error? If the task involves plenty of room for error and automation makes sense, this can save your employees time and stress and save your business money.
The tradeoff for automating these tasks should always be more time and mental bandwidth to focus on business-critical functions such as sales, customer service, or other jobs that can’t be automated.
When asking these clarifying questions, keep in mind the potential to scale. If the processes can’t grow as your business grows, it might be better to keep things manual for now.
Examples of AI in Marketing Automation
Flesh out this section to augment word count and talk about different types of AI marketing automation tools other than copywriting tools
AI for marketing automation has reached the peak of trendiness in recent years. A wide variety of tools have emerged across several marketing niches including copywriting, email marketing, content marketing, website-based chat, marketing analytics, and customer relationship management.
The creators of these tools have different end goals. Some tools are intended to augment manual practices and make those practices more efficient and effective. The founders of other tools argue that what they have built will completely revolutionize that particular subset of marketing to the point that automation will become the gold standard, and manual processes will be completely eliminated.
The latter seems much more likely than the former, given all of the nuances required in the marketing industry, that at this point in our history, only humans can understand and apply to their daily work.
AI and the Copywriting Industry
The copywriting industry – of the niches mentioned above – seems the ripest for disruption, and is an industry where artificial intelligence automated marketing may see a substantial disruption. There’s an open debate, however, that these AI copywriting tools can ever replace human copywriters in the way the founders of the companies promoting them claim will happen in coming years.
Over the last few years, emerging copywriting AI tools such as Jarvis or Jasper.ai have shaken up how copywriters and business owners approach copywriting and marketing.
In one camp, business owners who see the value of content marketing yet don’t have that way with words or who may speak English as a second language might eventually heavily rely on these AI copywriting tools.
In the other camp, seasoned, expert copywriters may feel threatened by the supposed prowess of a computer that can, allegedly, ‘write faster than a human.’
Marketing for these tools varies. Depending on the target audience, the organic and paid messaging can switch from positioning copy AI tools as a helpful tool for existing copywriters to automate their processes and write faster (and therefore scale their business) to non-copywriter business owners that want copy written faster than the human brain can produce.
However, copy AI tools lack the fundamental connection to the human spirit; AI lacks the necessary motivation, drive, and consciousness to drive the nuance in tone, style, and voice that makes a good copy so enjoyable to read. Therefore, there has to be some degree of manual review.
Copy AI tools have a long way to go before they can replace human writers. However, these tools can be perfect for short-form copy in a pinch or are a great starting point for copywriters (who want to take the time to become familiar with them) who need a little nudge to bring a piece of copy to life.
A copywriter that uses copy AI tools to streamline the creative process and reduce steps is a perfect example of combining manual processing with automation.
Questions to Consider as You Think About Adopting Artificial Intelligence Automated Marketing
The most important thing you can do as you consider adopting artificial intelligence automated marketing is to ask yourself some tough questions about why you see it as an option.
Here are some potential scenarios:
The work your marketing team is doing needs to be augmented (maybe because you have a small team or limited resources)
Your team is making consistently making mistakes that are easily avoidable through automation (usually due to manual data input)
Manual work that’s being done by an entry-level employee could be replaced by an AI marketing tool
You’re looking for a better return on investment for your marketing spend (the fixed costs of salary for your team members aren’t being replaced by closed business, for example)
Your marketing is too blanketed, and not personalized enough, and you want to lean on tools driven by AI to improve that personalization
You need to make more decisions, faster
In each of these scenarios, the work of your human team members is being amplified but not replaced by marketing automation. And for now, that’s the best-case scenario to maintain the chemistry you have built on your teams and the trust your marketing employees have in their futures with you.
Some Things to Consider About Marketing Automation, In General
There’s little doubt left that AI and marketing automation is the future of content creation, but even with that being the case, these tools shouldn’t totally dominate your content strategy.
AI holds the most power in helping lean marketing organizations publish more content, more often. When you lean in on the power of AI to help you replicate and spin out content, it’s much easier to put a high volume of your work out into the world.
Some AI content marketing tools can also help you better understand the types of content your community prefers to interact with, and help you craft content along those lines, accordingly.
Artificial intelligence is the backbone of automation, but as a content marketer – or generalized marketer – your expectation shouldn’t be for the work that your human team does to be replaced by marketing automation and artificial intelligence, but rather, amplified by it.
Human Work is Amplified But Not Replaced By Marketing Automation
Remember, marketing automation using AI does not replace marketing. It makes it easier, to be sure, but relying solely on automation takes away the strategy and humanity that has made the most iconic campaigns so successful.
Marketing teams within early-stage companies would do well to place their focus on developing a robust marketing plan – and how to execute it – and then focus on automation.
For newbie marketing teams, staying abreast of ever-changing marketing and SEO best practices through industry-leading blogs, listening to podcasts, and following seasoned marketers online can be invaluable when fleshing out a new marketing campaign or strategy.
Marketing automation is the natural next step after the company sees growth and all team players are well-versed in the marketing strategy.
The State of CSS survey recently opened up. Last year, the survey confirmed everyone’s assumptions that TailwindCSS is super popular and CSS variables are mainstream. It also codified what many of us want from CSS, from Container Queries to a parent selector. (Spoiler alert, we now have both of ’em.)
While I wouldn’t say the results have been super surprising each year, this time I’m excited to start seeing more historical trends reveal themselves. The survey has been running since 2019, so that’s going to be four years (ancient in front-end years!) of data to see if certain frameworks came and went, specific features are gaining momentum, what general learning practices are out there, and just plain more context. It takes time for stuff to build up like this, so kudos to Sacha Greif for keeping this thing going.
And speaking of the team behind the survey, Lea Verou is new to the bunch and lead this year’s edition. Lea made some nice additions, including more open-ended comments, questions about browser inconsistencies, and a question that compares the amount of time you write CSS versus JavaScript.
Browsers actually use this stuff to help prioritize what features to work on — so definitely add your voice to the mix! The polls close on October 20.
This is a post about Shoelace, a component library by Cory LaViska, but with a twist. It defines all your standard UX components: tabs, modals, accordions, auto-completes, and much, much more. They look beautiful out of the box, are accessible, and fully customizable. But rather than creating these components in React, or Solid, or Svelte, etc., it creates them with Web Components; this means you can use them with any framework.
Some preliminary things
Web Components are great, but there’s currently a few small hitches to be aware of.
React
I said they work in any JavaScript framework, but as I’ve written before, React’s support for Web Components is currently poor. To address this, Shoelace actually created wrappers just for React.
Another option, which I personally like, is to create a thin React component that accepts the tag name of a Web Component and all of its attributes and properties, then does the dirty work of handling React’s shortcomings. I talked about this option in a previous post. I like this solution because it’s designed to be deleted. The Web Component interoperability problem is currently fixed in React’s experimental branch, so once that’s shipped, any thin Web Component-interoperable component you’re using could be searched, and removed, leaving you with direct Web Component usages, without any React wrappers.
Server-Side Rendering (SSR)
Support for SSR is also poor at the time of this writing. In theory, there’s something called Declarative Shadow DOM (DSD) which would enable SSR. But browser support is minimal, and in any event, DSD actually requires server support to work right, which means Next, Remix, or whatever you happen to use on the server will need to become capable of some special handling.
That said, there are other ways to get Web Components to just work with a web app that’s SSR’d with something like Next. The short version is that the scripts registering your Web Components need to run in a blocking script before your markup is parsed. But that’s a topic for another post.
Of course, if you’re building any kind of client-rendered SPA, this is a non-issue. This is what we’ll work with in this post.
Let’s start
Since I want this post to focus on Shoelace and on its Web Component nature, I’ll be using Svelte for everything. I’ll also be using this Stackblitz project for demonstration. We’ll build this demo together, step-by-step, but feel free to open that REPL up anytime to see the end result.
I’ll show you how to use Shoelace, and more importantly, how to customize it. We’ll talk about Shadow DOMs and which styles they block from the outside world (as well as which ones they don’t). We’ll also talk about the ::part CSS selector — which may be entirely new to you — and we’ll even see how Shoelace allows us to override and customize its various animations.
If you find you like Shoelace after reading this post and want to try it in a React project, my advice is to use a wrapper like I mentioned in the introduction. This will allow you to use any of Shoelace’s components, and it can be removed altogether once React ships the Web Component fixes they already have (look for that in version 19).
Introducing Shoelace
Shoelace has fairly detailed installation instructions. At its most simple, you can dump and tags into your HTML doc, and that’s that. For any production app, though, you’ll probably want to selectively import only what you want, and there are instructions for that, too.
With Shoelace installed, let’s create a Svelte component to render some content, and then go through the steps to fully customize it. To pick something fairly non-trivial, I went with the tabs and a dialog (commonly referred to as a modal) components. Here’s some markup taken largely from the docs:
<sl-tab-group>
<sl-tab slot="nav" panel="general">General</sl-tab>
<sl-tab slot="nav" panel="custom">Custom</sl-tab>
<sl-tab slot="nav" panel="advanced">Advanced</sl-tab>
<sl-tab slot="nav" panel="disabled" disabled>Disabled</sl-tab>
<sl-tab-panel name="general">This is the general tab panel.</sl-tab-panel>
<sl-tab-panel name="custom">This is the custom tab panel.</sl-tab-panel>
<sl-tab-panel name="advanced">This is the advanced tab panel.</sl-tab-panel>
<sl-tab-panel name="disabled">This is a disabled tab panel.</sl-tab-panel>
</sl-tab-group>
<sl-dialog no-header label="Dialog">
Hello World!
<button slot="footer" variant="primary">Close</button>
</sl-dialog>
<br />
<button>Open Dialog</button>
This renders some nice, styled tabs. The underline on the active tab even animates nicely, and slides from one active tab to the next.
I won’t waste your time running through every inch of the APIs that are already well-documented on the Shoelace website. Instead, let’s look into how best to interact with, and fully customize these Web Components.
Interacting with the API: methods and events
Calling methods and subscribing to events on a Web Component might be slightly different than what you’re used to with your normal framework of choice, but it’s not too complicated. Let’s see how.
Tabs
The tabs component () has a show method, which manually shows a particular tab. In order to call this, we need to get access to the underlying DOM element of our tabs. In Svelte, that means using bind:this. In React, it’d be a ref. And so on. Since we’re using Svelte, let’s declare a variable for our tabs instance:
It’s the same idea for events. There’s a sl-tab-show event that fires when a new tab is shown. We could use addEventListener on our tabs variable, or we can use Svelte’s on:event-name shortcut.
That works and logs the event objects as you show different tabs.
Typically we render tabs and let the user click between them, so this work isn’t usually even necessary, but it’s there if you need it. Now let’s get the dialog component interactive.
Dialog
The dialog component () takes an open prop which controls whether the dialog is… open. Let’s declare it in our Svelte component:
<script>
let tabs;
let open = false;
</script>
It also has an sl-hide event for when the dialog is hidden. Let’s pass our open prop and bind to the hide event so we can reset it when the user clicks outside of the dialog content to close it. And let’s add a click handler to that close button to set our open prop to false, which would also close the dialog.
<sl-dialog no-header {open} label="Dialog" on:sl-hide={() => open = false}>
Hello World!
<button slot="footer" variant="primary" on:click={() => open = false}>Close</button>
</sl-dialog>
And that’s that. Interacting with a component library’s API is more or less straightforward. If that’s all this post did, it would be pretty boring.
But Shoelace — being built with Web Components — means that some things, particularly styles, will work a bit differently than we might be used to.
Customize all the styles!
As of this writing, Shoelace is still in beta and the creator is considering changing some default styles, possibly even removing some defaults altogether so they’ll no longer override your host application’s styles. The concepts we’ll cover are relevant either way, but don’t be surprised if some of the Shoelace specifics I mention are different when you go to use it.
As nice as Shoelace’s default styles are, we might have our own designs in our web app, and we’ll want our UX components to match. Let’s see how we’d go about that in a Web Components world.
We won’t try to actually improve anything. The Shoelace creator is a far better designer than I’ll ever be. Instead, we’ll just look at how to change things, so you can adapt to your own web apps.
A quick tour of Shadow DOMs
Take a peek at one of those tab headers in your DevTools; it should look something like this:
Our tab element has created a div container with a .tab and .tab--active class, and a tabindex, while also displaying the text we entered for that tab. But notice that it’s sitting inside of a shadow root. This allows Web Component authors to add their own markup to the Web Component while also providing a place for the content we provide. Notice the element? That basically means “put whatever content the user rendered between the Web Component tags here.”
So the component creates a shadow root, adds some content to it to render the nicely-styled tab header along with a placeholder () that renders our content inside.
Encapsulated styles
One of the classic, more frustrating problems in web development has always been styles cascading to places where we don’t want them. You might worry that any style rules in our application which specify something like div.tab would interfere with these tabs. It turns out this isn’t a problem; shadow roots encapsulate styles. Styles from outside the shadow root do not affect what’s inside the shadow root (with some exceptions which we’ll talk about), and vice versa.
The exceptions to this are inheritable styles. You, of course, don’t need to apply a font-family style for every element in your web app. Instead, you can specify your font-family once, on :root or html and have it inherit everywhere beneath it. This inheritance will, in fact, pierce the shadow root as well.
CSS custom properties (often called “css variables”) are a related exception. A shadow root can absolutely read a CSS property that is defined outside the shadow root; this will become relevant in a moment.
The ::part selector
What about styles that don’t inherit. What if we want to customize something like cursor, which doesn’t inherit, on something inside of the shadow root. Are we out of luck? It turns out we’re not. Take another look at the tab element image above and its shadow root. Notice the part attribute on the div? That allows you to target and style that element from outside the shadow root using the ::part selector. We’ll walk through an example is a bit.
Overriding Shoelace styles
Let’s see each of these approaches in action. As of now, a lot of Shoelace styles, including fonts, receive default values from CSS custom properties. To align those fonts with your application’s styles, override the custom props in question. See the docs for info on which CSS variables Shoelace is using, or you can simply inspect the styles in any given element in DevTools.
Inheriting styles through the shadow root
Open the app.css file in the src directory of the StackBlitz project. In the :root section at the bottom, you should see a letter-spacing: normal; declaration. Since the letter-spacing property is inheritable, try setting a new value, like 2px. On save, all content, including the tab headers defined in the shadow root, will adjust accordingly.
Overwriting Shoelace CSS variables
The component reads an --indicator-color CSS custom property for the active tab’s underline. We can override this with some basic CSS:
sl-tab-group {
--indicator-color: green;
}
And just like that, we now have a green indicator!
Querying parts
In the version of Shoelace I’m using right now (2.0.0-beta.83), any non-disabled tab has a pointer cursor. Let’s change that to a default cursor for the active (selected) tab. We already saw that the element adds a part="base" attribute on the container for the tab header. Also, the currently selected tab receives an active attribute. Let’s use these facts to target the active tab, and change the cursor:
sl-tab[active]::part(base) {
cursor: default;
}
And that’s that!
Customizing animations
For some icing on the metaphorical cake, let’s see how Shoelace allows us to customize animations. Shoelace uses the Web Animations API, and exposes a setDefaultAnimation API to control how different elements animate their various interactions. See the docs for specifics, but as an example, here’s how you might change Shoelace’s default dialog animation from expanding outward, and shrinking inward, to instead animate in from the top, and drop down while hiding.
That code is in the App.svelte file. Comment it out to see the original, default animation.
Wrapping up
Shoelace is an incredibly ambitious component library that’s built with Ceb Components. Since Web Components are framework-independent, they can be used in any project, with any framework. With new frameworks starting to come out with both amazing performance characteristics, and also ease of use, the ability to use quality user experience widgets which aren’t tied to any one framework has never been more compelling.
Each month we publish this roundup of the best new fonts for designers to help you find new ways of packing personality into your designs.
In October’s edition, you’ll find a number of revivals and a ton of vintage inspiration, all wrapped up with a modern twist. After years of geometric sans-serifs, a few decorative flourishes are more than welcome. Enjoy!
The Future
The Future and its accompanying monospace The Future Mono is a homage to the classic Futura. The Future is a great revision of classic forms, and The Future Mono is a blend of Western Modernism and Japanese typographic styles.
Rapidissima
Rapida and Rapidissima began as part of a master’s course at the Royal Academy of Art in Den Haag. While Rapida is a careful, usable serif with lots of thoughtful details, Rapidissima is a visually exciting exploration of speed.
Aiglon
Aiglon is a pseudo-geometrics sans-serif with beautiful proportions. It draws inspiration from 20th-century architectural lettering. It’s a tremendous alternative to Gotham for those looking for a more European aesthetic.
Raskal Oner Write
Raskal Oner Write is a script font for designers that don’t want a script font. All of the classic feel of handwritten letters is here, but the construction is entirely original. Contextual alternatives combine to create the visual look of lettering.
Grostino
Grostino is an elegant display typeface. The enormous contrast in width between its rounded glyphs and its square glyphs adds enormous personality. It’s ideal for branding projects that need to evoke classicism.
Figtree
Figtree is a highly usable sans-serif packed with practical features, including fractions, monospaced numbers, and scientific inferiors. It’s both minimal and friendly, making it an ideal choice for corporate design systems. It’s free to download.
Gills & Co
Gills & Co is a modern serif that draws inspiration from Art Nouveau to create beautiful finials and ligatures. It works really well as a logotype and for packaging.
Catalog
Catalog is a sturdy, easy-to-use serif with thick slab serifs. It has a simplified shape and is easily readable on lower-resolution screens. It features an unusual lowercase g, which adds visual interest to passages of text.
Kreol Display
Kreol Display is a didone typeface with some interesting details that raise it above similar designs. The lowercase ‘a’ and the uppercase ‘R’ are particularly pleasing.
Gwen
Gwen is a typeface family that includes a highly characteristic display face and a more subtle text face. There are seven different weights, and it is available as a variable font.
Benogi
Benogi is a display font run through with wave-like forms. The ’70s aesthetic is continued in the proportion of the glyphs. It’s a great option for health and beauty product branding.
Marcin Antique
Marcin Antique is inspired by early French grotesque typefaces. It has just been reissued with new widths, additional weights, and redrawn italics, making it an even more usable sans-serif.
VVDS The Dickens Tale
It’s horrifying to say it, but yes, the holiday season is just weeks away. If you’re preparing marketing material with a heritage feel, then check out The Dickens Tale, it’s as classic as candy canes and Peanuts reruns.
Povetarac Sans
Povetarac Sans is a workhorse of a sans-serif that performs well as both display and running text. Inspired by vintage designs, it comes with six weights and supports fractions.
Blothe
Blothe is a fabulously chunky display face that is drawn wide, thick, and rounded. Use it at huge sizes to make the most of its weighty presence.