How to Easily Convert Forms to PDF with Forminator and E2Pdf (For Free!)

Thanks to Forminator and E2Pdf, you can now quickly and easily generate a PDF from a form in WordPress. This makes it as simple as ever when creating agreements, contracts, certificates, licenses, and more directly from a form on your WordPress site.

Plus — it’s free!

As you’ll see, when these two get together, they form a PDF-ect team.

To kick things off, watch Forminator and E2Pdf in action in the video below. Then, once you get a glimpse of how they work together,  we’ll break-down all the information in detail throughout this article.

As you can see, Forminator and E2Pdf can deliver some amazing PDFs as easily as ever.

You should already be familiar with Forminator. He’s our popular 5-star form building plugin that can create amazing forms, quizzes, polls, registration forms, and much more in just a few clicks.

Forminator banner.
Forminator is the champ at simplifying form building.

And when it comes to PDFs, E2Pdf is another popular 5-star rated plugin that features PDF Document Viewer, PDF Document Editor, PDF Data Injector, and other awesome features.

E2Pdf banner.
E2Pdf is ready to include PDFs with your WordPress quickly and easily.

You’ll see how the combined forces of Forminator and E2Pdf can allow your users to fill out a form on your WordPress site and have it become a PDF.

If you haven’t already, download Forminator and E2Pdf. Once you have them installed and activated, you’ll be ready to follow along as we create some PDFs directly from our WordPress form.

Now, let’s walk through how to create a PDF using three different methods that include:

Additionally, at the end of this post, there’s an opportunity to get a sweet discount for E2Pdf. Though it’s free to use, there are some upgrades you can make with WPMU DEV and E2Pdf’s partnership.

Ready to get your PDF on? Let’s get started.

Automatically Generating a PDF From a Form

This method creates a PDF template based on a form that was created in Forminator. It’s a way to get started with an established form instantly, so you don’t have to start from scratch.

Clicking on Templates from the E2Pdf admin and Add New will get you started. Once clicking Add New, a pop-up will appear where you will create the PDF.

Where you add a new E2Pdf.
The PDF is ready to be made!

From here, you’ll want to give this PDF a Title, select whether it’s active or not in the Status, and change the Width & Height.

You can also choose a premade custom selection from the Size Preset dropdown regarding the size. There are options for Letter, Note, Tabloid, and more.

You can see there are quite a few options already available to you.

Also, choose a Font, Font Size, and Alignment.

Once you have the prerequisites figured out, head to the Extension dropdown. This is where the integration comes into play.

You’ll notice that E2Pdf has picked up that Forminator is installed on our WordPress site and automatically included it as an option. Cool, huh?

I premade a form on Forminator and titled it “E2PDF Test Form.” You can see I have First Name, Email Address, Phone Number, and Message as the fields in the preview below.

Forminator preview.
A preview of my Forminator form shows all the fields.

Keep the Extension on Forminator, and then you’ll choose what form you want to use in the Item dropdown.

You’ll notice my premade Forminator form “E2PDF” is an option, so we’ll select that.

The name of the form that fields will be used.
The name of the form will appear in the dropdown.

When everything is set up, hitting the Auto PDF button will take care of the rest.

The auto PDF button.
You’re one click away from a PDF.

And just like that, we now have a PDF template that is created from a form. E2Pdf takes all the input fields and places them into a template automatically.

Test template.
The template is an exact copy of the form created in Forminator.

You can check out what it looks like by hitting Preview.

Preview of PDF.
The PDF in all its glory.

Need to edit? That’s a click away by clicking the gear icon for Options.

You can also drag and drop the fields around to rearrange any way that you’d like. Additionally, if you right-click (or use two fingers to tap if you’re on a Mac) on a field, it will open up the options for:

  • Map Field
  • Hide
  • Copy
  • Cut
  • Delete
  • Properties
The various field options.
All of these options are available in each field.

The PDF Builder located on the righthand side allows you to drag and drop Fields and Objects into your PDF form.

Drag and drop any additional details that you’d like.

Again, just hit Update if any changes are made, and you’ll be all set!

You’ll notice then that your new PDF for the form is in the Templates section of E2Pdf’s admin. From here, you can open it up, see if it’s active or not, and get the Shortcode for it (which I’ll be discussing soon).

Templates in admin.
The new template in the admin area.

Now that we’ve looked at how to generate a PDF from a form automatically let’s move on to…

Using a Premade PDF

Another way of creating a PDF from a form is by using a premade template and simply mapping data to the fields in it.

You’ll want to add a new PDF template by going to Templates > Add New. Then, title it, and include the settings you’ll want (e.g. width, font, etc.).

Make sure Forminator is selected as the Extension and choose the form used to add in all of the data.

Next, we’ll click Upload PDF, and we’ll select a PDF we want to upload as a template.

Upload PDF button.
Once you click upload, you can choose a file from anywhere.

Once uploaded, it shows up in the admin. In this example, I created one called “Another Example.”

PDF set up in Word.
You can see, I set this up like a contract.

Currently, none of the form fields are mapped on the template. Changing that is a breeze. All you have to do is add them manually from the PDF Builder — just like I showed in the previous example.

Fields you can place in the PDF.
Place the fields wherever you’d like!

As you can see, I added several input fields and a signature field.

Example of the new PDF.
My new PDF form has all of the fields now included.

Now, to choose how the data is stored in the form on Forminator, all you do is right-click (or use two fingers on a Mac) on the field and select Map Field. You’ll then click on the field in Forminator’s form for whatever selection you want.

All the data is quick and accessible to input.

Do this for every field that you want to include on the form and PDF.

If you’re happy with everything after hitting preview, just click Update and save your changes. It’s that easy!

The final method of creating a form that translates into a PDF is the…

Creating a PDF from the PDF Builder to Design a Template

This method creates a template by just using the PDF Builder. Like the other ways of creating PDFs, it’s fast and straightforward to set up.

You’ll start by going to Templates and Add New for a new template. As I previously demonstrated, name it and choose the settings that suit your needs.

Make sure Forminator is selected in Extensions, and choose a form that you’d like to use from the dropdown menu.

This time around, we will click the Empty PDF button because we will completely design this template.

Empty PDF button.
We’re going to start from scratch with this one.

Once clicking Empty PDF, it takes you to — you guessed it — an empty PDF page.

PRO TIP: When doing this, write everything down that you want to include on your PDF. That way, you don’t miss anything, and you can ensure that your PDF design is precisely how you want it before you start putting it together.

Once you know what you’d like to include, you can map all of the blank PDF fields by dragging items from the PDF Builder. Then, right-click (or use two fingers on a MacBook) to Map Field to the form inputs on the Forminator form.

Mapped PDF.
You can even add a company logo as an image.

As always, you can preview it. Once it looks good, click Save, and you’re all set!

How Users View, Receive and Download PDFs

The way users view, receive, and download PDFs all begins with shortcodes. Then, depending on where you add them, users can download, view, or save the PDF.

Each time you create a new template, it creates a shortcode accessible in the admin under Templates and each template. When clicking on Shortcodes, a dropdown appears that has several to choose from.

Shortcodes for the PDFs.
You can see the variety of shortcodes available in the dropdown.

Copy and paste a shortcode of your preference. Then, we’ll head into the form settings in Forminator.

From here, you’ll click on the form that you want and select Edit and then Behavior.

We’re going to add this shortcode to the inline message that appears after the form submission. I’ll also add a little note beforehand. This particular shortcode that I copied is to save the PDF.

Submission Behavior section.
Your user is now all set to save the PDF.

Additionally, after a user submits a form, they can receive an email. I’ll set up an Attachment option for the PDF that the user will receive.

Then, just copy the Attachment shortcode…

The attachment shortcode.
It’s the first shortcode on the top.

Go into Forminator, Email Notifications, and Add Notification (or edit, if you already have one set up). Finally, paste the shortcode that the user receives with your message.

Where you set up an email notification.
The shortcode in the message is all ready to go!

After a user submits a form, they’ll get an email notification with the PDF attachment. Here’s what this example email looks like:

How the PDF looks in the email.
As you can see, the PDF is ready to download.

When the user downloads the PDF, it will show exactly what was submitted on the form that the user filled out.

The downloadable PDF.
Here’s the example I used.

This is a great way to provide contracts, quotes, or any form to your user and yourself — all in an easy and accessible way via PDF.

E2Pdf Plus Forminator Form a Great Team

As you can see, E2Pdf teaming up with Forminator makes creating a PDF based on a form a reliable way to provide PDFs directly from your WordPress site.

There’s an endless amount of combinations you can create when it comes to forms that create PDFs. E2Pdf free version allows for one active page template at a time. That might be fine, depending on what you’re using Forminator and E2Pdf for.

However, if you need more templates than just one, be sure to take advantage of a special 20% discount for E2Pdf on our partners’ page.

And now, you should have the perfect PDF solution for you and your users!

Parse error: syntax error, unexpected ‘:’, expecting ‘)’

the issue is with line 8, I can't work out where to put the bracket/s

<?php 
defined('APPLICATION_PATH') || define('APPLICATION_PATH',realpath(dirname(__FILE__) . '/../app'));
const DS = DIRECTORY_SEPARATOR;
require APPLICATION_PATH . DS .'config' . DS . 'config.php';

//index.php?page=

$page = get (name:'page', def: 'home');

$model = $config['MODEL_PATH'] . $page . '.php';
$view  = $config['VIEW'] . $page . '.phtml';
$_404  = $config['VIEW'] . $page . '.phtml';

if(file_exists($model))
{
    require $model;
}

$main_content = $_404;

if(file_exists($view))
{
    $main_content = $view;
}


include $config['VIEW'] . $page . 'navbar.phtml';

Editor Plus 2.6 Adds Block Pattern and Template Library

A couple of weeks ago, Munir Kamal released version 2.6 of his Editor Plus WordPress plugin. The latest version does not add a slew of features as its users have seen in the past. However, it introduces one major upgrade. The new version lets users insert templates from Gutenberg Hub’s growing library directly from the block editor.

I first asked Kamal whether he would include a template inserter in his plugin in July 2020. “I will possibly include a direct inserter for templates and blocks in the Editor Plus plugin,” he said at the time, not giving away too much.

He had just launched Gutenberg Hub’s block library (really, something more akin to block patterns). The system was useful but far from perfect. Users could copy a JSON code snippet and import it via Editor Plus. This was a slight improvement over copying separate block HTML and CSS snippets from an earlier iteration of a block template system he had launched last March. It was still not an ideal system, but anyone paying attention could see the possibilities.

Over the months since that launch, Kamal continued to build more tools into Editor Plus. He launched a separate landing page template directory. And, he continued adding more items to Gutenberg Hub’s library.

“I am already working on adding a Template Inserter in my EditorPlus plugin,” he said when we talked in September. “It will allow users to browse and insert these templates directly from Gutenberg without leaving the website.”

I had already been hounding him for months, and he knew that I would ask. He was looking for feedback, not wanting to push something out before he felt that it worked.

“Earlier, I created a template inserter similar to other blocks plugins, but later I changed my mind and thought that I should integrate with the Gutenberg Patterns API and load the templates into the ‘patterns’ panel in the block inserter,” he said. “But, I am having a few issues and thinking about going back to the original idea to have a Templates button on the top toolbar that opens a popup window to browse and filter templates that users can insert on a click.”

It was an almost methodical process toward building a massive body of work in a year. As is often the case with Kamal’s work, he quietly pushed out version 2.6 of his plugin. Even without much fanfare, he has managed to surpass 4,000 active installs, doubling its number in the past few months.

Now all of the plugin’s users have direct access to Gutenberg Hub’s section patterns and landing page templates.

The Template Library

Editor Plus 2.6 adds a new “Library” button to the block editor’s post header toolbar. It pops up a simple overlay of the plugin’s layout choices.

Users can insert a “Pattern” or a “Template,” as they are called through the plugin’s UI. Patterns are pre-designed sections that end-users can use to piece together larger page layouts. Templates are full-blown page designs, ready for deployment after content customization. Many of the patterns are present in the templates. It all comes down to how users want to build their pages — piecemeal vs. having everything in place.

Editor Plus plugin's library popup modal.
Modal showing block templates.

Of course, everything is editable. Users can insert a template then proceed to removing the bits they do not need and adding custom blocks of their choosing.

The overlay that appears after clicking the Library button allows users to select a pattern or template. This method is becoming increasingly common among block-related plugins. Where the Gutenberg project has fallen behind in its patterns UI, plugin authors are filling the gaps and creating better user experiences. Genesis Blocks, for example, adds a similar overlay for choosing layouts. Patterns, templates, layouts, or whatever-you-want-to-call-them all need room to breathe instead of being relegated to a width-restrained flyout. What makes sense on mobile does not always create an ideal experience on larger screens.

Selecting a photography-related template via the Editor Plus WordPress plugin.
Viewing a photography template.

Once a user finds a pattern or template to insert, they can click on it to view a larger version. If they are satisfied, they merely need to click the “Add” button to insert it into the content canvas.

An important caveat is that what you see in the library is not exactly what you will get. The library uses screenshots to showcase the patterns and templates. These images are created while using a different theme than what a particular user has installed on their site. Things like fonts will match whatever theme is installed. Generally speaking, the overall designs should match up fine.

In the future, perhaps Editor Plus will handle the pattern and template previews with live instances instead of screenshots.

Inserting a food-related template from Editor Plus into the block editor.
Cafe-type full landing template.

The plugin breaks its library down into 15 categories, such as Arts & Entertainment, Photography, and Real Estate. It is almost a bit excessive. Some contain only one or two templates. Combining categories like Home Services, Professional Services, and Retail into an all-encompassing Business group could help curb the dizzying effects of too much choice.

The new library in Editor Plus 2.6 is a welcome addition. Overall, it worked well in testing.

Elementor Raises Eyebrows with Google Ads Targeting Full-Site Editing

WordPress’ growing market share is fueling a continual influx of new users but also a higher level of scrutiny around advertising. Companies with large advertising budgets target this segment of consumers, because many who are new to WordPress need help hosting and creating their websites.

Last week Bluehost pulled an advertisement that misused WordPress’ trademark. The company’s PR department has not responded to our request for comment, but onlookers have noted that this isn’t the first time Bluehost has floated questionable ads. Multiple Facebook campaigns, dating back several years, include trademark abuses, as well as active campaigns on YouTube in various markets.

In another advertising-related matter, Elementor, a popular page builder used by more than five million websites, has caught some attention recently for its Google ads that target “full-site editing.” Birgit Pauli-Haack, publisher of the Gutenberg Times, pointed out the ads last week in the Post Status Slack community.

“I have no trouble if Elementor and Beaver Builder duke it out on the Google Ads,” Pauli-Haack said. “It’s certainly fair game. Why I think it’s shady in regards to WordPress? It’s the searcher’s intent diverted, in a misleading way. 30% of Google Searchers do not know that the first results are paid ads and are led astray. Information about Full Site Editing has people already confused and worried. It doesn’t help if someone hijacks the new feature’s keyword. WordPress is also an easy target because the Foundation certainly doesn’t have any money to throw at the problem to bid higher on the keywords.”

At first glance the keyword targeting may appear to skirt the line of ethical advertising, but Elementor representative Ben Pines claims the company is simply advertising for a feature set of the same name. It enables customers to edit the header, footer, archive and single templates, and page or post content on the same screen.

“Our google ads vary to provide the most value for users in the search,” Pines said. “This one is no different. This doesn’t represent any new strategy. We released full site editing back in March 2020.”

Pines referenced a beta release post dated March 1, 2020, which referred to Elementor’s “groundbreaking Full Site Editing feature.” WordPress’ Full-Site Editing project predates this release by at least a year.

“Full site editing is a very generic industry name and is a fundamental capability in website building tools, searched by many of our users,” Pines said.

When asked if Elementor is considering changing the name to avoid confusion with the core WordPress project, Pines said, “We don’t see any potential confusion. Elementor’s capabilities and ads are clear.”

Others involved in the conversation on Post Status Slack said this type of advertising seems to be standard practice in the world of ad buying, since they are buying based on relevant keywords. Competitors also routinely purchase each other’s keywords.

“Instead of supporting, it is undermining the project,” Pauli-Haack said.

She and other participants in the conversation about the ads found it hard to believe that the strategy is not intentional. Some were also irked by other Elementor ads running on Google and Facebook that attempt to capitalize on users’ frustration with WordPress.

Elementor’s advertising appears to be a self-preservation strategy, as Gutenberg’s full site editing capabilities will inevitably ring the death knell for page builders that don’t build on top of the core standard. Third-party page builders will need to overcome severe performance deficiencies in order to remain competitive.

Understanding where full-site editing is heading is critical for WordPress site owners who are adopting new tools and workflows that will be future-proof with core changes. During this transition many will likely be googling for solutions that will enable them to be on the ground running when core introduces its full-site editing MVP in WordPress 5.8.

Participants in the conversation noted that the Elementor team is not very involved in contributing to the open source project. This may be why the team claims they cannot see any confusion in targeting Google ads at users searching “full-site editing.”

“We actively contribute to WP and its ecosystem through sponsoring events, translations, accessibility tools and more,” Pines said. “We are looking to further our contribution even more this year and are on the look out for a dedicated team member.”

Privacy Toggle in Context Menu

It used to be that in order to change a Pen, Project, or Collection from public to private (or vise versa), you had to open it directly and edit it there. Now, you can make that change from anywhere you see them in grid, be it in the Your Work section, your profile, or anywhere else you see something you own.

If you have a bunch of things you need to toggle, this should be much faster, particularly in list view.

Privacy is a PRO feature, so if you aren’t PRO, you’ll see a message like this:

The post Privacy Toggle in Context Menu appeared first on CodePen Blog.

The “Gray Dead Zone” of Gradients

Erik D. Kennedy notes an interesting phenomenon of color gradients. If you have a gradient between two colors where the line between them in the color space goes through the zero-saturation middle, you get this “gray dead zone” in the middle.

It’s a real thing. See the gray middle here:

You can also see how colors might not do that, like red and blue here shooting right through purple instead, which you can visualize on that color circle above.

Erik says one solution can be taking a little detour instead of going straight through the gray zone:

His updated gradient tool deals with this by using different “interpolation modes” and easing the gradient with a choice of precision stops. Don’t miss the radial and conic options as well, with the ability to place the centers “offscreen” which can yield pretty cool looks you can’t do any other way.


Oh and speaking of conic gradients, Adam Argyle has a little gallery of possibilities that is pretty unique.


The post The “Gray Dead Zone” of Gradients appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Creating a Formal API Program With James Higginbotham

The year 2020 saw an unprecedented and transformative shift for the IT industry. The lockdowns forced us all to shut down our offices and work from home, which called for IT departments everywhere to rise to the occasion and use technology to become more agile, responsive, and resilient.

As we reach the end of the year, it becomes vital for us to look at how digital transformation is currently being implemented within organizations, and what businesses are doing to improve their IT infrastructure in 2021 and beyond.

How to Map Mouse Position in CSS

Let’s look at how to get the user’s mouse position and map it into CSS custom properties: --positionX and --positionY.

We could do this in JavaScript. If we did, we could do things like make make an element draggable or move a background. But actually, we can still do similar things, but not use any JavaScript!

I’ve used this method as a part of a demo I’ve made for getting a ‘Click and drag’ effect with pure CSS. I used the perspective tips from my pervious article. It’s a pretty neat effect to get this done entirely in CSS, which might have wider usefulness than my demo, so let’s take a look.

The setup

Our first demo is going to use --positionX and --positionY custom properties to set the width and height of an element.

Heads up that we’re only using SCSS here for brevity, but all of this can be done in pure CSS.

This is our initial state. We have here a ‘wrapper’ <div> with a .content class of that is spread to the width and height of the body. This <div> will host the content of our project, and the elements we want to control using the mouse position – in this case, the .square element.

We’ve also added the two custom-properties to the content. we will use the mouse position to set the value of these properties, and then use them set the .square element’s width and height accordingly.

Once we have mapped the custom properties for mouse position, we can use them to do pretty much anything we want . For example, we could use them to set the top / left properties of an absolute positioned element, control a transform property, set the background-position, manipulate colors, or even set the content of a pseudo-element. We’ll see some of these bonus demos at the end of the article.

The grid

The goal is to create an invisible grid on the screen, and use the :hover pseudo-class to map each ‘cell’ to a set of values that we will allocate to the custom properties. So, when the mouse cursor moves to the right side of the screen, the value of the --positionX will be higher; and when it moves to left, it gets lower. We’ll do the same with --positionY: the value will be lower as the cursor moves to the top, and higher when it moves to the bottom.

A few words about the grid size we’re using: We can actually make the grid whatever size we want. The larger it is, the more accurate our custom property values will be. But that also means we will have more cells, which can lead to performance issues. It’s important to maintain proper balance and adjust the grid size to the specific needs of each project.

For now, lets say that we want a 10×10 grid for a total of 100 cells in our markup. (And yes, it’s OK to use Pug for that, even though I won’t in this example.)

<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<!-- 97 more cells -->

<div class="content">
  <div class="square"></div>
</div>

You’re probably wondering why the .cell elements come before the .content. That’s because of the cascade.

We want to use the .cell class to control the .square, and the way the cascade works (for now) is that an element can only control its children (or descendants) and its siblings (or their descendants) — but only as long as the sibling is after the controlling element.

That means two things:

  1. Each .cell must come before the element we want to control (in this case, the .square).
  2. We can’t put those .cells in a container, because if we do, the .content is no longer their sibling.

Positioning the cells

There are a few ways to position the .cells. we can position: absolute them and offset them with the top and left properties. Or we can translate them into position using transform. But the easiest option is likely using display: grid.

body {
  background-color: #000;
  height: 100vh;
  display: grid;
  grid-template: repeat(10, 1fr) / repeat(10, 1fr);
}

.cell {
  width: 100%;
  height: 100%;
  border: 1px solid gray;
  z-index: 2;
}
  • The border is just temporary, so we could see the cells on the screen. we’ll remove it later on.
  • the z-index is important, because we want the cells to be in front of the content.

Here’s what we have so far:

Adding values

We want to use .cell to set the --positionX and --positionY values.

When we hover over a .cell that is in the first (left) column, the value of --positionX should be 0. When we hover over a .cell in the second column, the value should be 1. It should be 2 in the third column, and so on.

The same goes for the y-axis. When we hover over a .cell that is in the first (top) row, --positionY should be 0, and when we hover over a cell in the second row, the value should be 1, and so on.

A black ten by ten grid of squares with white borders and numbers in sequential order from left to right.

The numbers in this image represent the numbers of the cell elements in the grid. If we take just a single .cell as an example — let’s say cell 42 — we can select it using :nth-child():

.cell:nth-child(42) { }

But we need to remember a couple of things:

  1. We only want this selector to work when we hover over the cell, so we will attach :hover to it.
  2. We want to select the .content instead of the cell itself, so we’ll use the General Sibling Combinator (~) to do that.

So now, to set --positionX to 1 and --positionY to 3 for .content when the 42nd cell is hovered, we need to do something like this:

.cell:nth-child(42):hover ~ .content {
  --positionX: 1;
  --positionY: 3;
}

But who wants to do that 100 times!? There are a few approaches to make things easier:

  1. Use a Sass @for loop to go through all 100 cells, and do some math to set the proper --positionX and --positionY values for each iteration.
  2. Separate the x- and y-axes to select each row and each column individually with :nth-child’s functional notation.
  3. Combine those two approaches and use a Sass @for loop and :nth-child functional notation.

I thought long and hard about what would be the best and easiest approach to take, and while all of then have pros and cons, I landed on the third approach. The amount of code to write, the quality of the compiled code, and the math complexity all went into my thinking. Don’t agree? Tell my why in the comments!

Setting values with a @for loop

@for $i from 0 to 10 {
 .cell:nth-child(???):hover ~ .content {
    --positionX: #{$i};
  }
  .cell:nth-child(???):hover ~ .content {
    --positionY: #{$i};
  }
}

This is the basic loop. We’re going over it 10 times since we have 10 rows and 10 columns. And we’ve separated the x- and y-axes to set --positionX for each column, and the --positionY for each row. All we need to do now is to replace those ??? things with the proper notation to select each row and column.

Let’s start with the x-axis

Going back to our grid image (the one with numbers),We can see that the numbers of all the cells in the second column are multiples of 10, plus 2. The cells in the third column are multiples of 10 plus 3. And so on.

Now let’s ‘translate’ it into the :nth-child functional notation. Here’s how that looks for the second column:

:nth-child(10n + 2)
  • 10n selects every multiple of 10.
  • 2 is the column number.

And for our loop, we will replace the column number with #{$i + 1} to iterate sequentially:

.cell:nth-child(10n + #{$i + 1}):hover ~ .content {
  --positionX: #{$i};
}

Now lets deal with the y-axis

Look again at the grid image and focus on the fourth row. The cell numbers are somewhere between 41 and 50. The cells in the fifth row are between 51 to 60, and so on. To select each row, we’ll need to define its range. For example, the range for the fourth row is:

.cell:nth-child(n + 41):nth-child(-n + 50)
  • (n + 41) is the start of the range.
  • (-n + 50) is the end of the range.

Now we’ll replace the numbers with some math on the $i value. For the start of the range, we get (n + #{10 * $i + 1}), and for the end of the range we get (-n + #{10 * ($i + 1)}).

So the final @for loop is:

@for $i from 0 to 10 {
 .cell:nth-child(10n + #{$i + 1}):hover ~ .content {
    --positionX: #{$i};
  }
  .cell:nth-child(n + #{10 * $i + 1}):nth-child(-n + #{10 * ($i + 1)}):hover ~ .content {
    --positionY: #{$i};
  }
}

The mapping is done! When we hover over elements, --positionX and --positionY change according to the mouse position. That means we can use them to control the elements inside the .content.

Handling the custom properties

OK, so now we have the mouse position mapped to two custom-properties, The next thing is to use them to control the .square element’s width and height values.

Let’s start with the width and say that we want the minimum width of the .square to be 100px (i.e. when the mouse cursor is at the left side of the screen), and we want it to grow 20px for each step the mouse cursor moves to the right.

Using calc(), we can do that:

.square {
  width: calc(100px + var(--positionX) * 20px);
}

And of course, we’ll do the same for the height, but with --positionY instead:

.square {
  width: calc(100px + var(--positionX) * 20px);
  height: calc(100px + var(--positionY) * 20px);
}

That’s it! Now we have a simple .square element, with a width and height that is controlled by the mouse position. Move your mouse cursor over the window, and see how the square changes its width and height accordingly.

I added a small transition to make the effect smoother. That’s not required, of course. And I’ve also commented out on the .cell border.

Let’s try an alternative method

There might be a case where you want to ‘bypass’ --positionX and --positionY, and set the end value directly inside the @for loop. So, for our example it would look like this:

@for $i from 0 to 10 {
 .cell:nth-child(10n + #{$i + 1}):hover ~ .content {
    --squareWidth: #{100 + $i * 20}px;
  }
  .cell:nth-child(n + #{10 * $i + 1}):nth-child(-n + #{10 * ($i + 1)}):hover ~ .content {
    --squareHeight: #{100 + $i * 20}px;: #{$i};
  }
}

Then the .square would use the custom properties like this:

.square {
  width: var(--squareWidth);
  height: var(--squareHeight);
}

This method is a little more flexible because it allows for more advanced Sass math (and string) functions. That said, the general principle is absolutely the same as what we already covered.

What’s next?

Well, the rest is up to you — and the possibilities are endless! How do you think you’d use it? Can you take it further? Try using this trick in your CSS, and share your work in the comments or let me know about it on Twitter. It will be great to see a collection of these come together.

Here are a few examples to get your hamster wheel turning:


The post How to Map Mouse Position in CSS appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

State Of GDPR In 2021: Cookie Consent For Designers And Developers

Last week, I gave you an update on everything that’s happened with GDPR since 2018. (TL;DR: A lot has changed.) In this article, we’ll look at cookie consent: specifically, the paradox where marketers are heavily reliant on Google Analytics cookie data but need to comply with regulations.

We’ll take a look at two developments that have impacted cookies, plus a third on the horizon. Then I’ll walk you through the risk-based approach that we’ve taken — for the moment, at least. And come back next time for a deep dive into first-party ad tracking as we start to see moves away from third-party cookies.

Big Development #1: Cookie Consent

In May 2020, the EU updated its GDPR guidance to clarify several points, including two key points for cookie consent:

  • Cookie walls do not offer users a genuine choice, because if you reject cookies you’re blocked from accessing content. It confirms that cookie walls should not be used.
  • Scrolling or swiping through web content does not equate to implied consent. The EU reiterates that consent must be explicit.

What does this mean for our industry?

Well, the EU is tightening up on cookie consent — perhaps the most noticeable (and annoying!) aspect of GDPR. Critics say that cookie notices are a cumbersome block for users, and don’t do anything to protect user privacy. The EU is trying to change this, by promoting simple, meaningful, equitable options for cookie consent.

But that restricts what we can do with cookies, and it hints ahead to when the Privacy and Electronic Communications Regulation (PECR) may come into force. More on that shortly.

Big Development #2: Google and Apple crack down on third-party tracking; get hit by anti-trust complaints

As the big digital players figure out how to comply with GDPR — and how to turn privacy legislation to their advantage — some have already come under fire.

Google is being investigated by the UK’s competition watchdog, the Competition and Markets Authority (CMA), for its ‘Privacy Sandbox’ initiative, following complaints from adtech companies and publishers.

The Internet giant, which is also facing an antitrust investigation in Italy for display advertising, and in the US for its search advertising services, is looking to remove third-party cookies from Chrome. (Firefox and Safari already block these cookies by default.)

The complainants say that this change will further concentrate advertising revenue in Google’s hands. Google’s response? The advertising industry needs to make ‘major changes’ as it shifts to a ‘web without third-party cookies’.

Google’s not alone. In October 2020, four French digital advertising lobbies filed an antitrust suit against Apple’s forthcoming iOS privacy change, a feature it’s called App Tracking Transparency (ATT).

ATT, coming in an early-spring 2021 release of iOS 14, shifts app users from an opt-out to an opt-in ad-tracking model. With ATT, every app must get your permission to share your Identifier for Advertisers (IDFA), which enables third-party ad tracking across multiple sites and channels.

The complainants say that by restricting apps’ ad revenue, developers may have to boost app subscriptions and in-app purchases or switch to Apple’s targeted ad platform — all of which will funnel ad spend away from them and towards Cupertino.

Critics including Facebook have slammed the change, saying it’ll hit small businesses who rely on microtargeted ads. Apple has defended the move and praised the EU’s defence of citizens’ data privacy.

To sum up:

  • Implied consent doesn’t equal consent under GDPR, according to the EU.
  • We should also avoid cookie walls
  • Google and Apple are moving against third-party cookies — which some say exploits their dominant market position.

So what does that mean for us, as designers and developers? First, let’s take a look at why this is important.

Here’s What Designers Should Know About Cookies

  • GDPR is critical for you because you’ll design the points at which cookies are placed, what data is collected, and how it’s processed.
  • A functionality audit means you can map your cookie activity in the data and compliance layers on your service blueprint.
  • It can help to do a cookie audit and gap analysis, i.e. is the existing cookie pattern compliant? What content does it need around it?
  • Follow Privacy by Design best practices. Don’t try to reinvent the wheel — if you’ve created a compliant cookie banner, use your proven design pattern.
  • Work with your compliance and development teams to ensure designs meet GDPR and can be implemented. Only ask for the data you need.
  • If you need to compromise, take a risk-based approach. There’s a walk-through of one that we did further down.
  • Be aware that your content team may need to update your privacy policy as GDPR and your use of cookies evolve.

Here’s What Developers Should Know About Cookies

  • Make sure you’re involved upfront about cookie consent and tracking, so what’s decided can be implemented.
  • If you’re doing a product or website redesign, a cookie audit using Chrome Dev Tools can show you what tracking cookies are being used. Tools like Ghostery or Cookiebot give you more detail.
  • You should implement the standard cookie opt in/out as per GDPR guidance. (Note that while GDPR is standard, the enforcement of it varies across EU countries. There’s more on this further down.) You may stand to lose Google Analytics data. You might also come under pressure to implement things that could be considered as dark patterns. There’s more on this later, with a walk-through of what we did and a look at the risk.

So that’s where we are today. Oh, and there’s one more thing to be aware of: a piece of further legislation that might be coming our way. I like to call it Schrodinger’s Law.

Schrodinger’s Law: The ePrivacy Regulation

You may have heard of GDPR’s twin sister, the ePrivacy Regulation, who’s lurking on the legislative horizon. If you haven’t, here’s an introduction.

As I said above, cookie consent — the notice that pops up when you visit a website — is regulated by the GDPR. However, cookies themselves fall under a different piece of legislation, the ePrivacy Directive of 2002, commonly known as the Cookie Law. Like GDPR, it aims to protect customer privacy.

The ePrivacy Directive is due to be replaced by more stringent legislation, the ePrivacy Regulation. (If you’re interested in the difference between EU directives and regulations, EU directives set out the goals for legislation but delegate the implementation of those goals to member states’ legislatures. EU regulations mandate both the goals and the implementation at an EU-wide level.)

The draft ePrivacy Regulation goes beyond cookies and ad tracking. It applies to all electronic communications, including messaging apps, spam mail, IoT data transfer and more.

The draft ePrivacy Regulation was first presented by the EU in 2017. However, it has to be agreed by both the European Parliament and the Council of the European Union. (The Council consists of government representatives of each EU member state.)

This is where it gets messy. Since 2017, the European Parliament and the Council haven’t been able to agree on the scope and detail of the ePrivacy Regulation.

That’s because some countries — widely thought to include the Nordic states of Finland and Denmark — want to strengthen the current ePrivacy Directive. They want users, for example, to be able to set acceptance and rejection of tracking cookies in their browsers, not on every site they visit.

But other countries, notably Austria and believed also to include those with sizeable digital marketing and advertising sectors, say this is bad for business. It’s thought the 27 EU member states are split down the middle on this issue — and they’re all being heavily lobbied by the tech industry.

So the draft regulation has been ricocheting back and forth between the European Commission and its Working Party on Telecommunications and Information Society as they try to agree its scope. In November 2020, the Working Party rejected the redrafted legislation once again.

What happens next? There are two possibilities. Either a compromise will be reached, in which case the legislation will be agreed. Because it takes time for legislation to be implemented, the soonest the ePrivacy Regulation could become law is 2025.

Alternatively, the legislation cannot be agreed and is withdrawn by the European Commission. But the EU has staked so much on it. It will be extremely reluctant to take that step.

That’s why I call it Schrodinger’s Law. It’s hard for us to know how to plan for any cookie-related developments because we simply don’t know what’s happening.

So what should I do about cookies right now?

Different EU countries are currently implementing the ePrivacy Directive differently. Over in the UK, the ICO (the UK’s data protection authority) is taking a tough stance. It’s requiring strict consent for analytics cookies, for example, and has spoken out against cookie walls.

Until — and if — we get consistency from a new ePrivacy Regulation, if you’re based in an EU country, start by following the advice from your national Data Protection Authority. Then watch this space for developments around the ePrivacy Regulation.

If you’re based outside the EU, make sure you’re giving EU citizens the options required under the GDPR and the ePrivacy Directive.

However, when it comes down to the detail, there are times when I recommend taking a risk-based approach. That’s what we’ve done at Cyber-Duck — and here’s why.

Here’s our original cookie notice. You see these everywhere. They’re pretty meaningless — users just hit accept and continue on their way.

But we wanted to be compliant, so we replaced it with this notice. You’ll see that tracking cookies are turned off by default — in line with ICO guidance. We knew there was a risk we would lose analytics data as GTM would no longer fire on first load.

Let’s see what happened.

Problem solved? Actually, no. It just created another problem. The impact was far more significant than we expected:

Look at the collapse in the blue line when we implemented the new cookie notice. We released the new cookie consent on 17 December and went straight from plenty of tracked traffic to almost zero. (The orange line shows the previous year’s traffic, for comparison.)

In both the before-and-after scenarios, the default option was by far the most popular. Most users just naturally click on “accept” or “confirm”. That’s tricky, because we now know so little about the people visiting our site that we can’t give them the best information tailored to their needs.

We needed a solution. Analytics and marketing data ultimately drive business decisions. I’m sure we all know how important data is. In this case, it was like putting money in a bank account and not knowing how much we’d spent or saved!

Some of the solutions that were posed include design alternatives (would removing the toggle, or having two buttons with a visual nudge towards the “accept” help?) Or would we enable analytics cookies by default?

For now, we’ve implemented a compromise position. Marketing and analytics cookies are on by default, with one clear switch to toggle them off:

And here’s what that’s done to our stats:

The new cookie banner was relaunched on 15 January. You can see our website traffic starts to pick back up again. However, we’re not getting the full data we were getting before as Google Tag Manager doesn’t fire unless a user chooses cookies.

The good news is, we are getting some data back again! But the story doesn’t end here. After we had turned cookie tracking back on by default, the attribution model got messed up. It wasn’t attributing to the correct channel in Google Analytics.

Here’s what we mean:

Scenario 1: (Correct Attribution)

  1. User lands on our website via a paid ad (PPC) or from the search result (organic)
  2. User accepts cookies straight away.
  3. The channel source is attributed correctly, e.g. to PPC.

Scenario 2: (Incorrect Attribution)

  1. User lands on our website via a paid ad (PPC) or from the search result (organic)
  2. User visits a few other pages on our website without responding to the cookie banner prompt (banner appears on every page until it gets a response)
  3. User finally accepts cookie banner after browsing a few pages.
  4. Attribution comes through as direct — although they originally came from a search engine.

How does that work? When a user browses other pages on the site, nothing is tracked until they respond to the cookie prompt. Tracking only kicks in at that point. So to Google, it looks as though the user has just landed on that page — and they are attributed to Direct traffic.

Back to the drawing board.

Note: I’m sure by now you’re starting to see a pattern here. This entire experience is new for us and there’s not a lot of documentation around, so it’s been a real learning curve.

Now, how could we solve this attribution issue and stop users from navigating around the site until they’ve selected their cookie preference?

A cookie wall is one option we considered, but that would potentially push us further away from being compliant, according to the ICO. (Though you might like to try browsing their site incognito and see if they stick to their own guidance...)

But that’s what we’ve chosen to go with. The journey ends here for now, as we’re still gathering data. In the future, we want to explore other tools and the potential impact of moving away from Google Analytics.

So what’s everyone else doing?

Well, McDonald’s UK offers straightforward on/off buttons:

Coca Cola’s British site nudges you to accept by making the ‘reject’ option harder to find:

Whereas Sanrio just has an option to agree to ad tracking:

Hello Kitty, hello cookies.

Die Zeit offers free access if you accept tracking cookies — but for an untracked, ad-free experience you’ll have to pay:

And here’s one of my favourite dark patterns. This restaurant site only has the ‘Necessary’ cookies selected. But it nudges you to the ‘Allow all cookies’ big red button — and when you click that, the analytical and ad cookie boxes are automatically checked and set. Give it a go here!

Even the EU isn’t consistent on its own sites.

The European Parliament’s cookie consent offers two clear options:

The CJEU’s site isn’t so clear:

While Europol’s site comes with two pre-checked boxes:

And if you look at the sites for the German presidency of the Council of the European Union (July–December 2020), at first it seems as if there’s no cookies at all:

When you land on the site, there are no cookie banners or prompts. A closer look, with cookie extension tools, shows that no cookies are being placed either.

So are they capturing any analytics data? The answer is yes.

We found this little snippet in their code, which shows they are using ‘Piwik’. Piwik is now known as Matomo, one of a clutch of new tools that help with cookie compliance along with Fathom (server-side tracking) and HelloConsent (cookie management).

So alternatives and solutions are emerging. We’ll take a closer look at that next time — with new alternatives to third-party cookies that will help you take control of your data and get the insight you need to deliver optimum experiences to your customers. Stay tuned!

Further Reading

Business optimisation architecture – Common architectural elements

In my previous article from this series I introduced a use case around business optimisation for retail stores. 
The process was laid out how I've approached the use case and how portfolio solutions are the base for researching a generic architectural blueprint.
The only thing left to cover was the order in which you'll be led through the blueprint details.

This article starts the real journey at the very top, with a generic architecture from which we'll discuss the common architectural elements one by one.

Blueprints review

As mentioned before, the architectural details covered here are base on real solutions using open source technologies. The example scenario presented here is a generic common blueprint that was uncovered researching those solutions. It's my intent to provide a blueprint that provides guidance and not deep technical details.

Software Distribution Tactics to Win at DevOps

Deployment frequency is considered one of the finest DevOps metrics, and the elite performers in DevOps space deploy multiple times per day with confidence. The deployment process requires systems that promote trust between teams (Dev or Ops) throughout the pipelines- so they can ensure they’re using the latest builds for testing, approved binaries for deploying, etc. This involves managing artifacts between the developers, so they get the latest of everything to deploy and make the software ready, no matter if the team is in the same room or is working remotely.

The ability to continuously integrate and release application updates to any deployment target has become crucial to any business's success.