> All in One 586

Ads

Wednesday, April 1, 2020

‘A perfect storm for first time managers,’ say VCs with their own shops

Until very recently, it had begun to seem like anyone with a thick enough checkbook and some key contacts in the startup world could not only fund companies as an angel investor but even put himself or herself in business as a fund manager.

It helped that the world of venture fundamentally changed and opened up as information about its inner workings flowed more freely. It didn’t hurt, either, that many billions of dollars poured into Silicon Valley from outfits and individuals around the globe who sought out stakes in fast-growing, privately held companies — and who needed help in securing those positions.

Of course, it’s never really been as easy or straightforward as it looks from the outside. While the last decade has seen many new fund managers pick up traction, much of the capital flooding into the industry has accrued to a small number of more established players that have grown exponentially in terms of assets under management. In fact, talk with anyone who has raised a first-time fund and you’re likely to hear that the fundraising process is neither glamorous nor lucrative and that it’s paved with very short phone conversations. And that’s in a bull market.

What happens in what’s suddenly among the worst economic environments the world has seen? First and foremost, managers who’ve struck out on their own suggest putting any plans on the back burner. “I would love to be positive, and I’m an optimist, but I would have to say that now is probably one of the toughest times” to get a fund off the ground, says Aydin Senkut, who founded the firm Felicis Ventures in 2006 and just closed its seventh fund.

“It’s a perfect storm for first-time managers,” adds Charles Hudson, who launched his own venture shop, Precursor Ventures, in 2015.

Hitting pause doesn’t mean giving up, suggests Eva Ho, cofounder of the three-year-old, seed-stage L.A.-based outfit Fika Ventures, which last year closed its second fund with $76 million. She says not to get “too dismayed” by the challenges.

Still, it’s good to understand what a first-time manager is up against right now, and what can be learned more broadly about how to proceed when the time is right.

Know it’s hard, even in the best times

As a starting point, it’s good to recognize that it’s far harder to assemble a first fund than anyone who hasn’t done it might imagine.

Hudson knew he wanted to leave his last job as a general partner with SoftTech VC when the firm — since renamed Uncork Capital — amassed enough capital that it no longer made sense for it to issue very small checks to nascent startups. “I remember feeling like, Gosh, I’ve reached a point where the business model for our fund is getting in the way of me investing in the kind of companies that naturally speak to me,” which is largely pre-product startups.

Hudson suggests he miscalculated when it came to approaching investors with his initial idea to create a single GP fund that largely backs ideas that are too early for other VCs. “We had a pretty big LP based [at SoftTech] but what I didn’t realize is the LP base that’s interested in someone who is on fund three or four is very different than the LP base that’s interested in backing a brand new manager.”

Hudson says he spent a “bunch of time talking to fund of funds, university endowments — people who were just not right for me until someone pulled me aside and just said, ‘Hey, you’re talking to the wrong people. You need to find some family offices. You need to find some friends of Charles. You need to find people who are going to back you because they think this is a good idea and who aren’t quite so orthodox in terms of what they want to see in terms partner composition and all that.'”

Collectively, it took “300 to 400 LP conversations” and two years to close his first fund with $15 million. (Its now raising its third pre-seed fund).

Ho says it took less time for Fika to close its first fund but that she and her partners talked with 600 people in order to close their $41 million debut effort, adding that she felt like a “used car salesman” by the end of the process.

Part of the challenge was her network, she says. “I wasn’t connected to a lot of high-net-worth individuals or endowments or foundations. That was a whole network that was new to me, and they didn’t know who the heck I was, so there’s a lot of proving to do.” A proof-of-concept fund instilled confidence in some of these investors, though Ho notes you have to be able to live off its economics, which can be miserly.

She also says that as someone who’d worked at Google and helped found the location data company Factual, she underestimated the work involved in running a small fund. “I thought, ‘Well, I’ve started these companies and run these big teams. How how different could it be?” But “learning the motions and learning what it’s really like to run the funds and to administer a fund and all responsibilities and liabilities that come with it . . . it made me really stop and think, ‘Do I want to do this for 20 to 30 years, and if so, what’s the team I want to do it with?'”

Investors will offer you funky deals; avoid these if you can

In Hudson’s case, an LP offered him two options, either a typical LP agreement wherein the outfit would write a small check, or an option wherein it would make a “significant investment that have been 40% of our first fund,” says Hudson.

Unsurprisingly, the latter offer came with a lot of strings. Namely, the LP said it wanted to have a “deeper relationship” with Hudson, which he took to mean it wanted a share of Precursor’s profits beyond what it would receive as a typical investor in the fund.

“It was very hard to say no to that deal, because I didn’t get close to raising the amount of money that I would have gotten if I’d said yes for another year,” says Hudson. He still thinks it was the right move, however. “I was just like, how do I have a conversation with any other LP about this in the future if I’ve already made the decision to give this away?”

Fika similarly received an offer that would have made up 25 percent of the outfit’s debut fund, but the investor wanted a piece of the management company. It was “really hard to turn down because we had nothing else,” recalls Ho. But she says that other funds Fika was talking with made the decision simpler. “They were like, ‘If you sign on to those terms, we’re out.” The team decided that taking a shortcut that could damage them longer term wasn’t worth it.

Your LPs have questions, but you should question LPs, too

Senkut started off with certain financial advantages that many VCs do not, having been the first product manager at Google and enjoying the fruits of its IPO before leaving the outfit in 2005 along with many other Googleaires, as they were dubbed at the time.

Still, as he tells it, it was “not a friendly time a decade ago” with most solo general partners spinning out of other venture funds instead of search engine giants. In the end, it took him “50 no’s before I had my first yes” — not hundreds —   but it gave him a taste of being an outsider in an insider industry, and he seemingly hasn’t forgotten that feeling.

Indeed, according to Senkut, anyone who wants to crack into the venture industry needs to get into the flow of the best deals by hook or by crook. In his case, for example, he shadowed angel investor Ron Conway for some time, working checks into some of the same deals that Conway was backing.

“If you want to get into the movie industry, you need to be in hit movies,” says Senkut. “If you want to get into the investing industry, you need to be in hits. And the best way to get into hits is to say, ‘Okay. Who has an extraordinary number of hits, who’s likely getting the best deal flow, because the more successful you are, the better companies you’re going to see, the better the companies that find you.”

Adds Senkut, “The danger in this business is that it’s very easy to make a mistake. It’s very easy to chase deals that are not going to go anywhere. And so I think that’s where [following others] things really helped me.”

Senkut has developed an enviable track record over time. The companies that Felicis has backed and been acquired include Credit Karma, which was just gobbled up by Intuit; Plaid, sold in January to Visa; Ring, sold in 2018 to Amazon, and Cruise, sold to General Motors in 2016, and that’s saying nothing of its portfolio companies to go public.

That probably gives him a kind of confidence that it’s harder to earlier managers to muster. Still, Senkut also says it’s very important for anyone raising a fund to ask the right questions of potential investors, who will sometimes wittingly or unwittingly waste a manager’s time.

He says, for example, that with Felicis’s newest fund, the team asked many managers outright about how many assets they have under management, how much of those assets are dedicated to venture and private equity, and how much of their allotment to each was already taken. They did this so they don’t find themselves in a position of making a capital call that an investor can’t meet, especially given that venture backers have been writing out checks to new funds at a faster pace than they’ve ever been asked to before.

In fact, Felicis added new managers who “had room” while cutting back some existing LPs “that we respected . .. because if you ask the right questions, it becomes clear whether they’re already 20% over-allocated [to the asset class] and there’s no possible way [they are] even going to be able to invest if they want to.”

It’s a “little bit of an eight ball to figure out what are your odds and the probability of getting money even if things were to turn south,” he notes.

Given that they have, the questions look smarter still.



from Amazon – TechCrunch https://ift.tt/3aCVoJf
via IFTTT

Web Performance Checklist

The other day, I realized that web performance is an enormous topic covering so very much — from minimizing assets to using certain file formats, it can be an awful lot to keep in mind while building a website. It’s certainly far too much for me to remember!

So I made a web performance checklist. It’s a Notion doc that I can fork and use to mark completed items whenever I start a new project. It also contains a bunch of links for references.

This doc is still a work in progress. Any recommendations or links?Feel free to suggest something in the comments below!

The post Web Performance Checklist appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/343hW3j
via IFTTT

An Annotated Docker Config for Front-End Web Development

Andrew Welch sings the praises of using Docker containers for local dev environments:

Here are the advan­tages of Dock­er for me:

• Each appli­ca­tion has exact­ly the envi­ron­ment it needs to run, includ­ing spe­cif­ic ver­sions of any of the plumb­ing need­ed to get it to work (PHP, MySQL, Post­gres, whatever)
• Onboard­ing oth­ers becomes triv­ial, all they need to do is install Dock­er and type docker-compose up and away they go
• Your devel­op­ment envi­ron­ment is entire­ly dis­pos­able; if some­thing goes wrong, you just delete it and fire up a new one
• Your local com­put­er is sep­a­rate from your devel­op­ment envi­ron­ment, so switch­ing com­put­ers is triv­ial, and you won’t run into issues where you hose your com­put­er or are stuck with con­flict­ing ver­sions of DevOps services
• The cost of try­ing dif­fer­ent ver­sions of var­i­ous ser­vices is low; just change a num­ber in a .yaml file, docker-compose up, and away you go

Here’s an, uhm, very different perspective I’m anonymously posting that I snagged from a group Slack:

I have spent basically the whole day fucking around with Docker bullshit.

This has now cost the client literally thousands of dollars in me not getting any actual work done. The setup was created by the dev team, who are great, but the brittle, unstable nature of this is, well, bullshit.

I get the motivation but everyone knows that Docker is horribly slow on the Mac. It has for several years and yet it’s still in use. I just don’t get it.

Is there any way that developing with Docker on a Mac can not suck? Asking for a friend. Who is me.

Diff’rent Strokes.

Direct Link to ArticlePermalink

The post An Annotated Docker Config for Front-End Web Development appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2WCqP2d
via IFTTT

Cloudinary Studio

I knew that Cloudinary worked with video as well as images but, the other day, I was curious if Cloudinary offered a video player embed just like other video hosts do (e.g. YouTube, Vimeo, etc). Like an <iframe> that comes with a special player.

I was curious because, as much as I appreciate the simplicity of just tossing a <video> on a page, there is one little hurdle that I always forget: you have to use a poster attribute if you want anything but a blank white rectangle on mobile browsers. Having to cut a special poster for every video I use is a step I’m frankly just too lazy to do most of the time.

Turns out Cloudinary does a have a player, and it allows for a bunch of nice customization, including handling the poster for you: Video Player Studio.

If I use this player instead, not only do I get a free configurable poster, but other advantages you’d expect from Cloudinary, like serving the video in the best possible format and optimizing the size.

But there is another thing that is a kind of big deal here, particularly for long videos: “adaptive bitrate streaming.” Behind the scenes, some library probably needs to be downloaded, but the bandwidth savings likely pay for that almost instantly. I’m not an expert on any of this by any means, but I’m referring to HLS and MPEG-DASH, which seem to be the big players, and this Cloudinary player offers both.

For the record, this post is not sponsored by Cloudinary. I was just thinking about all this the other day because we frequently embed video here on CSS-Tricks and I already use Cloudinary for all sorts of stuff.

Here’s an example:

In running this past the Cloudinary team, they said two things:

  1. The player is built on top of VideoJS. Credit where credit is due.
  2. They’ve got a blog post that goes far deeper into customizing the player than I talk about here.

The post Cloudinary Studio appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/39BjaUT
via IFTTT

In a significant change, Apple customers can now buy or rent titles directly in the Prime Video app

Amazon has made it easier for Apple customers to buy or rent movies from its Prime Video app with a recent update. Before, customers using the Prime Video app from an iOS device or Apple TV would have to first purchase or rent the movie elsewhere — like through the Amazon website or a Prime Video app on another device, such as the Fire TV, Roku, or an Android device. Now, Prime Video users can make the purchase directly through the app instead.

The changes weren’t formally announced, but quickly spotted once live.

Amazon declined to comment, but confirmed to TechCrunch the feature is live now for customers in the U.S., U.K., and Germany.

The change makes it possible for Prime Video users to rent or buy hundreds of thousands of titles from Amazon’s video catalog. This includes new release movies, TV shows, classic movies, award-winning series, Oscar-nominated films, and more.

This is supported on a majority of Apple devices, including the iPhone, iPad, and iPod touch running iOS/iPadOS 12.2 or higher, as well as Apple TV HD and Apple TV 4K.

Amazon for years has prevented users from directly purchasing movies and TV shows from Prime Video app on Apple devices. That’s because Apple requires a 30% cut of all in-app purchases taking place on its platform. To avoid fees, many apps — including not only Amazon, but also Netflix, Tinder, Spotify, and others — have bypassed the major app platforms’ fees at times by redirecting users to a website.

Since the news broke, many have questioned if Amazon had some sort of deal with Apple that was making the change possible — especially since it didn’t raise the cost of rentals or subscriptions to cover a 30% cut.

As it turns out, it sort of does.

Apple tells TechCrunch it offers program aimed at supporting subscription video entertainment providers.

“Apple has an established program for premium subscription video entertainment providers to offer a variety of customer benefits — including integration with the Apple TV app, AirPlay 2 support, tvOS apps, universal search, Siri support and, where applicable, single or zero sign-on,” an Apple spokesperson said. “On qualifying premium video entertainment apps such as Prime Video, Altice One and Canal+, customers have the option to buy or rent movies and TV shows using the payment method tied to their existing video subscription,” the spokesperson noted.

It remains to be seen in Amazon will extend Apple the same courtesy on its Fire TV platform, by allowing Apple customers to rent or buy movies directly in the Apple TV app there.

Amazon’s adoption of this program is notable, as it comes at a time when Apple is under increased scrutiny for alleged anti-competitive behaviors — particularly those against companies with a rival product or service — like Prime Video is to Apple TV+, or Fire TV is to Apple TV, for example.

Amazon called attention to the new feature in its Prime Video app, which now alerts you upon first launch that “Movie night just got better” in a full-screen pop-up. It also advertises the easier option for direct purchases through a home screen banner.



from Amazon – TechCrunch https://ift.tt/2R3Z9Qf
via IFTTT

Performant Expandable Animations: Building Keyframes on the Fly

Animations have come a long way, continuously providing developers with better tools. CSS Animations, in particular, have defined the ground floor to solve the majority of uses cases. However, there are some animations that require a little bit more work.

You probably know that animations should run on the composite layer. (I won’t extend myself here, but if you want to know more, check this article.) That means animating transform or opacity properties that don’t trigger layout or paint layers. Animating properties like height and width is a big no-no, as they trigger those layers, which force the browser to recalculate styles.

On top of that, even when animating transform properties, if you want to truly hit 60 FPS animations, you probably should get a little help from JavaScript, using the FLIP technique for extra smoother animations! 

However, the problem of using transform for expandable animations is that the scale function isn’t exactly the same as animating width/height properties. It creates a skewed effect on the content, as all elements get stretched (when scaling up) or squeezed (when scaling down).

So, because of that, my go-to solution has been (and probably still is, for reasons I will detail later), technique #3 from Brandon Smith’s article. This still has a transition on height, but uses Javascript to calculate the content size, and force a transition using requestAnimationFrame. At OutSystems, we actually used this to build the animation for the OutSystems UI Accordion Pattern.

Generating keyframes with JavaScript

Recently, I stumbled on another great article from Paul Lewis, that details a new solution for expanding and collapsing animations, which motivated me to write this article and spread this technique around.

Using his words, the main idea consists of generating dynamic keyframes, stepping…

[…] from 0 to 100 and calculate what scale values would be needed for the element and its contents. These can then be boiled down to a string, which can be injected into the page as a style element. 

To achieve this, there are three main steps.

Step 1: Calculate the start and end states

We need to calculate the correct scale value for both states. That means we use getBoundingClientRect() on the element that will serve as a proxy for the start state, and divide it with the value from the end state. It should be something like this:

function calculateStartScale () {
  const start= startElement.getBoundingClientRect();
  const end= endElement.getBoundingClientRect();
  return {
    x: start.width / end.width,
    y: start.height / end.height
  };
}

Step 2: Generate the Keyframes

Now, we need to run a for loop, using the number of frames needed as the length. (It shouldn’t really be less than 60 to ensure a smooth animation.) Then, in each iteration, we calculate the correct easing value, using an ease function:

function ease (v, pow=4) {
  return 1 - Math.pow(1 - v, pow);
}

let easedStep = ease(i / frame);

With that value, we’ll get the scale of the element on the current step, using the following math:

const xScale = x + (1 - x) * easedStep;
const yScale = y + (1 - y) * easedStep;

And then we add the step to the animation string:

animation += `${step}% {
  transform: scale(${xScale}, ${yScale});
}`;

To avoid the content to get stretched/ skewed, we should perform a counter animation on it, using the inverted values:

const invXScale = 1 / xScale;
const invYScale = 1 / yScale;

inverseAnimation += `${step}% {
  transform: scale(${invXScale}, ${invYScale});
}`;

Finally, we can return the completed animations, or directly inject them in a newly created style tag.

Step 3: Enable the CSS animations 

On the CSS side of things, we need to enable the animations on the correct elements:

.element--expanded {
  animation-name: animation;
  animation-duration: 300ms;
  animation-timing-function: step-end;
}

.element-contents--expanded {
  animation-name: inverseAnimation ;
  animation-duration: 300ms;
  animation-timing-function: step-end;
}

You can check the example of a Menu from Paul Lewis article, on Codepen (courtesy of Chris Coyer):

Building an expandable section 

After grasping these baseline concepts, I wanted to check if I could apply this technique to a different use case, like a expandable section.

We only need to animate the height in this case, specifically on the function to calculate scales. We’re getting the Y value from the section title, to serve as the collapsed state, and the whole section to represent the expanded state:

    _calculateScales () {
      var collapsed = this._sectionItemTitle.getBoundingClientRect();
      var expanded = this._section.getBoundingClientRect();
      
      // create css variable with collapsed height, to apply on the wrapper
      this._sectionWrapper.style.setProperty('--title-height', collapsed.height + 'px');

      this._collapsed = {
        y: collapsed.height / expanded.height
      }
    }

Since we want the expanded section to have absolute positioning (in order to avoid it taking space when in a collapsed state), we are setting the CSS variable for it with the collapsed height, applied on the wrapper. That will be the only element with relative positioning.

Next comes the function to create the keyframes: _createEaseAnimations(). This doesn’t differ much from what was explained above. For this use case, we actually need to create four animations:

  1. The animation to expand the wrapper
  2. The counter-expand animation on the content
  3. The animation to collapse the wrapper
  4. The counter-collapse animation on the content

We follow the same approach as before, running a for loop with a length of 60 (to get a smooth 60 FPS animation), and create a keyframe percentage, based on the eased step. Then, we push it to the final animations strings:

outerAnimation.push(`
  ${percentage}% {
    transform: scaleY(${yScale});
  }`);
  
innerAnimation.push(`
  ${percentage}% {
    transform: scaleY(${invScaleY});
  }`);

We start by creating a style tag to hold the finished animations. As this is built as a constructor, to be able to easily add multiple patterns, we want to have all these generated animations on the same stylesheet. So, first, we validate if the element exists. If not, we create it and add a meaningful class name. Otherwise, you would end up with a stylesheet for each section expandable, which is not ideal.

 var sectionEase = document.querySelector('.section-animations');
 if (!sectionEase) {
  sectionEase = document.createElement('style');
  sectionEase.classList.add('section-animations');
 }

Speaking of that, you may already be wondering, “Hmm, if we have multiple expandable sections, wouldn’t they still be using the same-named animation, with possibly wrong values for their content?” 

You’re absolutely right! So, to prevent that, we are also generating dynamic animation names. Cool, right?

We make use of the index passed to the constructor from the for loop when making the querySelectorAll('.section') to add a unique element to the name:

var sectionExpandAnimationName = "sectionExpandAnimation" + index;
var sectionExpandContentsAnimationName = "sectionExpandContentsAnimation" + index;

Then we use this name to set a CSS variable on the current expandable section. As this variable is only in this scope, we just need to set the animation to the new variable in the CSS, and each pattern will get its respective animation-name value.

.section.is--expanded {
  animation-name: var(--sectionExpandAnimation);
}

.is--expanded .section-item {
  animation-name: var(--sectionExpandContentsAnimation);
}

.section.is--collapsed {
  animation-name: var(--sectionCollapseAnimation);
}

.is--collapsed .section-item {
  animation-name: var(--sectionCollapseContentsAnimation);
}

The rest of the script is related to adding event listeners, functions to toggle the collapse/expand status and some accessibility improvements.

About the HTML and CSS: it needs a little bit of extra work to make the expandable functionality work. We need an extra wrapper to be the relative element that doesn’t animate. The expandable children have an absolute position so that they don’t occupy space when collapsed.

Remember, since we need to make counter animations, we make it scale full size in order to avoid a skew effect on the content.

.section-item-wrapper {
  min-height: var(--title-height);
  position: relative;
}

.section {
  animation-duration: 300ms;
  animation-timing-function: step-end;
  contain: content;
  left: 0;
  position: absolute;
  top: 0;
  transform-origin: top left;
  will-change: transform;
}

.section-item {
  animation-duration: 300ms;
  animation-timing-function: step-end;
  contain: content;
  transform-origin: top left;
  will-change: transform;  
}

I would like to highlight the importance of the animation-timing-functionproperty. It should be set to linear or step-end to avoid easing between each keyframe.

The will-change property — as you probably know — will enable GPU acceleration for the transform animation for an even smoother experience. And using the contains property, with a value of contents, will help the browser treat the element independently from the rest of the DOM tree, limiting the area before it recalculates the layout, style, paint and size properties.

We use visibility and opacity to hide the content, and stop screen readers to access it, when collapsed.

.section-item-content {
  opacity: 1;
  transition: opacity 500ms ease;
}

.is--collapsed .section-item-content {
  opacity: 0;
  visibility: hidden;
}

And finally, we have our section expandable! Here’s the complete code and demo for you to check:

Performance check

Anytime we work with animations, performance ought to be in the back of our mind. So, let’s use developer tools to check if all this work was worthy, performance-wise. Using the Performance tab (I’m using Chrome DevTools), we can analyze the FPS and the CPU usage, during the animations.

And the results are great!

The higher the green bar, the higher the frames. And there’s no junk either, which would be signed by red sections.

Using the FPS meter tool to check the values at greater detail, we can see that it constantly hits the 60 FPS mark, even with abusive usage.

Final considerations

So, what’s the verdict? Does this replace all other methods? Is this the “Holy Grail” solution?

In my opinion, no. 

But… that’s OK, really! It’s another solution on the list. And, as is true with any other method, it should be analyzed if it’s the best approach for the use-case.

This technique definitely has its merits. As Paul Lewis says, this does take a lot of work to prepare. But, on the flip side, we only need to do it once, when the page loads. During interactions, we are merely toggling classes (and attributes in some cases, for accessibility).

However, this brings some limitations for the UI of the elements. As you could see for the expandable section element, the counter-scale makes it much more reliable for absolute and off-canvas elements, like floating-actions or menus. It’s also difficult to styled borders because it’s using overflow: hidden.

Nevertheless, I think there’s tons of potential with this approach. Let me know what you think!

The post Performant Expandable Animations: Building Keyframes on the Fly appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2w3L6CT
via IFTTT

Let a website be a worry stone

Ethan Marcotte just redesigned his website and wrote about how the process was a distraction from the difficult things that are going on right now. Adding new features to your blog or your portfolio, tidying up performance issues, and improving things bit by bit can certainly relieve a lot of stress. Also? It’s fun!

What about adding a dark mode to our websites? Or playing around with Next.js? How about finally updating to that static site generator we’ve always wanted to experiment with? Or perhaps we could make the background color of our website animate slowly over time, like Robin’s? Or what about rolling up our sleeves and making a buck wild animation like the one on Sarah’s homepage?

Not so long ago, I felt a bout of intense anxiety hit me out of nowhere and I wound up updating my own website — it was nothing short of relaxing, like going to the spa for a day. I suddenly realized that I could just throw all that stress at my website and do something half-useful in the process. One evening I sat down to focus on my Lighthouse score, the next day was all about fonts, and after that I made a bunch of commits to update the layouts on my site.

This isn’t about being productive right now — it’s barely possible to focus on anything for me with the state of things. And also I’m certainly not trying to guilt trip anyone into cranking out more websites. We all need to take a breath and take each day at a time.

But! If treating your website like a worry stone can help, then I think it’s time to roll up our sleeves and make something weird for ourselves.

Direct Link to ArticlePermalink

The post Let a website be a worry stone appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2QKgBJu
via IFTTT

What Can We Actually Do With corner-shape?

When I first started messing around with code, rounded corners required five background images or an image sprite likely created in Photosh...