RESTify Your SQL Data

Strategic Business Agility

RESTful APIs are at the heart of Digital Transformation and are required for mobile apps and integration. They are core to Business Agility. That's strategic.

But the conventional development process — create an ORM and design and code your APIs — is remarkably code-intensive and complex. And then there's the Business Logic — a substantial portion of any system — more code. Not agile.

What a Self-Organizing Team Is (Not)

No, self-organizing teams aren't teams gone wild.

At a recent conference, I overheard three managers talking about self-organizing teams:

“You can’t just turn people loose and let a team make all the decisions. They’ll mess things up. And with all these Scrum Masters, coaches, and self-organizing teams, sounds like I’m out of a job,” said one with resignation.

Book Review: Designing Data-Intensive Applications (Part 3)

This is part 3 of a three-part review. You can find part 1 here and part 2 here.

10. Batch Processing

This is the first chapter of the part of the book dealing with derived data. There is a distinction between systems of record (holds the authoritative version of the data) and derived data systems. Data in derived data systems is existing data transformed or processed in some way. For example, a cache or a search index.

Nested Gradients with background-clip

I can't say I use background-clip all that often. I'd wager it's hardly ever used in day-to-day CSS work. But I was reminded of it in a post by Stefan Judis, which coincidentally was itself a learning-response post to a post over here by Ana Tudor.

Here's a quick explanation.

You've probably seen this thing a million times:

The box model visualizer in DevTools.

That's showing you the size and position of an element, as well as how that size is made up: content size, padding, margin, and border.

Those things aren't just theoretical to help with understanding and debugging. Elements actually have a content-box, padding-box, and border-box. Perhaps we encounter that most often when we literally set the box-sizing property. (It's tremendously useful to universally set it to border-box).

Those values are the same values as background-clip uses! Meaning that you can set a background to only cover those specific areas. And because multiple backgrounds is a thing, that means we can have multiple backgrounds with different clipping on each.

Like this:

See the Pen
Multiple background-clip
by Chris Coyier (@chriscoyier)
on CodePen.

But that's boring and there are many ways to pull off that effect, like using borders, outline, and box-shadow or any combination of them.

What is more interesting is the fact that those backgrounds could be gradients, and that's a lot harder to pull off any other way!

See the Pen
Nested Gradients
by Chris Coyier (@chriscoyier)
on CodePen.

The post Nested Gradients with background-clip appeared first on CSS-Tricks.

The AI Impact on Software Testing

Software testing performed by human resources still has its value, although Artificial Intelligence (AI) is a promising way to make the process easier, faster, and clearer. Someday, the emerging technology of AI may force software testers to start looking for a new job elsewhere. But don't get tripped up with such predictions.

Strategies to implement AI and machine learning are far from perfect; companies still have plenty of challenges to work through. However, one thing is certain: the use of AI by QA professionals would upgrade the whole testing process, enhance testers' professional skills, and contribute to business growth.

Lock-In: Let Me Count the Ways

Vendor lock-in can occur a few different ways


We've all heard the term "Vendor Lock-in," but many don't know about the wide variety of ways in which this stealthy lock-in takes place. Rigidity and frustration caused by this lock-in can mean high costs for enterprises and unhappiness for developers. With new technologies like virtualization and cloud computing, vendors are finding more ways to force users to stay on their platform and purchase their offerings.  The following list describes the different kinds of lock-in that have been seen in the IT industry.

How Does Leadership Fit Into Self-Organizing Teams?

There may not be an 'I' in team, but that doesn't mean there isn't a leader, even in self-organizing ones.

Let’s say we’ve “conquered agile," and the prophecy came true: We have a self-organizing team!

But how does leadership fit into this? What does a leader do in a self-organizing team?

Intro to Couchbase Transactions Java API [Video]

This video, about Couchbase Distributed ACID Transactions, is a quick guide for you, the busy Java developer, on how to get started with the new API, including some important best practices you’ll want to implement. I’m not going to cover how transactions work or dive into ACID, as there are other resources being released that cover that.

Couchbase Transactions are available for Community Edition, and there are no new services to configure, and there’s nothing new to set up on the cluster. Just add a line to your Gradle or Maven project to pull in the library, and you’re ready to go — you can check out our documentation for transactions and the Java API documentation to get started.

StandardJS Pauses Experiment with Ads in the Terminal after Linode Pulls Sponsorship

Feross Aboukhadijeh, maintainer of the StandardJS library, a JavaScript style guide, linter, and automatic code fixer, launched an experiment last week that places ads in the terminal in order to fund development. The experiment has since been paused after receiving negative feedback from the developer community, causing Linode, one of the initial sponsors, to remove its advertisement.

“I think that the current model of sustaining open source is not working and we need more experimentation,” Aboukhadijeh said. “This is one such experiment.” He developed a module that inserts an ad whenever Standard 14 is installed. Sponsorship funds are designated to pay for maintainer time, which he defined as “writing new features, fixing bugs, answering user questions, and improving documentation.”

Aboukhadijeh is a prolific developer who has authored more than 100 packages on npm that are downloaded 100+ million times per month. Standard is his most popular open source project and is used by high profile projects and companies, including Node.js, npm, GitHub, Automattic, and many more.

Aboukhadijeh said his goal with the experiment is to make Standard and other open source projects healthier.

“For complex reasons, companies are generally hesitant or unwilling to fund OSS directly,” he said. “When it does happen, it’s never enough and it never reaches packages which are transitive dependencies (i.e. packages that no one installs explicitly and therefore no one knows exists). Essentially, we have a public good which is consumed by huge numbers of users, but which almost no one pays for. Fortunately, there exists a funding model that usually works for public goods like this – ads.”

Here is an example of the LogRocket ad that was part of the initial experiment:

While some developers communicated support for open source maintainers to monetize their projects in whatever way they choose, the majority of feedback on GitHub, Hacker News, Reddit, and social media strongly criticized this particular approach.

William Hilton, developer at Stoplight, speculated on the consequences of this type of advertising becoming a popular funding model:

I do worry that npm install will just become a long trail of banner ads though eventually and it won’t scale. Because if every npm package adds ads, the noticeability of each ad will diminish. (Interestingly, the most valuable “realestate” will be packages whose banner is displayed last, so if it becomes a literal “race-to-the-bottom” people might add sleep statements to their post-install scripts so they are displayed nearest the bottom. What a dystopian installation experience!)

He also noted that Yarn blocks the output of post-install scripts, which in this case would serve as built-in ad-blocking. Yarn’s maintainer chimed in on the thread with more context.

“As maintainer of Yarn, I’m strongly against this pattern, although not for the reasons you might think,” Maël Nison said. “Post-install scripts deoptimize packages and break workflows.

“Yarn already doesn’t print the build logs unless they make the installs crash, so this post-install script wouldn’t have any visible effect for our users. Still, I value the health of the ecosystem a lot, both from the point of view of maintainers and users, and I would be happy to discuss how we could satisfy this use case in a more integrated and less intrusive way.”

Since this is a newer experiment and hasn’t gone mainstream, it’s not clear whether npm may decide to block all methods of serving advertisements through the terminal in the future. A new module called No CLI Ads was created in response to Aboukhadijeh’s funding module. It blocks ads from appearing in console output. npm-adblock is an alternative that functions in a different way. The existence of simple, albeit inconvenient, ways of blocking these types of ads may be all that is necessary to dry up any potential revenue stream.

Feedback on this experiment demonstrates that there is wide support for finding a solution to the problem of open source funding, but most agree that terminal ads is not a viable option. In fact, many commenters identified this approach as the most annoying thing that a package maintainer can do, apart from removing the package. Developers do not wish to be spammed while installing a dependency. One commenter describes his terminal as “the one last stronghold” and “haven of peace” that doesn’t serve ads from corporate overlords.

“Selling ad-space is not innovative,” developer Matthias Hogerheijde said. “And it’s particularly unhelpful in my logs. For me, the issue is more that I don’t want stuff that doesn’t help me in my logs. I wholeheartedly agree with putting your ‘supported by company X’ in the readme. That helps me understand, it does resonate with me when I see certain companies donating money to OSS. I, too, want to live in a perfect world where every developer can live, pay rent and only work on projects they like. That perfect world for me does not include ads in my terminal.”

Reddit commenters took humorous jabs at the idea, penning sample ads that interrupt the build process:

Linode Pulls Sponsorship from Standard’s Terminal Ads Experiment

Standard.js users who were unhappy with the ads in their terminals complained to the sponsors and Linode decided to remove its ad from the experiment.

“We reconsidered after reflecting on the developer community’s reaction,” a Linode representative said on Twitter. “We still passionately support open source software along with @feross, but we’ll be more careful about experimenting in the future while continuing to innovate.”

Prior to pausing the experiment, Aboukhadijeh reported he had raised $2,000, enough to fund five days worth of his time to release Standard 14.

“If we are able to raise additional funds, the next thing I’d like to focus on is out-of-the-box TypeScript support in StandardJS (one of the most common feature requests!) and modernizing the various text editor plugins (many of which are currently unmaintained),” Aboukhadijeh said. “If others in the community are interested in taking the lead on any of these issues, I’d like to direct some funds to you.”

The experiment isn’t entirely off the table, since it seems to have met one of Aboukhadijeh’s immediate objectives, despite annoying (and in some cases infuriating) the developer community.

Four days ago, Standard locked the GitHub thread discussing the new funding model after it became too heated. The project’s maintainers are now evaluating this iteration of the experiment, but the discussion extends beyond the simple question of whether developers like ads in their terminals. A new thread on the project’s repo, titled “What’s wrong with Open Source right now?” has diverted some of the negative feedback into a broader, more productive discussion.

The experiment has reignited important conversations about the sustainability of open source and where project maintainers want to see it go in the future. In a recent tweet, Aboukhadijeh shared a link to particular situation that one maintainer faced in supporting a free syntax highlighting library.

After receiving urgent comments and emails following a release that had errors causing dependencies to break, Ivan Sagalaev, the original author of highlight.js, aptly summarized the current state of the relationship between businesses and open source projects:

Dear fellow engineers, please take this build hiccup as an opportunity to explain to your particular business people that their entire intellectual property is a thin layer on top of a shaky foundation of open-source code lazily maintained by hobbyists or paid for by other businesses having their own goals in mind.

If they really want stability they have to invest in it by, for example, hiring engineers to deal with myriad of dependencies, maintain local stable forks, contribute patches upstream, or whatever — the key point is that it should not look like it ‘just works’ on fairy dust.

Introverts at Work: 4 Reasons Agile Is an Introvert’s Dream

Who says introverts at work can't be agile?

While the main benefits of Agile are higher efficiency and reduced waste of time and resources, shorter delivery time, and more flexibility across the board, there is also one other aspect that requires recognition: It's the impact that the ability to shorten and flex the development process has on human interactions within the organization.

You may also like: Why Social Situations Exhaust Introverts: A Programmer's Tale

Because Agile makes it possible for teams to rely on visual communication and tracking more than on in-person data presentation and direct engagement in face-to-face communication, all team members can easily stay informed and engaged in the work, no matter each individual's comfort level with in-person interaction.

Announcing WPBeginner Growth Accelerator Fund (Round 2)

Last year, I decided to do something that was never done before in the WordPress community. I created the WPBeginner Growth Accelerator, first-ever growth fund focused entirely on WordPress businesses. Today, I want to take the exciting steps and open up the second round of applications as well as share the results from last year.

Introducing WPBeginner Growth Fund Round 2

Note: Applications will be closed on September 30, 2019

What is the WPBeginner Growth Accelerator Fund?

WPBeginner Growth Accelerator Fund is the first-ever growth fund focused entirely on WordPress focused businesses.

As part of this accelerator, we will invest between $100k to $2M in a small group of WordPress focused businesses. Along with the investment, we will work intensively with founders to refine and optimize their existing product / processes by using the Awesome Motive playbook.

Companies will also get to benefit from our vast media resources and the business network that we have built over the last decade.

The Story Behind WPBeginner Growth Accelerator

Over the last decade, we have spent a lot of time talking to users and figuring out how to make things people want. Usually we can see fairly quickly the direction in which an idea should be expanded to make the biggest impact.

It took us a long time to get to this level, and I would have never been here without the help of my mentors and other amazing entrepreneurs who were kind enough to share their wisdom with me.

This kind of mentorship is available in a lot of other verticals, but it’s not openly available in the WordPress business community.

A lot of WordPress entrepreneurs expressed interest in joining the Awesome Motive family, have me join their board, or getting an investment from me to fast-track their business growth. Few also expressed their frustrations about lack of investor interest in the space.

The problem is that the WordPress market is not very well understood by investors. And frankly, majority of WordPress businesses are not large enough to meet their criteria.

But this doesn’t mean that WordPress businesses don’t have the potential. It’s quite the opposite – they have a lot of potential. There are tons of opportunities to grow in the WordPress ecosystem with the right playbook, and I want to help prove that.

After a lot of thought and discussion, I decided to create the first WordPress-focused growth accelerator fund to help boost the WordPress small business community.

Results from Our First Round of Investments

In the first round (last year), I invested in 3 WordPress focused companies that represented 5 WordPress products including MemberPress, Pretty Links, Affiliate Royale, Formidable Forms, and SeedProd.

We worked closely with each founder to unlock tremendous growth in each businesses by optimizing the marketing strategy, improving internal processes, and even launching new products.

SeedProd launched a brand new product, RafflePress, which I can honestly say is the best WordPress giveaway plugin in the market.

MemberPress and Pretty Links saw tremendous growth in all areas including product, operations, and overall revenue. I’m really excited about the new product launches and features they’re going to be releasing (can’t share too much more).

Here’s a quote from Blair Williams, founder of MemberPress about his experience with the accelerator:

I’m so glad we joined the Growth Accelerator — it’s been awesome for our business! Not only have we had direct access to Syed but also the other companies in the Growth Accelerator & Awesome Motive. Having this type of ‘cross-pollination’ with these other companies and their seasoned owners in our industry has helped us take our business to the next level. We now have a clearer vision for the future, are operating much more efficiently, serving our customers better and seeing more success than ever before!

Formidable Forms has seen some amazing growth in both their product as well as business revenue. They released a brand new form building experience and a whole new website design. The new features they’re working on is very exciting because they’re continuing to push the limits of the advanced WordPress form experience.

We made a joint decision to not reveal revenue numbers or exact percentage growth since each company is privately held, but I can truly say that I’m very very happy with the growth.

Here’s a quote from Stephanie Wells, co-founder and lead developer of Formidable Forms:

Before joining up with Syed in the Accelerator program, I was burned out and in need of a change. We were growing slowly, but nothing I did seemed to make a difference. Within a month of working with Syed, we were gaining traction. For the first time, I was learning how to manage my team and company instead of just being the developer.

With an amazing, experienced advisor, I no longer feel like I’m paddling frantically in circles. When I lose focus or get distracted, our retreats and meetings get me back on course. The rest of the Awesome Motive and Accelerator companies have also proven to be an invaluable resource. I’m ridiculously lucky to get a piece of that endless resource of knowledge and experience.

I can proudly say that the last year has been huge success for all accelerator companies, and I’m really excited for our second bi-annual accelerator retreat coming up in two weeks where I get to spend time with these super smart and talented entrepreneurs whom I have an honor of calling my friends.

We’re going to close 2019 with a bang, and I’m really excited to see all the amazing new features and products that are in the pipeline for each accelerator company as well as my Awesome Motive portfolio companies.

Along with that, I’m also excited to open up the second round of the WPBeginner Growth Accelerator Fund for WordPress focused companies who’re looking to take their business to the next level.

How Does the Accelerator Work (Format and Philosophy)

One of the questions I get asked a lot is how does the Growth Accelerator work? The best way to answer that is by sharing our philosophy as well as the format we use.

Our Philosophy

We know that independence is one of the main reasons why people want to create a business in the first place, and it’s also one of the reasons why businesses succeed. Our goal is to interfere as little as possible with the day to day.

We believe that founders of WordPress-focused companies are great at hacking. We want to empower them with our framework and resources to do just that.

Most investors offer a combination of money and help. In our case, money is by far the smaller component. We want to share our experience, knowledge, and resources (collectively “needle-movers”) to help founders unlock extreme revenue growth.

We will offer a lot of advice, but we will never force anyone to take it.

The kind of advice that we will give literally can’t be bought because very few companies have the WordPress-specific insights like we do. And those that do are not in the business of consulting.

Format

Me along with other Awesome Motive partners will hand-pick a small group of WordPress companies to invest and work with. And no, we won’t ask you to move to the Bay Area or another big city.

If you have an existing WordPress focused business, then you can apply here.

We will review your application and invite the most promising companies to have a series of conversations with us. We will make our funding decision shortly after that.

Once funded, we will work closely with you to identify the growth levers in your business and help you implement the right processes to take your business to the next level.

Below are some of the benefits that you will have access to:

  • Our playbooks for product development, growth, and operations.
  • Office Hours with Awesome Motive Partners (including me)
  • Office Hours with Other Industry Experts
  • Bi-Annual Mastermind Meetings
  • Exposure on our media properties and access to our PR team
  • Private Founders Slack

How to Apply

If you already have a WordPress-focused business, then you can fill out the application below.

Important Note: this fund is for existing WordPress-focused businesses (i.e WordPress plugins, themes, and services) that have been around for at least six months.

Deadline: Applications will be closed on September 30th, 2019

All information you submit below are confidential. We are also open to signing a NDA if that helps – simply ask in the request below :)

(List as City, State, Country - for example: Miami, FL, USA)
(Pending lawsuits, co-founders who have left, etc.)

Final Thoughts

I am committed to the WordPress ecosystem, and I have two main goals with this fund:

  1. Help WordPress-focused companies succeed
  2. Help introduce more user-focused WordPress products

If you like a specific WordPress products that you think we should invest in, then please reach out to them and let them know about the growth accelerator fund.

Yours Truly,
Syed Balkhi
Founder of WPBeginner

The post Announcing WPBeginner Growth Accelerator Fund (Round 2) appeared first on WPBeginner.

Creating a Maintainable Icon System with Sass

One of my favorite ways of adding icons to a site is by including them as data URL background images to pseudo-elements (e.g. ::after) in my CSS. This technique offers several advantages:

  • They don't require any additional HTTP requests other than the CSS file.
  • Using the background-size property, you can set your pseudo-element to any size you need without worrying that they will overflow the boundaries (or get chopped off).
  • They are ignored by screen readers (at least in my tests using VoiceOver on the Mac) so which is good for decorative-only icons.

But there are some drawbacks to this technique as well:

  • When used as a background-image data URL, you lose the ability to change the SVG's colors using the "fill" or "stroke" CSS properties (same as if you used the filename reference, e.g. url( 'some-icon-file.svg' )). We can use filter() as an alternative, but that might not always be a feasible solution.
  • SVG markup can look big and ugly when used as data URLs, making them difficult to maintain when you need to use the icons in multiple locations and/or have to change them.

We're going to address both of these drawbacks in this article.

The situation

Let's build a site that uses a robust iconography system, and let's say that it has several different button icons which all indicate different actions:

  • A "download" icon for downloadable content
  • An "external link" icon for buttons that take us to another website
  • A "right caret" icon for taking us to the next step in a process

Right off the bat, that gives us three icons. And while that may not seem like much, already I'm getting nervous about how maintainable this is going to be when we scale it out to more icons like social media networks and the like. For the sake of this article, we're going to stop at these three, but you can imagine how in a sophisticated icon system this could get very unwieldy, very quickly.

It's time to go to the code. First, we'll set up a basic button, and then by using a BEM naming convention, we'll assign the proper icon to its corresponding button. (At this point, it's fair to warn you that we'll be writing everything out in Sass, or more specifically, SCSS. And for the sake of argument, assume I'm running Autoprefixer to deal with things like the appearance property.)

.button {
  appearance: none;
  background: #d95a2b;
  border: 0;
  border-radius: 100em;
  color: #fff;
  cursor: pointer;
  display: inline-block;
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
  padding: 1em calc( 1.5em + 32px ) 0.9em 1.5em;
  position: relative;
  text-align: center;
  text-transform: uppercase;
  transition: background-color 200ms ease-in-out;

  &:hover,
  &:focus,
  &:active {
    background: #8c3c2a;
  }
}

This gives us a simple, attractive, orange button that turns to a darker orange on the hover, focused, and active states. It even gives us a little room for the icons we want to add, so let's add them in now using pseudo-elements:

.button {

  /* everything from before, plus... */

  &::after {
    background: center / 24px 24px no-repeat; // Shorthand for: background-position, background-size, background-repeat
    border-radius: 100em;
    bottom: 0;
    content: '';
    position: absolute;
    right: 0;
    top: 0;
    width: 48px;
  }

  &--download {

    &::after {
      background-image: url( 'data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="30.544" height="25.294" viewBox="0 0 30.544 25.294"><g transform="translate(-991.366 -1287.5)"><path d="M1454.5,1298.922l6.881,6.881-6.881,6.881" transform="translate(2312.404 -157.556) rotate(90)" fill="none" stroke="%23fff" stroke-width="3"/><path d="M8853.866,5633.57v9.724h27.544v-9.724" transform="translate(-7861 -4332)" fill="none" stroke="%23fff" stroke-linejoin="round" stroke-width="3"/><line y2="14" transform="translate(1006.5 1287.5)" fill="none" stroke="%23fff" stroke-width="3"/></g></svg>' );
      }
    }

  &--external {

    &::after {
      background-image: url( 'data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="31.408" height="33.919" viewBox="0 0 31.408 33.919"><g transform="translate(-1008.919 -965.628)"><g transform="translate(1046.174 2398.574) rotate(-135)"><path d="M0,0,7.879,7.879,0,15.759" transform="translate(1025.259 990.17) rotate(90)" fill="none" stroke="%23fff" stroke-width="3"/><line y2="16.032" transform="translate(1017.516 980.5)" fill="none" stroke="%23fff" stroke-width="3"/></g><path d="M10683.643,5322.808v10.24h-20.386v-21.215h7.446" transform="translate(-9652.838 -4335)" fill="none" stroke="%23fff" stroke-width="3"/></g></svg>' );
    }
  }

  &--caret-right {

    &::after {
      background-image: url( 'data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.129 34.016"><path d="M1454.5,1298.922l15.947,15.947-15.947,15.947" transform="translate(-1453.439 -1297.861)" fill="none" stroke="%23fff" stroke-width="3"/></svg>' );
    }
  }
}

Let's pause here. While we're keeping our SCSS as tidy as possible by declaring the properties common to all buttons, and then only specifying the background SVGs on a per-class basis, it's already starting to look a bit unwieldy. That's that second downside to SVGs I mentioned before: having to use big, ugly markup in our CSS code.

Also, note how we're defining our fill and stroke colors inside the SVGs. At some point, browsers decided that the octothorpe ("#") that we all know and love in our hex colors was a security risk, and declared that they would no longer support data URLs that contained them. This leaves us with three options:

  1. Convert our data URLs from markup (like we have here) to base-64 encoded strings, but that makes them even less maintainable than before by completely obfuscating them; or
  2. Use rgba() or hsla() notation, not always intuitive as many developers have been using hex for years; or
  3. Convert our octothorpes to their URL-encoded equivalents, "%23".

We're going to go with option number three, and work around that browser limitation. (I will mention here, however, that this technique will work with rgb(), hsla(), or any other valid color format, even CSS named colors. But please don't use CSS named colors in production code.)

Moving to maps

At this point, we only have three buttons fully declared. But I don't like them just dumped in the code like this. If we needed to use those same icons elsewhere, we'd have to copy and paste the SVG markup, or else we could assign them to variables (either Sass or CSS custom properties), and reuse them that way. But I'm going to go for what's behind door number three, and switch to using one of Sass' greatest features: maps.

If you're not familiar with Sass maps, they are, in essence, the Sass version of an associative array. Instead of a numerically-indexed array of items, we can assign a name (a key, if you will) so that we can retrieve them by something logical and easily remembered. So let's build a Sass map of our three icons:

$icons: (
  'download':    '<svg xmlns="http://www.w3.org/2000/svg" width="30.544" height="25.294" viewBox="0 0 30.544 25.294"><g transform="translate(-991.366 -1287.5)"><path d="M1454.5,1298.922l6.881,6.881-6.881,6.881" transform="translate(2312.404 -157.556) rotate(90)" fill="none" stroke="%23fff" stroke-width="3"/><path d="M8853.866,5633.57v9.724h27.544v-9.724" transform="translate(-7861 -4332)" fill="none" stroke="%23fff" stroke-linejoin="round" stroke-width="3"/><line y2="14" transform="translate(1006.5 1287.5)" fill="none" stroke="%23fff" stroke-width="3"/></g></svg>',
  'external':    '<svg xmlns="http://www.w3.org/2000/svg" width="31.408" height="33.919" viewBox="0 0 31.408 33.919"><g transform="translate(-1008.919 -965.628)"><g transform="translate(1046.174 2398.574) rotate(-135)"><path d="M0,0,7.879,7.879,0,15.759" transform="translate(1025.259 990.17) rotate(90)" fill="none" stroke="%23fff" stroke-width="3"/><line y2="16.032" transform="translate(1017.516 980.5)" fill="none" stroke="%23fff" stroke-width="3"/></g><path d="M10683.643,5322.808v10.24h-20.386v-21.215h7.446" transform="translate(-9652.838 -4335)" fill="none" stroke="%23fff" stroke-width="3"/></g></svg>',
  'caret-right': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.129 34.016"><path d="M1454.5,1298.922l15.947,15.947-15.947,15.947" transform="translate(-1453.439 -1297.861)" fill="none" stroke="%23fff" stroke-width="3"/></svg>',
);

There are two things to note here: We didn't include the data:image/svg+xml;utf-8, string in any of those icons, only the SVG markup itself. That string is going to be the same every single time we need to use these icons, so why repeat ourselves and run the risk of making a mistake? Let's instead define it as its own string and prepend it to the icon markup when needed:

$data-svg-prefix: 'data:image/svg+xml;utf-8,';

The other thing to note is that we aren't actually making our SVG any prettier; there's no way to do that. What we are doing is pulling all that ugliness out of the code we're working on a day-to-day basis so we don't have to look at all that visual clutter as much. Heck, we could even put it in its own partial that we only have to touch when we need to add more icons. Out of sight, out of mind!

So now, let's use our map. Going back to our button code, we can now replace those icon literals with pulling them from the icon map instead:

&--download {

  &::after {
    background-image: url( $data-svg-prefix + map-get( $icons, 'download' ) );
  }
}

&--external {

  &::after {
    background-image: url( $data-svg-prefix + map-get( $icons, 'external' ) );
  }
}

&--next {

  &::after {
    background-image: url( $data-svg-prefix + map-get( $icons, 'caret-right' ) );
  }
}

Already, that's looking much better. We've started abstracting out our icons in a way that keeps our code readable and maintainable. And if that were the only challenge, we'd be done. But in the real-world project that inspired this article, we had another wrinkle: different colors.

Our buttons are a solid color which turn to a darker version of that color on their hover state. But what if we want "ghost" buttons instead, that turn into solid colors on hover? In this case, white icons would be invisible for buttons that appear on white backgrounds (and probably look wrong on non-white backgrounds). What we're going to need are two variations of each icon: the white one for the hover state, and one that matches button's border and text color for the non-hover state.

Let's update our button's base CSS to turn it in from a solid button to a ghost button that turns solid on hover. And we'll need to adjust the pseudo-elements for our icons, too, so we can swap them out on hover as well.

.button {
  appearance: none;
  background: none;
  border: 3px solid #d95a2b;
  border-radius: 100em;
  color: #d95a2b;
  cursor: pointer;
  display: inline-block;
  font-size: 18px;
  font-weight: bold;
  line-height: 1;
  padding: 1em calc( 1.5em + 32px ) 0.9em 1.5em;
  position: relative;
  text-align: center;
  text-transform: uppercase;
  transition: 200ms ease-in-out;
  transition-property: background-color, color;

  &:hover,
  &:focus,
  &:active {
    background: #d95a2b;
    color: #fff;
  }
}

Now we need to create our different-colored icons. One possible solution is to add the color variations directly to our map... somehow. We can either add new different-colored icons as additional items in our one-dimensional map, or make our map two-dimensional.

One-Dimensional Map:

$icons: (
  'download-white':  '<svg xmlns="http://www.w3.org/2000/svg" width="30.544" height="25.294" viewBox="0 0 30.544 25.294"><g transform="translate(-991.366 -1287.5)"><path d="M1454.5,1298.922l6.881,6.881-6.881,6.881" transform="translate(2312.404 -157.556) rotate(90)" fill="none" stroke="%23fff" stroke-width="3"/><path d="M8853.866,5633.57v9.724h27.544v-9.724" transform="translate(-7861 -4332)" fill="none" stroke="%23fff" stroke-linejoin="round" stroke-width="3"/><line y2="14" transform="translate(1006.5 1287.5)" fill="none" stroke="%23fff" stroke-width="3"/></g></svg>',
  'download-orange': '<svg xmlns="http://www.w3.org/2000/svg" width="30.544" height="25.294" viewBox="0 0 30.544 25.294"><g transform="translate(-991.366 -1287.5)"><path d="M1454.5,1298.922l6.881,6.881-6.881,6.881" transform="translate(2312.404 -157.556) rotate(90)" fill="none" stroke="%23d95a2b" stroke-width="3"/><path d="M8853.866,5633.57v9.724h27.544v-9.724" transform="translate(-7861 -4332)" fill="none" stroke="%23d95a2b" stroke-linejoin="round" stroke-width="3"/><line y2="14" transform="translate(1006.5 1287.5)" fill="none" stroke="%23d95a2b" stroke-width="3"/></g></svg>',
);

Two-Dimensional Map:

$icons: (
  'download': (
    'white':  '<svg xmlns="http://www.w3.org/2000/svg" width="30.544" height="25.294" viewBox="0 0 30.544 25.294"><g transform="translate(-991.366 -1287.5)"><path d="M1454.5,1298.922l6.881,6.881-6.881,6.881" transform="translate(2312.404 -157.556) rotate(90)" fill="none" stroke="%23fff" stroke-width="3"/><path d="M8853.866,5633.57v9.724h27.544v-9.724" transform="translate(-7861 -4332)" fill="none" stroke="%23fff" stroke-linejoin="round" stroke-width="3"/><line y2="14" transform="translate(1006.5 1287.5)" fill="none" stroke="%23fff" stroke-width="3"/></g></svg>',
    'orange': '<svg xmlns="http://www.w3.org/2000/svg" width="30.544" height="25.294" viewBox="0 0 30.544 25.294"><g transform="translate(-991.366 -1287.5)"><path d="M1454.5,1298.922l6.881,6.881-6.881,6.881" transform="translate(2312.404 -157.556) rotate(90)" fill="none" stroke="%23d95a2b" stroke-width="3"/><path d="M8853.866,5633.57v9.724h27.544v-9.724" transform="translate(-7861 -4332)" fill="none" stroke="%23d95a2b" stroke-linejoin="round" stroke-width="3"/><line y2="14" transform="translate(1006.5 1287.5)" fill="none" stroke="%23d95a2b" stroke-width="3"/></g></svg>',
  ),
);

Either way, this is problematic. By just adding one additional color, we're going to double our maintenance efforts. Need to change the existing download icon with a different one? We need to manually create each color variation to add it to the map. Need a third color? Now you've just tripled your maintenance costs. I'm not even going to get into the code to retrieve values from a multi-dimensional Sass map because that's not going to serve our ultimate goal here. Instead, we're just going to move on.

Enter string replacement

Aside from maps, the utility of Sass in this article comes from how we can use it to make CSS behave more like a programming language. Sass has built-in functions (like map-get(), which we've already seen), and it allows us to write our own.

Sass also has a bunch of string functions built-in, but inexplicably, a string replacement function isn't one of them. That's too bad, as its usefulness is obvious. But all is not lost.

Hugo Giradel gave us a Sass version of str-replace() here on CSS-Tricks in 2014. We can use that here to create one version of our icons in our Sass map, using a placeholder for our color values. Let's add that function to our own code:

@function str-replace( $string, $search, $replace: '' ) {

  $index: str-index( $string, $search );

  @if $index {
    @return str-slice( $string, 1, $index - 1 ) + $replace + str-replace( str-slice( $string, $index + str-length( $search ) ), $search, $replace);
  }

  @return $string;
}

Next, we'll update our original Sass icon map (the one with only the white versions of our icons) to replace the white with a placeholder (%%COLOR%%) that we can swap out with whatever color we call for, on demand.

$icons: (
  'download':    '<svg xmlns="http://www.w3.org/2000/svg" width="30.544" height="25.294" viewBox="0 0 30.544 25.294"><g transform="translate(-991.366 -1287.5)"><path d="M1454.5,1298.922l6.881,6.881-6.881,6.881" transform="translate(2312.404 -157.556) rotate(90)" fill="none" stroke="%%COLOR%%" stroke-width="3"/><path d="M8853.866,5633.57v9.724h27.544v-9.724" transform="translate(-7861 -4332)" fill="none" stroke="%%COLOR%%" stroke-linejoin="round" stroke-width="3"/><line y2="14" transform="translate(1006.5 1287.5)" fill="none" stroke="%%COLOR%%" stroke-width="3"/></g></svg>',
  'external':    '<svg xmlns="http://www.w3.org/2000/svg" width="31.408" height="33.919" viewBox="0 0 31.408 33.919"><g transform="translate(-1008.919 -965.628)"><g transform="translate(1046.174 2398.574) rotate(-135)"><path d="M0,0,7.879,7.879,0,15.759" transform="translate(1025.259 990.17) rotate(90)" fill="none" stroke="%%COLOR%%" stroke-width="3"/><line y2="16.032" transform="translate(1017.516 980.5)" fill="none" stroke="%%COLOR%%" stroke-width="3"/></g><path d="M10683.643,5322.808v10.24h-20.386v-21.215h7.446" transform="translate(-9652.838 -4335)" fill="none" stroke="%%COLOR%%" stroke-width="3"/></g></svg>',
  'caret-right': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.129 34.016"><path d="M1454.5,1298.922l15.947,15.947-15.947,15.947" transform="translate(-1453.439 -1297.861)" fill="none" stroke="%%COLOR%%" stroke-width="3"/></svg>',
);

But if we were going to try and fetch these icons using just our new str-replace() function and Sass' built-in map-get() function, we'd end with something big and ugly. I'd rather tie these two together with one more function that makes calling the icon we want in the color we want as simple as one function with two parameters (and because I'm particularly lazy, we'll even make the color default to white, so we can omit that parameter if that's the color icon we want).

Because we're getting an icon, it's a "getter" function, and so we'll call it get-icon():

@function get-icon( $icon, $color: #fff ) {

  $icon:        map-get( $icons, $icon );
  $placeholder: '%%COLOR%%';

  $data-uri: str-replace( url( $data-svg-prefix + $icon ), $placeholder, $color );

  @return str-replace( $data-uri, '#', '%23' );
}

Remember where we said that browsers won't render data URLs that have octothorpes in them? Yeah, we're str-replace()ing that too so we don't have to remember to pass along "%23" in our color hex codes.

Side note: I have a Sass function for abstracting colors too, but since that's outside the scope of this article, I'll refer you to my get-color() gist to peruse at your leisure.

The result

Now that we have our get-icon() function, let's put it to use. Going back to our button code, we can replace our map-get() function with our new icon getter:

&--download {

  &::before {
    background-image: get-icon( 'download', #d95a2b );
  }

  &::after {
    background-image: get-icon( 'download', #fff ); // The ", #fff" isn't strictly necessary, because white is already our default
  }
}

&--external {

  &::before {
    background-image: get-icon( 'external', #d95a2b );
  }

  &::after {
    background-image: get-icon( 'external' );
  }
}

&--next {

  &::before {
    background-image: get-icon( 'arrow-right', #d95a2b );
  }

  &::after {
    background-image: get-icon( 'arrow-right' );
  }
}

So much easier, isn't it? Now we can call any icon we've defined, with any color we need. All with simple, clean, logical code.

  • We only ever have to declare an SVG in one place.
  • We have a function that gets that icon in whatever color we give it.
  • Everything is abstracted out to a logical function that does exactly what it looks like it will do: get X icon in Y color.

Making it fool-proof

The one thing we're lacking is error-checking. I'm a huge believer in failing silently... or at the very least, failing in a way that is invisible to the user yet clearly tells the developer what is wrong and how to fix it. (For that reason, I should be using unit tests way more than I do, but that's a topic for another day.)

One way we have already reduced our function's propensity for errors is by setting a default color (in this case, white). So if the developer using get-icon() forgets to add a color, no worries; the icon will be white, and if that's not what the developer wanted, it's obvious and easily fixed.

But wait, what if that second parameter isn't a color? As if, the developer entered a color incorrectly, so that it was no longer being recognized as a color by the Sass processor?

Fortunately we can check for what type of value the $color variable is:

@function get-icon( $icon, $color: #fff ) {

  @if 'color' != type-of( $color ) {

    @warn 'The requested color - "' + $color + '" - was not recognized as a Sass color value.';
    @return null;
  }

  $icon:        map-get( $icons, $icon );
  $placeholder: '%%COLOR%%';
  $data-uri:    str-replace( url( $data-svg-prefix + $icon ), $placeholder, $color );

  @return str-replace( $data-uri, '#', '%23' );
}

Now if we tried to enter a nonsensical color value:

&--download {

  &::before {
    background-image: get-icon( 'download', ce-nest-pas-un-couleur );
  }
}

...we get output explaining our error:

Line 25 CSS: The requested color - "ce-nest-pas-un-couleur" - was not recognized as a Sass color value.

...and the processing stops.

But what if the developer doesn't declare the icon? Or, more likely, declares an icon that doesn't exist in the Sass map? Serving a default icon doesn't really make sense in this scenario, which is why the icon is a mandatory parameter in the first place. But just to make sure we are calling an icon, and it is valid, we're going to add another check:

@function get-icon( $icon, $color: #fff ) {

  @if 'color' != type-of( $color ) {

    @warn 'The requested color - "' + $color + '" - was not recognized as a Sass color value.';
    @return null;
  }

  @if map-has-key( $icons, $icon ) {

    $icon:        map-get( $icons, $icon );
    $placeholder: '%%COLOR%%';
    $data-uri:    str-replace( url( $data-svg-prefix + $icon ), $placeholder, $color );

    @return str-replace( $data-uri, '#', '%23' );
  }

  @warn 'The requested icon - "' + $icon + '" - is not defined in the $icons map.';
  @return null;
}

We've wrapped the meat of the function inside an @if statement that checks if the map has the key provided. If so (which is the situation we're hoping for), the processed data URL is returned. The function stops right then and there — at the @return — which is why we don't need an @else statement.

But if our icon isn't found, then null is returned, along with a @warning in the console output identifying the problem request, plus the partial filename and line number. Now we know exactly what's wrong, and when and what needs fixing.

So if we were to accidentally enter:

&--download {

  &::before {
    background-image: get-icon( 'ce-nest-pas-une-icône', #d95a2b );
  }
}

...we would see the output in our console, where our Sass process was watching and running:

Line 32 CSS: The requested icon - "ce-nest-pas-une-icône" - is not defined in the $icons map.

As for the button itself, the area where the icon would be will be blank. Not as good as having our desired icon there, but soooo much better than a broken image graphic or some such.

Conclusion

After all of that, let's take a look at our final, processed CSS:

.button {
  -webkit-appearance: none;
      -moz-appearance: none;
          appearance: none;
  background: none;
  border: 3px solid #d95a2b;
  border-radius: 100em;
  color: #d95a2b;
  cursor: pointer;
  display: inline-block;
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
  padding: 1em calc( 1.5em + 32px ) 0.9em 1.5em;
  position: relative;
  text-align: center;
  text-transform: uppercase;
  transition: 200ms ease-in-out;
  transition-property: background-color, color;
}
.button:hover, .button:active, .button:focus {
  background: #d95a2b;
  color: #fff;
}
.button::before, .button::after {
  background: center / 24px 24px no-repeat;
  border-radius: 100em;
  bottom: 0;
  content: '';
  position: absolute;
  right: 0;
  top: 0;
  width: 48px;
}
.button::after {
  opacity: 0;
  transition: opacity 200ms ease-in-out;
}
.button:hover::after, .button:focus::after, .button:active::after {
  opacity: 1;
}
.button--download::before {
  background-image: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="30.544" height="25.294" viewBox="0 0 30.544 25.294"><g transform="translate(-991.366 -1287.5)"><path d="M1454.5,1298.922l6.881,6.881-6.881,6.881" transform="translate(2312.404 -157.556) rotate(90)" fill="none" stroke="%23d95a2b" stroke-width="3"/><path d="M8853.866,5633.57v9.724h27.544v-9.724" transform="translate(-7861 -4332)" fill="none" stroke="%23d95a2b" stroke-linejoin="round" stroke-width="3"/><line y2="14" transform="translate(1006.5 1287.5)" fill="none" stroke="%23d95a2b" stroke-width="3"/></g></svg>');
}
.button--download::after {
  background-image: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="30.544" height="25.294" viewBox="0 0 30.544 25.294"><g transform="translate(-991.366 -1287.5)"><path d="M1454.5,1298.922l6.881,6.881-6.881,6.881" transform="translate(2312.404 -157.556) rotate(90)" fill="none" stroke="%23fff" stroke-width="3"/><path d="M8853.866,5633.57v9.724h27.544v-9.724" transform="translate(-7861 -4332)" fill="none" stroke="%23fff" stroke-linejoin="round" stroke-width="3"/><line y2="14" transform="translate(1006.5 1287.5)" fill="none" stroke="%23fff" stroke-width="3"/></g></svg>');
}
.button--external::before {
  background-image: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="31.408" height="33.919" viewBox="0 0 31.408 33.919"><g transform="translate(-1008.919 -965.628)"><g transform="translate(1046.174 2398.574) rotate(-135)"><path d="M0,0,7.879,7.879,0,15.759" transform="translate(1025.259 990.17) rotate(90)" fill="none" stroke="%23d95a2b" stroke-width="3"/><line y2="16.032" transform="translate(1017.516 980.5)" fill="none" stroke="%23d95a2b" stroke-width="3"/></g><path d="M10683.643,5322.808v10.24h-20.386v-21.215h7.446" transform="translate(-9652.838 -4335)" fill="none" stroke="%23d95a2b" stroke-width="3"/></g></svg>');
}
.button--external::after {
  background-image: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="31.408" height="33.919" viewBox="0 0 31.408 33.919"><g transform="translate(-1008.919 -965.628)"><g transform="translate(1046.174 2398.574) rotate(-135)"><path d="M0,0,7.879,7.879,0,15.759" transform="translate(1025.259 990.17) rotate(90)" fill="none" stroke="%23fff" stroke-width="3"/><line y2="16.032" transform="translate(1017.516 980.5)" fill="none" stroke="%23fff" stroke-width="3"/></g><path d="M10683.643,5322.808v10.24h-20.386v-21.215h7.446" transform="translate(-9652.838 -4335)" fill="none" stroke="%23fff" stroke-width="3"/></g></svg>');
}
.button--next::before {
  background-image: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.129 34.016"><path d="M1454.5,1298.922l15.947,15.947-15.947,15.947" transform="translate(-1453.439 -1297.861)" fill="none" stroke="%23d95a2b" stroke-width="3"/></svg>');
}
.button--next::after {
  background-image: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.129 34.016"><path d="M1454.5,1298.922l15.947,15.947-15.947,15.947" transform="translate(-1453.439 -1297.861)" fill="none" stroke="%23fff" stroke-width="3"/></svg>');
}

Yikes, still ugly, but it's ugliness that becomes the browser's problem, not ours.

I've put all this together in CodePen for you to fork and experiment. The long goal for this mini-project is to create a PostCSS plugin to do all of this. This would increase the availability of this technique to everyone regardless of whether they were using a CSS preprocessor or not, or which preprocessor they're using.

"If I have seen further it is by standing on the shoulders of Giants."
– Isaac Newton, 1675

Of course we can't talk about Sass and string replacement and (especially) SVGs without gratefully acknowledging the contributions of the others who've inspired this technique.

The post Creating a Maintainable Icon System with Sass appeared first on CSS-Tricks.

Can you rotate the cursor in CSS?

Kinda! There is no simple or standard way to do it, but it's possible. You can change the cursor to different built-in native versions with CSS with the cursor property, but that doesn't help much here. You can also use that property to set a static image as the cursor. But again that doesn't help much because you can't rotate it once it's there.

The trick is to totally hide the cursor with cursor: none; and replace it with your own element.

Here's an example of that:

See the Pen
Move fake mouse with JavaScript
by Chris Coyier (@chriscoyier)
on CodePen.

That's not rotating yet. But now that the cursor is just some element on the page, CSS's transform: rotate(); is fully capable of that job. Some math is required.

I'll leave that to Aaron Iker's really fun demo:

See the Pen
Mouse cursor pointing to cta
by Aaron Iker (@aaroniker)
on CodePen.

Is this an accessibility problem? Something about it makes me think it might be. It's a little extra motion where you aren't expecting it and perhaps a little disorienting when an element you might rely on for a form of stability starts moving on you. It's really only something you'd do for limited-use novelty and while respecting the prefers-reduced-motion. You could also keep the original cursor and do something under it, as Jackson Callaway has done here.

The post Can you rotate the cursor in CSS? appeared first on CSS-Tricks.

How to Win your Customer Heart with a Spellbinding Brand Personality

Ever wondered what makes a brand popular and aesthetic? You must have come across brands that are loved by their customers. You can also become one of them if you’re successfully able to develop an identity of your brand that your target audience will adore. The question is how you can create your own brand [...]

The post How to Win your Customer Heart with a Spellbinding Brand Personality appeared first on WPArena.

22 Hot Summer Fonts

In this blazing hot summer, it’s the best time to stock up on fonts that perfectly match the sunny weather. Designs you create using these typefaces can encapsulate that lively summer feeling and get people ready to have some fun in the sun. Use them in your marketing campaigns, on your seasonal website redesign, or in beautiful inspirational posters!

If you want to remind people of summer, the sun, and the sea, try out one of these 22 warm fonts we’ve collected just for you. Fun, elegant, or creative, there’s a typeface here for your project.

UNLIMITED DOWNLOADS: 400,000+ Fonts & Design Assets




Summer of 76 by Darumo Shop

Example of Summer of 76 by Darumo Shop

Sailor Stripes by On the Mark Designs

Example of Sailor Stripes by On the Mark Designs

Cassandra Personal Use by Billy Argel

Example of Cassandra Personal Use by Billy Argel

Sea Legs by Britt Fabello

Example of Sea Legs by Britt Fabello

Summer Palms Font Collection by Mel Volkman

Example of Summer Palms Font Collection by Mel Volkman

Mermaid Tails by Kitaleigh

Example of Mermaid Tails by Kitaleigh

Fire Font by Art Loft

Example of Fire Font by Art Loft

Salazar by Konstantine Studio

Example of Salazar by Konstantine Studio

Beach Please by Rsz Type Foundry

Example of Beach Please by Rsz Type Foundry

Forever Summer by Flycatcher Design

Example of Forever Summer by Flycatcher Design

Rome by Jen Wagner Co

Example of Rome by Jen Wagner Co

Lemon Jelly Personal Use by Billy Argel

Example of Lemon Jelly Personal Use by Billy Argel

Rainforest by Typodermic

Example of Rainforest by Typodermic

Hunter by New Tropical Design

Example of Hunter by New Tropical Design

Forbidden Isle by Spring Break Jake

Example of Forbidden Isle by Spring Break Jake

Havana Sunset Font Duo by Sam Parrett

Example of Havana Sunset Font Duo by Sam Parrett

Swung Note by PintassilgoPrints

Example of Swung Note by PintassilgoPrints

Aquarius – A Tropical Font Family by IconsByKassy

Example of Aquarius – A Tropical Font Family by IconsByKassy

Sveglia by Wacaksara co

Example of Sveglia by Wacaksara co

Laguna Beach Font Duo by Jen Wagner Co

Example of Laguna Beach Font Duo by by Jen Wagner Co

Bashira Brush Script by Maulana Creative

Example of Bashira Brush Script by Maulana Creative

Summer Lemonade by Hart Foundry

Example of Summer Lemonade by Hart Foundry

Try a Vibrant Summer Font

Nothing says summer like a colorful, lively font. All of these fonts embrace the brightness and energy of summer with their unique designs, flowy cursives, and light-hearted feel.

Some are casual and decorated with a cartoony look, while others are clean and professional. But all of them are eye-catchingly beautiful and perfect for any summer project. Try some for yourself; you’ll love the spark these fonts can instantly bring into your design.