Tag: Behind

Behind the CSScenes, November 2022

Is it Fall? Winter? I don’t know, but I woke up with snow in the front yard this morning and felt like it was time to write a little update about what’s been happening around CSS-Tricks this past month, as we’re known to do from time to time.

First up is the CSS-Tricks Newsletter! It’s starting to feel like we’re getting our rhythm down after months of hiatus. The last edition went out at the very end of October. That’s the third consecutive month we’ve been able to shoot it out which I’d call a big win for consistency. Nah, it’s not the weekly cadence we had before, but that’s something we’re aspiring to as our team continues to establish itself.

Speaking of which — we have a new team member! We brought Andrea Anderson on board. She’s a well-established technical editor and we’re lucky as heck she’s here. While she might work on a CSS-Tricks piece from time to time, her main focus is working on content that’s integrated into DigitalOcean’s Community site.

Oh, and while we’re on the topic of DigitalOcean’s Community, check out this Developer Markepear post deep-diving into DigitalOcean’s writing process. Seriously, it’s an incredibly deep dive that gets into the way tutorials are outlined and structured, the UX of navigating the tutorial archives, and even the delicate interplay between the content and advertising in each article.

I really like how DigitalOcean’s tutorials are described as “give-first” content that “has a smell of value all over it.” It speaks volumes about the team’s work ethic, which I can personally attest is top-notch. It’s really the reason DigitalOcean and CSS-Tricks make a great match.

Advertising is also pretty top-of-mind for us right now. When we ran a survey the other month, we knew that there’d be concerns about how CSS-Tricks ads would be affected after the DigitalOcean acquisition. Would we remove them? Make them all about DigitalOcean? Keep everything as-is? I mean, CSS-Tricks has traditionally relied on an advertising model to keep the lights on, but now that it’s backed by a company, how much do we really need to rely on ads at all?

Turns out many of you like the ads, according to the survey. They’re sort of like product recommendations baked into the site, and I think that’s a testament to Chris’s effort to make sure ads are (1) promoting good stuff and (2) are relevant to the front-end work we do. Case in point: we recently swapped out a bunch of DigitalOcean ads to promote Cloudways hosting after DigitalOcean acquired it. Those ads didn’t do so well, so we swapped the DigitalOcean ones back in, which were already doing quite well.

(The advertised deal is pretty darn good, by the way… $ 200 in free credits to spin up your project.)

The work to move CSS-Tricks from WordPress to the same CMS the DigitalOcean Community uses for its content is still in progress. A lot of the work is still mapping WordPress content fields to the new CMS. That’s no trivial task when we’re talking about a website with 7,000-odd articles over a 15-year span. That’s going well, as is the initial site architecture. Next up, we need to figure out how we’re handling WordPress blocks, replicating their features, and creating an inventory of all that we need to carry over. Phew!

New faces!

As always, we tend to have a few new faces on the site each month as we work with new guest authors. This month, we welcomed Krzysztof Gonciarz and Lorenzo Bonannella. Check out their articles and give ’em a high five for sharing their work. It takes a lot of work to write, not to mention some courage to put your ideas in front of other people. So, thanks a bunch Krzysztof and Lorenzo!

Meet Mojtaba Seyedi

I thought catching up with one of our long-time writers would be a nice way to cap off this month’s update. And few people have contributed as many articles to CSS-Tricks as Mojtaba Seyedi. You may not see his name pop up in the archives all that much, but it’s only because he spends so much time in the Almanac.

I asked Mojtaba a few questions about his work and he graciously responded with these answers…

Your very first article with us was a roundup of plugins for the Sublime Text editor way back in 2017. What made you think to publish it on CSS-Tricks?

I used to be very passionate about the Sublime Text editor and its plugins. I could always find a plugin to ease the pain whenever I was tired of doing repetitive tasks. I would show my co-workers how interesting whatever plugin I was using was and encourage them to use it.

One of my New Year’s resolutions back then — in 2017 — was to publish an article on CSS-Tricks. I always thought the idea had been highly technical. It never occurred to me I could simply create a list of Sublime Text plugins that I happened to find useful for development! Nowadays, I can see how the high bar I had set was preventing me from writing about something that I loved.

There was a brief moment when I considered giving up on that first article. I had psyched myself out thinking that there were tons of other posts already covering the exact same thing. But out of curiosity, I Googled some of the top Sublime Text plugin posts, and surprisingly, I didn’t see any of the plugins I was writing about. So, that’s how I submitted my first article on this website!

You’ve written a total of 35 articles for CSS-Tricks, 33 of which are in the Almanac. What do you enjoy about writing technical information like that?

Almanac entries are referenceable. We keep coming back to them to check the syntax of a property or a selector. For example, we might need to visit the background shorthand property to remember whether the background-position value goes before or after the slash (/). References never get old, which is why the Almanac is special to me.

Along the same lines, documentation is challenging. One of the challenges of writing for the CSS-Tricks Almanac is reading and understanding the W3C’s specifications. For example, when I wanted to write about the mask-border property, the CSS spec was practically my only source. I needed to figure out all the aspects of that module and how different values behave in different situations because there were scant examples in the wild. I enjoy that sort of challenge and feel great when I can turn my findings into something tangible that other developers can understand and use in their own work.

There’s also the joy of completeness. Documentation allows me to get deep into details that might not make it in a typical article. I get satisfaction when I’m able to grasp a property or selector and explain it in my own words. The CSS-Tricks Alamanc gives me that opportunity.

What can you say about the editing process for those who haven’t gone through it?

First, enjoy a clean and easy process. The CSS-Tricks editorial team will help you improve it and make it better than you can on your own.

Also, be sure to edit your draft first. Always edit the article yourself before submitting it. The more ready your writing is, the more time it gives the editor to help you improve your work. If the editor needs to spend a lot of time fixing basic grammar and spelling, that’s time that could have been spent pushing the idea further with feedback and other considerations.

And, of course, learn from your mistakes. Be open to learning while you’re in the editing process. The editorial team here is very experienced and helpful. I try to review what they have changed in my article and put them into practice in my next writings. I would love to thank Geoff, from whom I have learned a lot about technical writing.

Do you have any tips for someone thinking about submitting an article proposal?

Do not overthink the idea. Your article doesn’t have to be rocket science. Anything you know well enough to write about can be helpful to others.

Another piece of advice: do not underestimate yourself. When Chris Coyier invited the community to contribute to the CSS-Tricks Almanac, I told myself there were many more qualified people who could do that, even though I had experience writing CSS docs. And yes, many folks were (and maybe still are) more knowledgeable than me. But as it turned out, I could be a part of this because I was willing to try.

Another big deal is to not worry about repeating others. Your idea doesn’t have to be unique. You can write about something others have written about in a new and different way. Your point of view and perspective matter! Your approach to solving a problem and how you explain it might be different in a super helpful way.

And finally… what’s your favorite CSS trick?

My favorite trick used to be centering an element by setting display: table on it and letting auto margins do the rest. Nowadays, with CSS becoming much more awesome, I can do the same trick with min-content and without an additional wrapper.

I’m sure there is a blog post or article about this same topic somewhere on the web. But I would like to write about it here on CSS-Tricks. See? I want to share my own perspective with you and I want to explain it in my own way.

Have something you want to share on CSS-Tricks? Send us your pitch!


Behind the CSScenes, November 2022 originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

CSS-Tricks

, , ,

Behind the CSScenes, October 2022

Well, hey, welcome back to Behind the CSScenes! These posts are like little check-ins we’re doing each month to give you a peek behind what we’re doing here at CSS-Tricks, as well as a chance for us to pause and celebrate a few things.

Last month, we shared a small taste of a redesign for this very site. Thanks to all the folks who wrote in to comment on it! Seems the overwhelming response is pretty dang positive, though the background color was a mixed bag of reactions.

There’s more work to do, of course! This month, we have a little more to share with you on the development side of things, plus a roundup of some recent activity around here. So, let’s dial in Haley Mills for the latest.

Content updates

[Haley:] September was a busy month for our team! We published 16 articles by guest authors and another 15 by folks on our team. In addition to these, we’ve been updating many of the older articles, including adding freshly-linked resources. We’ve already updated over 50 articles and will continue these efforts as part of our day-to-day work. Thank you to the team and the awesome authors who contributed this content!

To build on our efforts to provide front-end developers with the tools they need, I’m also super excited to share that we are starting to kick the tires on new guides. Guides have been a free, helpful resource to the CSS-Tricks Community since the first one was published in 2019, and we’ve known from day 1 that we need to keep this tradition going. Since this is a new process for our team, we want to ensure that the workflow for authors is completely snag-free before opening it up to the public to apply. Until then, we will be working with hand-selected authors to bring you new guides on a variety of topics.

Have a suggestion for a guide that you’d love to see? Let us know in the comments!

Finally, you might’ve heard the news that CloudWays is joining DigitalOcean and is offering a $ 50 credit to folks in our community! While our top priority will always be to provide platform-agnostic resources to CSS-Tricks readers, you can expect to see helpful content about CloudWays in the future because we truly believe that their managed solution could be a great fit for the community.

Thanks for reading the content updates! Next up we have our senior web developer, David Berg, with an update on the back-end work we’re doing to move CSS-Tricks to a new CMS.

What’s happening on the back end

[David Berg:] The DigitalOcean team is actively working to pluck CSS-Tricks from WordPress and drop it into the same hand-rolled CMS we use for our other sites, including DigitalOcean’s library of tutorials. Don’t worry! CSS-Tricks will still be the same standalone site at the same domain, hyphenated and all. But it’s a ton of work, as you might imagine!

If anything has been challenging so far, it’s been aligning the WordPress data from the current site with the structure of our internal system. Our team currently uses a properly vetted, maintained, and organized PostgreSQL database that interfaces with the client through an array of in-repository services over which we maintain tight code control and quality. The WordPress database structure is unintuitive — at least to me and our team — and has required our team to find obscure and maybe overly complex solutions to mash these things together.

That said, migrating CSS-Tricks content over to our in-house solution allows us to ensure the integrity and future-proofing of complex database relationships. Through this process, we can slim down the time it takes to query the database, improve efficiencies of three (or more)-dimensional relationships, and accurately model new relationships according to new features we might develop down the road.

In short, that means we will no longer be reliant on a monolithic WordPress instance to serve a response to every request. We can statically export all the publicly accessible content to a CDN, with the services handling edit operations only when needed.

It’s easier to submit article proposals!

[Haley:] Speaking of a more robust back end architecture, something else happening behind the scenes is a new form for guest authors submitting article proposals to us for publication.

We used a form before this one, but we had it tied up with Jira in a way that helps us manage the proposals and keep track of where they are in the editing flow. That integration was crumbling right before our eyes, so we went with a Typeform-powered version instead.

CSS-Tricks guest writer application front page.

While it might seem like a fairly minor thing, it’s a big deal as far as making it easier to share your proposals and making sure nothing falls through the cracks — so we have fresh new front-end content to publish for you on a consistent basis!

Oh, and if you happen to submit a proposal (and you should!) please let us know if you see any opportunities for us to make it even easier and more helpful.

Passing it back to Geoff with my favorite part of these updates: author highlights!

Some fresh new faces around here

[Geoff:] The articles you read here at CSS-Tricks are written by folks like yourself. It’s amazing just how gosh darned smart this community is and all the ideas that get passed around here. In fact, we welcomed 5 new voices this past month:

What a great bunch, right? Give ‘em all some love for taking time out of their busy lives to share their wisdom and clever tricks with the rest of us. And a shout out to familiar faces, like Temani Afif, Preethi, Ollie Williams, and Mojtaba Seyedi for all the hard work they continue to do that keeps pushing this thing we call front-end development forward.

High fives to all these folks, and to you for reading. ✋ We wouldn’t be doing this without y’all.


Behind the CSScenes, October 2022 originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

CSS-Tricks

, , ,
[Top]

Behind the CSScenes, September 2022

Those of you who have been reading CSS-Tricks for a while may remember that we used to publish a little thing we called CSS-Tricks Chronicles. Our friend Chris Coyier would write up a reflection from the past couple of months or so, and it was a great way to get a pulse on what’s happening around CSS-Tricks, the site, and what the team is doing.

We like that and want to keep it going. It’s a new era, though! So what we’re going to do is welcome you back to what we’re now calling Behind the CSScenes. You’re going to meet some new and familiar faces in these updates, starting with Haley Mills, who is kicking off the very first issue.

How’s the transition going?

[Haley Mills:] Before we dive in, let me start by introducing myself! My name is Haley, and I’m the manager of Content Integration here at DigitalOcean. I’ve been at DigitalOcean for 5 years and previously worked on our editorial team, helping authors publish all sorts of topics through our Write For DOnations program. 

Many folks here at DigitalOcean (including myself) are avid readers of CSS-Tricks, and we still have to pinch ourselves for how lucky we are to be entrusted with this community. We recognize that CSS-Tricks is a critical free resource for devs across the world, and my goal is to keep it that way. 

  • Since the acquisition, we have published 95 pieces of new content and look forward to growing that number.
  • In the month of August, we performed maintenance on 6 existing pieces of content.

That said, change is to be expected when passing a torch.

I think we all know that no one can replace Chris’ voice — it’s a big reason why CSS-Tricks is, well, CSS-Tricks. His ability to have you laughing while learning something new is a skill that few can compete with. I know many of you miss his writing because you told us so in a survey (which we’ll get to in a bit), but it also opens up a huge opportunity for us all to take the torch and continue doing what CSS-Tricks does best:

Find creative solutions to problems and share them with the world. Chris brought people together this way on CSS-Tricks — and you can give back, too.

Your blossoming idea could turn out to be what the Flexbox Guide is for me and so many other people, so I humbly encourage you to reach out in our Guest Writing Form and talk to us about your topic ideas. We have two awesome editors, Geoff and Brad, to help you shape and bring your ideas to life to share with the CSS-Tricks community. In addition to paying you for your contribution, we will now also make a matching donation to a tech-focused charity of your choice.

Next up, we have Product Manager Karen Degi with some survey result highlights.

The results are in…

[Karen Degi:] In June, we shared a survey to collect feedback to help shape the future of CSS-Tricks. We received almost 900 responses, including some great written responses that helped us understand what CSS-Tricks means to the larger community. 

Many of you also volunteered to talk to us directly, which has us thinking about the best way to gather those thoughts. If you’re one of those folks, know that we haven’t forgotten about you and still want to hear from you. We just want to make sure we approach this in the most effective way!

The survey confirmed some things we already suspected and brought new things to our attention. The top few things that grabbed our attention are:

  • Engaging, high-quality content is at the heart of CSS-Tricks. We’re working to make sure that we continue investing in in-depth guides on front-end topics, as well as providing short articles about quick tricks and tutorials with embedded demos.
  • You love RSS! As we continue investing in CSS-Tricks and bringing new functionality, we’ll make sure we keep an eye on how our changes affect the RSS feed.
  • You come to CSS-Tricks to learn, to be entertained, and to do your jobs better. You do not come to CSS-Tricks because you’re excited about being sold…well, anything, really. Although we think DigitalOcean is pretty great, and we’ll probably continue to talk about ourselves where it makes sense, we understand that we need to do so in a way that is honest, trustworthy, and connected to your needs as a front-end enthusiast.

Next up is Logan Liffick, Senior Digital Experience Designer, with redesign updates.

A redesign is in the works!

[Logan Liffick:] If you’ve worked on the front end — or really anywhere on the web, you’re bound to know CSS-Tricks. It’s where I, and many others, started the journey. So, when I was asked to spearhead a redesign for the site, it was nothing short of an honor. Without a doubt, undertaking a brand update for something so familiar to so many is a challenge of incredible magnitude

If I were to do justice to this project, I’d need to pay tribute to the original. That mentality became the underlying theme of my work, and any effort to rejuvenate took inspiration from existing patterns and styles from the site.

  • Slideshow of Redesign Preview

Upon first glance, you’ll notice the fresh coat of paint. Past that, you’ll recognize the site reads more “editorial” than before. This was a purposeful decision to accentuate existing type stylings and, more importantly, to pay homage to the essence of CSS-Tricks as an informational resource. 

Preserving the element of “fun” was also top of mind. Sprinkled throughout the site are various snippets from the actual CSS “tricks” shared on this site — for example, there’s going to be a little Easter egg tucked inside a sticky footer using Preethi’s slide-out effect that’s my personal favorite, a fantastic suggestion from Geoff himself. Gradients are now a core color-way in the system, and border-radii have been rounded out. 

We wanted to give ourselves permission and space to explore an open-ended and malleable system far into the future, which lines up nicely with the overall mission and goal of CSS-Tricks: to explore what’s possible with CSS. This is just the beginning, there’s so much more to see, do, and learn with CSS-Tricks living in our (digital) ocean.

Next is Geoff with author highlights!

New authors!

[Geoff:] We’ve added a few new faces to our growing list of guest authors who have contributed to CSS-Tricks:

You may have also seen our editor Bradley Kouchi’s name pop up a couple of times, and you can expect to continue seeing him on a semi-regular basis.

That’s 16 new authors! You can be one, too, by filling out our guest writing form.

On a related note, I’m pleased as punch that we still get regular contributions from a large band of familiar faces from before the DigitalOcean acquisition. Just look at all the fine folks who’ve continued to share their great ideas with us:

Big shake-ups like the one we’re going through today can be scary. Seeing these familiar names in article bylines has helped me a ton as far as continuity and consistency go. CSS-Tricks still seems very CSS-Tricks-y to me, and that’s a big deal.

Until next time…

We hope you’ve enjoyed this little peek behind the CSScenes! We’ll do it again… and again and again. As you can tell, there’s a lot of activity happening around here, which means we’ll have lots to share in the next edition.

Oh, and if you’re one of the many who’ve told us just how much you miss the newsletter, it’s still here! We’re sending it just once a month while we get back in the swing of things, and you may very well need to re-subscribe to get it (we had to do a lot of scrubbing after the keys to the site were handed over).

Thanks for reading!


Behind the CSScenes, September 2022 originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

CSS-Tricks

, , ,
[Top]

The Story Behind TryShape, a Showcase for the CSS clip-path property

I love shapes, especially colorful ones! Shapes on websites are in the same category of helpfulness as background colors, images, banners, section separators, artwork, and many more: they can help us understand context and inform our actions through affordances.

A few months back, I built an application to engage my 7-year old daughter with mathematics. Apart from basic addition and subtraction, my aim was to present questions using shapes. That’s when I got familiar with the CSS clip-path property, a reliable way to make shapes on the web. Then, I ended up building another app called, TryShape using the power of clip-path.

I’ll walk you through the story behind TryShape and how it helps create, manage, share, and export shapes. We’ll cover a lot about CSS clip-path along the way and how it helped me quickly build the app.

Here are a few important links:

First, the CSS clip-path property and shapes

Imagine you have a plain piece of paper and a pencil to draw a shape (say, a square) on it. How will you proceed? Most likely, you will start from a point, then draw a line to reach another point, then repeat it exact three more times to come back to the initial point. You also have to make sure you have opposite lines parallel and of the same length.

So, the essential ingredients for a shape are points, lines, directions, curves, angles, and lengths, among many others. The CSS clip-path helps specify many of these properties to clip a region of an HTML element to show a specific region. The part that is inside the clipped region is shown, and the rest is hidden. It gives an ocean of opportunities to developers to create various shapes using clip-path property.

Learn more about clipping and how it is different from masking.

The clip-path values for shape creation

The clip-path property accepts the following values for creating shapes:

  • circle()
  • ellipse()
  • inset()
  • polygon()
  • A clip source using url() function
  • path()

We need to understand the basic coordinate system a bit to use these values. When applying the clip-path property on an element to create shapes, we must consider the x-axis, y-axis, and the initial coordinates (0,0) at the element’s top-left corner.

Here is a div element with its x-axis, y-axis, and initial coordinates (0,0).

A blue square with its starting point located at a zero zero position on a chart with x and y axes.
Initial coordinates(0,0) with x-axis and y-axis

Now let’s use the circle() value to create a circular shape. We can specify the position and radius of the circle using this value. For example, to clip a circular shape at the coordinate position (70, 70) with a radius of 70px, we can specify the clip-path property value as:

clip-path: circle(70px at 70px 70px)

So, the center of the circle is placed at the coordinate (70, 70) with a 70px radius. Now, only this circular region is clipped and shown on the element. The rest of the portion of the element is hidden to create the impression of a circle shape.

A blue circle on a grid with an x and y axis. The circle starts at the zero zero position and its center is located at 70 px and 70px. A zoomed in area shows the clipping path, which is also located at 70x and 70px.
The center of the circle is placed at (70, 70) coordinates with a 70px x 70px area clipped. Hence the full circle is shown.

Next, what if we want to specify the position at (0,0)? In this case, the circle’s center is placed at the (0,0) position with a radius of 70px. That makes only a portion of the circle visible inside the element.

The center of a blue circle is placed at the 0,0 coordinates with a 70px by 70px area clipping the bottom-left region of the circle.
The center of the circle is placed at (0, 0) coordinates with a 70px x 70px area clipping the bottom-left region of the circle.

Let’s move on to use the other two essential values, inset() and polygon(). We use an inset to define a rectangular shape. We can specify the gap that each of the four edges may have to clip a region from an element. For example:

clip-path: inset(30px)

The above clip-path value clips a region by leaving out the 30px values from element’s edges. We can see that in the image below. We can also specify a different inset value for each of the edges.

The inset() function allows us to clip and area from the outside edge of a shape.

Next is the polygon() value. We can create a polygonal shape using a set of vertices. Take this example:

clip-path: polygon(10% 10%, 90% 10%, 90% 90%, 10% 80%)

Here we are specifying a set of vertices to create a region for clipping. The image below shows the position of each vertex to create a polygonal shape. We can specify as many vertices as we want.

A square with four points inside of it located at 10% by 10%, 90% by 10%, 10% by 80% and 90% by 90%, creating the clipped area.
The polygon() function allows us to create polygonal shapes using the set of vertices passed to it.

Next, let’s take a look at the ellipse() and the url() values. The ellipse() value helps create shapes by specifying two radii values and a position. In the image below, we see an ellipse at the position where the radii is at (50%,50%) and the shape is 70px wide and 100px tall.

A blue blue against a light blue background. The ellipse is 70 pixels wide and 100 pixels tall and it's radius is centered at 50% 50%.
We need to specify two radii values and a position to create an ellipse.

url() is a CSS function to specify the clip-path element’s ID value to render an SVG shape. Please take a look at the image below. We have defined a SVG shape using clipPath and path elements. You can use the ID value of the clipPath element as an argument to the url() function to render this shape.

Showing the SVG code for a heart-shaped path and the actual heart next to it in blue.
Here, we are creating a heart shape using the url() function

Additionally, we can use the path values directly in the path() function to draw the shape.

Showing a line of CSS code for the clip-path property filled in with the code of an SVG path inside the path function. The result is below the code, a parabolic curve that's filled in blue.
Here we are creating a curvy shape using the path() function.

Alright. I hope you have got an understanding of different clip-path property values. With this understanding, let’s take a loot at some implementations and play around with them. Here is a Pen for you. Please use it to try adding, modifying values to create a new shape.

Let’s talk about TryShape

It’s time to talk about TryShape and its background story. TryShape is an open-source application that helps create, export, share, and use any shapes of your choice. You can create banners, circles, arts, polygons and export them as SVG, PNG, and JPEG files. You can also create a CSS code snippet to copy and use in your application.

TryShape is built using the following framework and libraries (and clip-path, of course):

  • CSS clip-path: We’ve already discussed the power of this awesome CSS property.
  • Next.js: The coolest React-based framework around. It helped me create pages, components, interactions, and APIs to connect to the back-end database.
  • HarperDB: A flexible database to store data and query them using both SQL and No-SQL interactions. TryShape has its schema and tables created in the HarperDB cloud. The Next.js APIs interact with the schema and tables to perform required CRUD operations from the user interface.
  • Firebase: Authentication services from Google. TryShape uses it to get the social login working using Google, GitHub, Twitter, and other accounts.
  • react-icons: One shop for all the icons for a React-based application
  • date-fns: The modern, lightweight library for date formatting
  • axios: Making the API calls easy from the React components
  • styled-components: A structured way to create CSS rules from react components
  • react-clip-path: A homegrown module to handle clip-path property in a React app
  • react-draggable: Make an HTML element draggable in a React app. TryShape uses it to adjust the position of shape vertices.
  • downloadjs: Trigger a download from JavaScript
  • html-to-image: Converts an HTML element to image (including SVG, JPEG, and PNG)
  • Vercel: Best for hosting a Next.js app

Creating shapes in TryShape using CSS clip-path

Let me highlight the source code that helps create a shape using the CSS clip-path property. The code snippet below defines the user interface structure for a container element (Box) that’s 300px square. The Box element has two child elements, Shadow and Component.

<Box    height="300px"    width="300px"    onClick={(e) => props.handleChange(e)}>   {      props.shapeInformation.showShadow &&      <Shadow        backgroundColor={props.shapeInformation.backgroundColor}        id="shapeShadow" />    }   <Component      formula={props.shapeInformation.formula}      backgroundColor={props.shapeInformation.backgroundColor}      id="clippedShape" /> </Box>

The Shadow component defines the area that is hidden by the clip-path clipping. We create it to show a light color background to make this area partially visible to the end user. The Component is to assign the clip-path value to show the clipped area.

See the styled-component definitions of Box, Shadow, and Component below:

// The styled-components code to create the UI components using CSS properties  // The container div const Box = styled.div`   width: $ {props => props.width || '100px'};   height: $ {props => props.height || '100px'};   margin: 0 auto;   position: relative; `;  // Shadow defines the area that is hidden by the `clip-path` clipping // We show a light color background to make this area partially visible. const Shadow = styled.div`   background-color: $ {props => props.backgroundColor || '#00c4ff'};   opacity: 0.25;   position: absolute;   top: 10px;   left: 10px;   right: 10px;   bottom: 10px; `;  // The actual component that takes the `clip-path` value (formula) and set // to the `clip-path` property. const Component = styled.div`   clip-path: $ {props => props.formula}; // the formula is the clip-path value   background-color: $ {props => props.backgroundColor || '#00c4ff'};   position: absolute;   top: 10px;   left: 10px;   right: 10px;   bottom: 10px; `;
An illustration of a blue box with its inset clip points drawing another square that indicates the visible area of the shape in a darker blue.
The components to show a shape(both visible and hidden areas) after the clipping.

Please feel free to look into the entire codebase in the GitHub repo.

The future scope of TryShape

TryShape works well with the creation and management of basic shapes using CSS clip-path in the background. It is helpful to export the shapes and the CSS code snippets to use in your web applications. It has the potential to grow with many more valuable features. The primary one will be the ability to create shapes with curvy edges.

To support the curvy shapes, we need the support of the following values in TryShape:

  • a clip source using url() and
  • path().

With the help of these values, we can create shapes using SVG and then use one of the above values. Here is an example of the url() CSS function to create a shape using the SVG support.

<div class="heart">Heart</div> <svg>   <clipPath id="heart-path" clipPathUnits="objectBoundingBox">     <path d="M0.5,1       C 0.5,1,0,0.7,0,0.3       A 0.25,0.25,1,1,1,0.5,0.3       A 0.25,0.25,1,1,1,1,0.3       C 1,0.7,0.5,1,0.5,1 Z" />   </clipPath> </svg>

Then, the CSS::

.heart {   clip-path: url(#heart-path); }
It produces a heart shape like this.

Now, let’s create a shape using the path() value. The HTML should have an element like a div:

<div class="curve">Curve</div>

In CSS:

.curve {   clip-path: path("M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80"); }

Before we end…

I hope you enjoyed meeting my TryShape app and learning about the idea that leads to it, the strategies I considered, the technology under the hood, and its future potential. Please consider trying it and looking through the source code. And, of course, feel free to contribute to it with issues, feature requests, and code.

Before we end, I want to leave you with this short video prepared for the Hashnode hackathon where TryShape was an entry and finally in the list of winners. I hope you enjoy it.

Let’s connect. You can @ me on Twitter (@tapasadhikary) with comments, or feel free to follow.


The post The Story Behind TryShape, a Showcase for the CSS clip-path property appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

CSS-Tricks

, , , , ,
[Top]

Behind the Source: Cassie Evans

I feel like the tech industry takes itself far too seriously sometimes. I get frustrated by all the posturing and gatekeeping – “You’re not a real developer unless you use x framework”, “CSS isn’t a real programming language”.

I think this kind of rhetoric often puts new developers off, and the ones that don’t get put off are more inclined to skip over learning things like semantic markup and accessibility in favour of learning the latest framework.

Having a deeper knowledge of HTML and CSS is often devalued.

Posturing and gatekeeping, indeed. I’ve yet to witness a conversation where discussing what is or isn’t “real” programming was fruitful for anybody.


Related sentiment from Mehdi Zed about PHP:

Most developers who hate PHP hate it out of elitism or ignorance. Either way it’s dumb.

Direct Link to ArticlePermalink

The post Behind the Source: Cassie Evans appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

The Thought Process Behind a Flexbox Layout

I just need to put two boxes side-by-side and I hear flexbox is good at stuff like that.

Just adding display: flex; to the parent element lays out the children in a row.

Well, that’s cool. I guess I could have floated them, but this is easier.

They should probably take up the full space they have though. Can I just stretch the parent to 100% wide? Well, I can, but that’s apparently not going to affect the child elements.

If the parent element has more space than the children need, it doesn’t do anything to help the children fill the space alone.

Maybe I can use width: 50%; on the children? That works, but I thought the point of flexbox is that you don’t have to be all specific about width. Ah yes, flexbox has all of these ways of expressing the growy-shrinky-initial behavior of children. Looks like flex: 1; is about as easy as it gets here.

Applying flex: 1; to the children allow them to grow and fill the space.

I like how I haven’t had to do any math or hard code values so far. Can I make it a three-up pattern without touching CSS?

Nice.

Hmmm, wait. The sizing is a bit, uhhhh, flexy? Nothing is forcing these boxes to be one-third of the container all the time.

Looks like flex-basis: 33% doesn’t fix this. flex: 0 0 33%; also doesn’t do the trick. Looks like width: 33%; flex-shrink: 0; does though, if we’re really wanting to strongarm it.

Sometimes a design calls for exactly equal size boxes. This is maybe CSS Grid territory, but whatever.

The long word forcing that sizing behavior at narrow widths is perhaps an uncommon scenario. We could have also solved it with word-break: break-word; hyphens: auto; on the child.

Another thing we could do it just let the dang items wrap instead of being so strict about it. Flexbox can do that, right?

Oh hey, that reminds me how cool it is that those first two items are the same height. That’s the default stretch behavior, but it can be controlled as well. And it’s by row, which is why the second row has its own different height.

What if I want that first “Love” block to be on top instead? Looks like I can re-order it, eh? Let’s see, the default order is 0, so to be first, I do order: -1;.

Ha! That kinda worked. But I meant that I want it to take up the full width on the top row. I guess I can just kick it up to flex-basis: 100%; and the others will wrap accordingly.

It’s pretty weird to have the source order and visual order different like this. Maybe that should go in the “don’t ever do this” category.

What if I wanna bail on the whole flexbox thing at a certain point? Part of me wants to change the direction to go vertical with flex-direction: column; and force the children to be full-width. Ah, a simple display: block; on the parent does that in one swoop.

Rather than changing all the flexbox stuff to handle a column layout, we just turn flexbox off.

Flexbox can do way more stuff! One of my favorites is how auto margins work to “push” other elements away when there is space. This is just one little journey playing with some UI and seeing the useful things flexible does along with things that can make it confusing.

The post The Thought Process Behind a Flexbox Layout appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

The Thinking Behind Simplifying Event Handlers

Events are used to respond when a user clicks somewhere, focuses on a link with their keyboard, and changes the text in a form. When I first started learning JavaScript, I wrote complicated event listeners. More recently, I’ve learned how to reduce both the amount of code I write and the number of listeners I need.

Let’s start with a simple example: a few draggable boxes. We want to show the user which colored box they dragged.

<section>   <div id="red" draggable="true">     <span>R</span>   </div>   <div id="yellow" draggable="true">     <span>Y</span>   </div>   <div id="green" draggable="true">     <span>G</span>   </div> </section>  <p id="dragged">Drag a box</p>

See the Pen
Dragstart events
by Tiger Oakes (@NotWoods)
on CodePen.

The intuitive way to do it

I wrote separate event listener functions for each element when I first started learning about JavaScript events. It’s a common pattern because it’s the simplest way to start. We want specific behavior for each element, so we can use specific code for each.

document.querySelector('#red').addEventListener('dragstart', evt => {   document.querySelector('#dragged').textContent = 'Dragged red'; });  document.querySelector('#yellow').addEventListener('dragstart', evt => {   document.querySelector('#dragged').textContent = 'Dragged yellow'; });  document.querySelector('#green').addEventListener('dragstart', evt => {   document.querySelector('#dragged').textContent = 'Dragged green'; });

Reducing duplicate code

The event listeners in that example are all very similar: each function displays some text. This duplicate code can be collapsed into a helper function.

function preview(color) {   document.querySelector('#dragged').textContent = `Dragged $  {color}`; }  document   .querySelector('#red')   .addEventListener('dragstart', evt => preview('red')); document   .querySelector('#yellow')   .addEventListener('dragstart', evt => preview('yellow')); document   .querySelector('#green')   .addEventListener('dragstart', evt => preview('green'));

This is much cleaner, but it still requires multiple functions and event listeners.

Taking advantage of the Event object

The Event object is the key to simplifying listeners. When an event listener is called, it also sends an Event object as the first argument. This object has some data to describe the event that occurred, such as the time the event happened. To simplify our code, we can use the evt.currentTarget property where currentTarget refers to the element that the event listener is attached to. In our example, it will be one of the three colored boxes.

const preview = evt => {   const color = evt.currentTarget.id;   document.querySelector('#dragged').textContent = `Dragged $  {color}`; };  document.querySelector('#red').addEventListener('dragstart', preview); document.querySelector('#yellow').addEventListener('dragstart', preview); document.querySelector('#green').addEventListener('dragstart', preview);

Now there is only one function instead of four. We can re-use the exact same function as an event listener and evt.currentTarget.href will have a different value depending on the element that fires the event.

Using bubbling

One final change is to reduce the number of lines in our code. Rather than attaching an event listener to each box, we can attach a single event listener to the <section> element that contains all the colored boxes.

An event starts off at the element where the event originated (one of the boxes) when it is fired. However, it won’t stop there. The browser goes to each parent of that element, calling any event listeners on them This will continue until the root of the document is reached (the <body> tag in HTML). This process is called “bubbling” because the event rises through the document tree like a bubble.

Attaching an event listener to the section will cause the focus event to bubble from the colored box that was dragged up to the parent element. We can also take advantage of the evt.target property, which contains the element that fired the event (one of the boxes) rather than the element that the event listener is attached to (the <section> element).

const preview = evt => {   const color = evt.target.id;   document.querySelector('#dragged').textContent = `Dragged $  {color}`; };  document.querySelector('section').addEventListener('dragstart', preview);

Now we’ve reduced many event listeners to just one! With more complicated code, the effect will be greater. By utilizing the Event object and bubbling, we can tame JavaScript events and simplify code for event handlers.

What about click events?

evt.target works great with events like dragstart and change, where there are only a small number of elements that can receive focus or have input changed.

However, we usually want to listen for click events so we can respond to a user clicking on a button in an application. click events fire for any element in the document, from large divs to small spans.

Let’s take our draggable color boxes and make them clickable instead.

<section>   <div id="red" draggable="true">     <span>R</span>   </div>   <div id="yellow" draggable="true">     <span>Y</span>   </div>   <div id="green" draggable="true">     <span>G</span>   </div> </section>  <p id="clicked">Clicked a box</p>
const preview = evt => {   const color = evt.target.id;   document.querySelector('#clicked').textContent = `Clicked $  {color}`; };  document.querySelector('section').addEventListener('click', preview);

See the Pen
Click events: Not quite working
by Tiger Oakes (@NotWoods)
on CodePen.

When testing this code, notice that sometimes nothing is appended to “Clicked” instead of when clicking on a box. The reason that it doesn’t work is that each box contains a <span> element that can be clicked instead of the draggable <div> element. Since the spans don’t have a set ID, the evt.target.id property is an empty string.

We only care about the colored boxes in our code. If we click somewhere inside a box, we need to find the parent box element. We can use element.closest() to find the parent closest to the clicked element.

const preview = evt => {   const element = evt.target.closest('div[draggable]');   if (element != null) {     const color = element.id;     document.querySelector('#clicked').textContent = `Clicked $  {color}`;   } };

See the Pen
Click events: Using .closest
by Tiger Oakes (@NotWoods)
on CodePen.

Now we can use a single listener for click events! If element.closest() returns null, that means the user clicked somewhere outside of a colored box and we should ignore the event.

More examples

Here are some additional examples to demonstrate how to take advantage of a single event listener.

Lists

A common pattern is to have a list of items that can be interacted with, where new items are inserted dynamically with JavaScript. If we have event listeners attached to each item, then y\our code has to deal with event listeners every time a new element is generated.

<div id="buttons-container"></div> <button id="add">Add new button</button>
let buttonCounter = 0; document.querySelector('#add').addEventListener('click', evt => {   const newButton = document.createElement('button');   newButton.dataset.number = buttonCounter;      // Make a new event listener every time "Add new button" is clicked   newButton.addEventListener('click', evt => {      // When clicked, log the clicked button's number.     document.querySelector('#clicked').textContent = `Clicked button #$  {newButton.textContent}`;   });    buttonCounter++;    const container = document.querySelector('#buttons-container');   container.appendChild(newButton); });

See the Pen
Lists: no bubbling
by Tiger Oakes (@NotWoods)
on CodePen.

By taking advantage of bubbling, we can have a single event listener on the container. If we create many elements in the app, this reduces the number of listeners from n to two.

let buttonCounter = 0; const container = document.querySelector('#buttons-container'); document.querySelector('#add').addEventListener('click', evt => {   const newButton = document.createElement('button');   newButton.dataset.number = buttonCounter;   buttonCounter++;    container.appendChild(newButton); }); container.addEventListener('click', evt => {   const clickedButton = evt.target.closest('button');   if (clickedButton != null) {     // When clicked, log the clicked button's number.     document.querySelector('#clicked').textContent = `Clicked button #$  {clickedButton.dataset.number}`;   } });

Forms

Perhaps there’s a form with lots of inputs, and we want to collect all the user responses into a single object.

<form>   <label>Name: <input name="name" type="text"/></label>   <label>Email: <input name="email" type="email"/></label>   <label>Password: <input name="password" type="password"/></label> </form> <p id="preview"></p>
let responses = {   name: '',   email: '',   password: '' };  document   .querySelector('input[name="name"]')   .addEventListener('change', evt => {     const inputElement = document.querySelector('input[name="name"]');     responses.name = inputElement.value;     document.querySelector('#preview').textContent = JSON.stringify(responses);   }); document   .querySelector('input[name="email"]')   .addEventListener('change', evt => {     const inputElement = document.querySelector('input[name="email"]');     responses.email = inputElement.value;     document.querySelector('#preview').textContent = JSON.stringify(responses);   }); document   .querySelector('input[name="password"]')   .addEventListener('change', evt => {     const inputElement = document.querySelector('input[name="password"]');     responses.password = inputElement.value;     document.querySelector('#preview').textContent = JSON.stringify(responses);   });

See the Pen
Forms: no bubbling
by Tiger Oakes (@NotWoods)
on CodePen.

Let’s switch to a single listener on the parent <form> element instead.

let responses = {   name: '',   email: '',   password: '' };  document.querySelector('form').addEventListener('change', evt => {   responses[evt.target.name] = evt.target.value;   document.querySelector('#preview').textContent = JSON.stringify(responses); });

Conclusion

Now we know how to take advantage of event bubbling and the event object to simplify complex jumbles of event handlers into just a few… and sometimes down to just one! Hopefully this article has helped you think about your event handlers in a new light. I know this was a revelation to me after I’d spent my early development years writing duplicative code to accomplish the same thing.

The post The Thinking Behind Simplifying Event Handlers appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]