Joomla Blocks FLoC by Default, Drupal Moves to Block FLoC in Upcoming 9.2 Release

Joomla has announced plans to block Google’s Federated Learning of Cohorts (FLoC) by default going forward. The 3.9.2.7 security update, released yesterday, added a Permissions Policy header to disable FLoC. Users can now find a new setting in Global configuration on the Site tab in the Site Settings area, where they can toggle FLoC on if desired. This change will also affect existing sites updated from older versions.

The Joomla Developer Network blog outlined a few concerns contributors have about fingerprinting, the technology Google uses to gather information from a user’s browser to create a unique, stable identifier. They also highlighted cross-content exposure as another concern:

The technology will share new personal data with trackers who can already identify users. For FLoC to be useful to advertisers, a user’s cohort will necessarily reveal information about their behavior.
This means every site you visit will have a good idea about what kind of person you are on first contact, without having to do the work of tracking you across the web.
If you visit a site to buy a jumper they will have access to your cohort identifying number. This could also give them your political thinking or reveal that you are also in certain defined medical groups. There is nothing to stop these groups being backward engineered and your movement between the cohorts will reveal a lot about you over time.

A similar permissions policy header was added to Drupal 9.2.0-beta1 on May 14, after a lengthy discussion with overwhelming consensus to block FLoC. It is expected to be part of Drupal core on June 16, 2021, when 9.2 is scheduled to be released.

“I’d love to see this added to core and enabled by default,” Drupal founder Dries Buytaert commented on the implementation discussion. “We should provide an option/mechanism to disable it though.” He said he has already added a Permissions-Policy header on his personal blog.

Drupal makes disabling it a bit more of a hurdle than Joomla, as it requires setting block_interest_cohort to FALSE in the settings.php file.

Although FLoC is still in the experimental stage, many other frameworks and tools have blocked it or are planning to block it. The DuckDuckGo Chrome extension has been reconfigured to block FLoC’s tracking, in addition to DuckDuckGo Search opting users out. GitHub is also blocking FLoC on GitHub Pages and all sites served from the github.io domain. Although Chrome is the market leader by a wide margin, Google has not yet been able to sway any other major browsers to get on board. At this time, Microsoft Edge, Safari, and Firefox do not plan to adopt FLoC.

“It is disappointing to see Google, instead of taking the present opportunity to help design and build a user-first, privacy-first Web, proposing and immediately shipping in Chrome a set of smaller, ad-tech-conserving changes, which explicitly prioritize maintaining the structure of the Web advertising ecosystem as Google sees it,” Brave CEO and co-founder Brendon Eich and senior privacy researcher Peter Snyder wrote in a statement on the company’s blog. “The worst aspect of FLoC is that it materially harms user privacy, under the guise of being privacy-friendly.”

Brave has disabled FLoC and the company recommends that all sites do the same, advising that “any new privacy-risking features on the web should be opt-in.” The post concludes that FLoC will not be an improvement on current ad tech:

Overall, FLoC, along with many other elements of Google’s “Privacy Sandbox” proposal, are a step backward from more fundamental, privacy-and-user focused changes the Web needs. Instead of deep change to enforce real privacy and to eliminate conflicts of interest, Google is proposing Titanic-level deckchair-shuffling that largely maintains the current, harmful, inefficient system the Web has evolved into, a system that has been disastrous for the Web, users and publishers.

What the Web desperately needs is radical change, one where “would users want this?” is the most important question asked for each new feature. Instead, FLoC and “Privacy Sandbox” ask “how can we make this work for ad-tech, in a way that users will tolerate or not notice.”

The open source Umbraco CMS is taking a more hands-off approach to the controversial issue. In response to a PR suggesting suggesting Umbraco block FLoC, Umbraco project manager Sebastiaan Janssen said, “We feel it’s not our place or task to enforce this kind of blocking, we believe site implementers should be free to use whatever services they think make sense for their sites (as well as block them when they want).”

At this point in Google’s Chrome’s Origin Trial, Chrome representatives do not yet know how the FLoC API will be finalized for determining which pages will be included in FLoC calculations. WordPress has not yet made a determination about whether to block FLoC or leave it site owners to decide. Multiple FLoC blocking plugins are already available to users who want to opt out now. After a lengthy and heated discussion on a proposal to block FLoC by default, WordPress core leadership moved the conversation to Trac where contributors are monitoring Google’s experiment.

The ticket has not yet received much feedback as WordPress is taking a more cautious approach that will depend on how Google decides to implement its FLoC API. Without the support of any major browsers, WordPress’ support or opposition may be critical to the success or failure of FLoC adoption on the web. Once more information from the FLoC trial becomes available, WordPress contributors will be in a better position to decide a course of action.

FSE Outreach #7: Building a Portfolio in the Upcoming Template-Editing Mode

Feedback for round #7 of the FSE Outreach Program opened today. Like round #6, the focus is once again on template-editing mode, a feature that is slated to ship with WordPress 5.8. All hands need to be on deck for it to have a chance of a successful landing.

I have been eager for this round of testing. FSE Outreach lead Anne McCarthy asked volunteers to follow a 16-step plan for building a portfolio template. Unlike the previous six tests, this one gives users more leeway, room to explore template editing.

As usual, the base set of tools is the latest version of the Gutenberg plugin and the TT1 Blocks theme.

For my portfolio, I decided to approach it as a hypothetical photographer who wanted to drum up some new clients and show off his latest work. The following screenshot is the end result:

Example portfolio page with a cover header, projects section, testimonials, and footer.

Anyone is welcome to grab the HTML block code for this template. I saved it as a GitHub Gist. The image URLs are to my local machine, so you will need to update those if you decide to give it a spin.

I had a lot of fun with this. And frustration. Some more fun. And…you guessed it…some more frustration.

The editor and I got off to a rough start. After adding my Cover block, I wanted to add a Columns block inside. Error. The dreaded invalid block message. I switched over to the code view to see if there was anything odd. It was empty. After switching back to visual, the Columns block seemed to be working. I was able to inconsistently reproduce this issue in template-editing mode.

I used a Columns block because it is the only way that I know how to create a left-aligned container covering 50% of its containing element. It is a bit of a hack, but you can set the block to one column and adjust its width to whatever size you need. Ideally, users would be able to do this with the Group block.

It was the underpinning of my template header area. I went with the traditional hero/cover intro that spanned the width of the page.

Adding a Cover block in the WordPress template editor with inner columns.
Header section of template using Cover block.

Adding a site logo and navigation is where I hit my second snag. The navigation worked fine, mostly. On mobile, the responsive menu overlay is partially covered by the WordPress toolbar on the front end. However, I already knew this. Responsive nav menus are a work in progress.

I was unable to use the Site Logo block. Whenever I attempted to add it, it had a continual spinner icon that never went away. So, I opted for an Image block — you make do with the tools you got or the ones that are working.

Spinning site logo block with a real image underneath.
Second test of adding a site logo in different section.

The next section of template testing consisted of adding a Query pattern and customizing it. I have a love/hate relationship with queries in Gutenberg right now. The Query block itself works well. It has a solid balance between advanced usage and simplicity for the most part. I am amazed at what the development team has done over months upon months of iteration.

The downfall is that the Query block is merely a wrapper. It is only as good as its weakest sub-block. Most of its nested blocks are for post-related data, and the weakest among them is Post Featured Image. It limits everything that can be truly fun about building queries. It does not even cover a basic sub-set of the Image, Cover, and Media & Text options.

It is frustrating because users and theme authors cannot build out their visions. I know it will get there someday. Today, we are limited to the basics without any themes offering highly customized Query patterns.

It is tough to go wrong with a simple grid, so that is what I did.

A three-column grid of portfolio project images, titles, and dates.
Grid-style portfolio layout (first image is out of line in editor)

I followed that section with two Columns blocks nested inside another Columns block for a testimonials group. Then, I wrapped it up with a basic footer, running into the same issue with uploading a site logo. The most prevalent problems in these sections were inconsistent spacing.

Some of the limitations with these tests are not from the template editor in Gutenberg. Instead, they are from the TT1 Blocks theme. However, I suppose that depends on your philosophy about what the future of theme development should be. If most front-end styles should come from WordPress/Gutenberg, it is not a theme issue.

Vertical alignment is inconsistent in the best of times. Liberal use of the Spacer block is not ideal in real-world projects to align blocks. It can be a handy tool when needed, but it should not be a crutch for correcting foundational issues. The block system adds a few potholes in the road, but a well-rounded and tested theme can mitigate most of these problems. And, TT1 Blocks just does not do this. It relies almost exclusively on the core block styles without swerving left or right when it needs to.

The current padding controls for a few blocks like Group help with this. However, most users are not going to micromanage every pixel of every page on their sites. The same can be said for the margin controls when they become available. Again, both are useful and necessary tools, but users should not lean on them too heavily to correct design issues. In the long run, it will create more problems as site owners eventually swap themes.

Mismatched output in the editor versus the front end can become a headache at times. This is a known issue and noted in the call for testing, so I won’t harp on it.

I enjoyed the process — yes, I revel in both the fun and frustration. Aside from everything that I think is broken, the overall system is pretty dang sweet. There are far more things that the development team has nailed down than there are that feel janky. However, calls for testing are all about finding the problems. I encourage all Tavern readers to join in and report your feedback.

The Beginner’s Guide to CRM Trends

CRM (customer relationship management) has rapidly evolved over the past several years. What began as a contact system for customers has turned into a solution for every department in an organization.

Regardless of your business size or industry, you need to keep an eye on CRM trends today and in the future.

We’ve identified what’s trending upward in the CRM space for the coming years after extensive research.

Why Are CRM Trends Important?

The customer experience (CX) is the driving force of today’s modern business world. So many brands have become customer-focused, and consumers expect nothing but the best when making buying decisions.

If your organization can’t identify the consumer’s needs and provide them with the most relevant information at each stage of the buying cycle, you’ll quickly fall behind the competition.

Beyond the initial sale, customers crave brand engagement. Whether it’s a new offer, deal, promotion, or they need assistance with a previous purchase, the way your brand handles these interactions will make or break your success.

In terms of CRM, new software is helping companies drive these brand engagements. From analyzing customer data to tracking conversational histories, the possibilities are seemingly limitless.

Failing to follow the latest CRM trends puts your business at a massive disadvantage.

It’s impossible to improve the customer experience without adapting to new CRM trends. Those who adapt will increase customer conversion rates, retention rates, and customer lifetime value.

How Do We Look For CRM Trends?

The process for identifying trends in any industry is quite complex. Our team conducted extensive research related to the latest CRM statistics in every category imaginable.

After analyzing the numbers and trends from prior years, experts can estimate the trajectory of where things are heading in the future.

Furthermore, our team keeps a close eye on all of the latest software and technology for businesses. We’re testing new solutions on a daily basis. Using different tools in the CRM category, we’ve been able to see which new features are the most prevalent among the top players in the CRM industry.

5 CRM Trends You Need To Know

There are dozens of emerging CRM trends. But these five are the most important to consider:

Trend 1: Ease of Adoption

Historically, there have been high barriers to entry in the CRM space. Smaller companies and users who weren’t very tech-savvy haven’t been able to deploy these tools.

Many CRM solutions were marketed toward enterprise organizations with dedicated IT teams and staff who had experience using CRM tools in the past.

Those days are long behind us. Today, CRM software is for all of us.

Even some of the best CRM software solutions on the market can be used by businesses of all sizes. From freelancers to small businesses, SMEs, and everything in between, there’s a solution for everyone.

Lots of CRM software is cloud-based. So there’s no on-site installation, and you don’t need an in-house IT staff to manage the system. Cloud deployment makes it easy to get up and running immediately.

Using CRM solutions is much easier as well. They’re not as clunky and rigid as they were in the past so that non-technical users can figure it quickly—without a steep learning curve.

Price is another reason why more companies have adopted CRM software. It’s now extremely affordable to deploy these solutions for your business.

Look at an industry leader, like HubSpot. This CRM software is 100% free.

You can add one million contacts and onboard your entire team to this platform without paying a dime.

Even paid solutions from HubSpot and other popular tools on the market are incredibly affordable. Entry-level rates typically start around $10 to $30 per month.

These are just a few of the many reasons why so many businesses have adopted CRM in recent years.

The numbers don’t lie. A recent study suggests that overall CRM usage increased from 56% to 74% in the last year. 91% of companies with 11+ employees use CRM software.

Trend 2: Artificial Intelligence (AI)

Similar to most industries, AI is trending upward at a rapid rate. Most of the CRM tools that we test and review have implemented AI solutions in some form or another.

Those that haven’t added AI features to the tool have plans to do so in the coming years.

Arguably the most significant benefit of leveraging AI with a CRM solution is the ROI. Computers can do things at a rate that’s impossible for even an entire team of people. By letting AI handle data processing and other complex tasks, your team can focus more on selling.

Here are just a handful of ways that AI is currently being used in CRM:

  • Consumer sentiment analysis
  • Predictive lead scoring
  • Improved customer segmentation
  • Personalized recommendations based on consumer behavior
  • Sales forecasting
  • Chatbots for sales, marketing, and support
  • Increased customer engagement

One specific example of AI for customer relationship management is Zia—the AI-powered sales assistant from Zoho CRM.

One of the craziest parts about AI is that we’re just barely scratching the surface with its capabilities.

Years ago, AI sounded like something that only belonged in science fiction movies. But today, it’s everywhere in our daily lives—including our CRM software.

As AI technology continues to advance in the coming years, businesses using future-proof CRM software will have a significant advantage compared to those using outdated systems.

Trend 3: Market Saturation

It feels like a new CRM software is released every day. As of the time I’m writing this, there are 642 different CRM solutions listed on G2. But more isn’t always better. Only 11% of these tools have a five-star rating.

Software companies have recognized the CRM trend and have been releasing new systems to get a piece of the pie.

As a business owner, it can be tough to weed out the good from the bad. To make your life easier, check out our guide to the best CRM software. We’ve done all of the research for you and narrowed down the top picks based on different use cases.

Even with so many systems out there to choose from, one dominates the global market share—Salesforce. Salesforce controls roughly 20% of the CRM market share worldwide, according to a recent study.

If you’re overwhelmed by the sheer number of options out there, you can’t go wrong with the industry’s most popular solution.

According to Grand View Research, the total CRM market size is expected to grow at a CAGR of 14.2% through 2027.

I expect to see the number of CRM solutions available on the market continue to rise in the coming years. But I can’t imagine the biggest players losing a ton of market share to these newer tools.

Trend 4: CRM Mobility

Roughly ten years ago, all CRM activity was done in a traditional office setting. Users were tied to a desktop using a local CRM solution. When they were away from that desk, they weren’t able to access any CRM data.

Cloud-based SaaS has extended the reach of modern CRM solutions. But mobile apps take that one step further.

The ability to go mobile is a crucial component of successful sales.

Even in the pre-pandemic days, more and more companies were shifting to remote work. This is especially true for sales, marketing, and support roles—the three primary components of CRM.

The best CRM tools have recognized this trend and adapted accordingly. Now, users can access crucial CRM information from a smartphone or tablet.

So many business professionals work in odd hours outside of a typical 9-5 job. Even if people are working in an office, they may want to quickly check a report or follow up with a client when they get home. Mobile CRM features make this possible.

For CRM mobility to have a true impact, desktop and mobile experience needs to be interchangeable. If you can’t get what you’re looking for from mobile, it’s a useless feature.

Here’s an example from Apptivo, a CRM solution that allows users to do anything from mobile devices:

If your team uses a solution like this, they won’t skip a beat as they transition from their computers to mobile.

Whenever you’re dealing with sensitive customer data, security will always be a top concern. So it’s important to use a CRM solution that understands these risks and secures the software accordingly, regardless of the device that it’s being accessed from.

Employees accessing CRM from their homes on a tablet will have the same security benefits they would while in the office.

Trend 5: CRM Integrations

As businesses continue to adopt and deploy new technology, things can start to get complicated for the end-user.

A recent study of 2,000 office workers found that 54% of employees use at least five different computer programs simultaneously. And 59% of those surveyed said that they waste time switching between different apps throughout the day.

This defeats the purpose of using new technology. If it becomes a burden on your staff, you can’t expect efficiencies to improve.

That’s why it’s so important to consider the different possibilities of CRM integrations. This is something that’s trending upward for the foreseeable future.

The idea behind a CRM integration is that it limits the number of times a user needs to switch between different apps. Everything they need can be accessed in a single source of truth.

It’s not about eliminating tools completely. But instead, you can use CRM integrations to extend the functionality of the software you’re using.

Look at a CRM solution like Pipedrive.

This is just one of many examples of a tool that has an app marketplace or similar alternative to manage integrations.

As of right now, there are 270+ different apps that you can integrate with this solution. The number continues to climb. I remember using this tool less than a year ago, and the integration list was closer to 150.

Remember, CRM is all about the customer. It’s easy to forget this as you’re getting lost in a web of so many different features and capabilities.

To best serve the customer, you need to have a firm grasp of everything they are doing.

A recent study suggests that modern marketers are using an average of 16 different data sources to track customers—16! That’s a huge number.

Pulling data from different sources and manually entering the info into a CRM tool is a colossal waste of time. Plus, there are too many opportunities for errors during this transmission process.

CRM integrations make your life much easier. Just connect your CRM with the data sources, and it will pull that information automatically.

Not only will integrations improve the way your CRM system functions, but they will also boost employee productivity. Users can spend more time within a single platform instead of bouncing back and forth between multiple screens.

How Trends Affect You Affect Your CRM Purchasing Decisions

The term “future-proof” gets thrown around frequently in the business world, especially when referring to software. But the meaning of this phrase gets overlooked far too often.

If you’re not keeping a close eye on the trends, your CRM solution will quickly be outdated within a year or so.

From here, one of two things can happen. You’ll either stick with an outdated tool and slowly fall behind the competition as your customers’ needs go overlooked. Or you’ll be forced to switch solutions, and your whole team will have to re-learn a new system.

Switching CRM software can cause data loss and other problems too. So it’s something that you’ll definitely want to avoid.

Don’t rush through the buying process as you’re evaluating different CRM tools. Ask for demos, take advantage of free trials, and assess whether the software can accommodate your needs.

You should also look to see if the software is keeping pace with the latest CRM trends.

Is the provider coming out with new features like AI assistance and automation? Can the software seamlessly integrate with other third-party business tools that you’re already using?

These are just a couple of examples of the many questions you should be asking as you go through the CRM purchasing process. Keeping pace with CRM trends will ultimately help you make the right decision.

help for my code

  1. Combat between two creature cards: Reduce the defending creatures HP by the attack power of the attacking creature card AND reduce the attacking creatures HP by the attack power of the defending creature card. If either the attacker or the defender or both of them is/are reduced to 0 HP or lower these creatures are destroyed.
    Special abilities:
    a. If the attacking creature has Trample ability, the excess amount of attack power is dealt to the opposing player (which can cause the opposing player dying). Here the excess amount of attack power is calculated as:
    Excess attack power = Attackers attack power defenders HP
    b. If the attacking creature has First Strike ability,
    i. If the defending creature also has First Strike ability, normal attack procedure.
    ii. If the defending creature does NOT have First Strike ability; then first the Attackers attack power is applied to the defenders HP. If the defender is destroyed then the combat stops here (i.e., the defender CANNOT deal its damage to the attacker)
    c. If the attacking creature does NOT have First Strike ability,
    i. If the defending creature has First Strike ability, then first the Defenders attack power is
    applied to the attackers HP. If the attacker is destroyed then the combat stops here (i.e., the
    attacker CANNOT deal its damage to the defender)
    ii. If the defending creature also does NOT have First Strike ability; normal attack procedure.
  2. Combat between one creature card and the opposing player: Reduce the HP of the opposing player by the attack power of the attacking creature card. If the opposing players HP is reduced to 0 or lower, that player loses the game.

magicthegathering

Can anyone help me to write combat class?

  1. Combat between two creature cards: Reduce the defending creatures HP by the attack power of the attacking creature card AND reduce the attacking creatures HP by the attack power of the defending creature card. If either the attacker or the defender or both of them is/are reduced to 0 HP or lower these creatures are destroyed.
    ------Special abilities:
    a. If the attacking creature has Trample ability, the excess amount of attack power is dealt to the opposing player (which can cause the opposing player dying). Here the excess amount of attack power is calculated as:
    Excess attack power = Attackers attack power defenders HP
    b. If the attacking creature has First Strike ability,
    i. If the defending creature also has First Strike ability, normal attack procedure.
    ii. If the defending creature does NOT have First Strike ability; then first the Attackers attack power is applied to the defenders HP. If the defender is destroyed then the combat stops here (i.e., the defender CANNOT deal its damage to the attacker)
    c. If the attacking creature does NOT have First Strike ability,
    i. If the defending creature has First Strike ability, then first the Defenders attack power is
    applied to the attackers HP. If the attacker is destroyed then the combat stops here (i.e., the
    attacker CANNOT deal its damage to the defender)
    ii. If the defending creature also does NOT have First Strike ability; normal attack procedure.
  2. Combat between one creature card and the opposing player: Reduce the HP of the opposing player by the attack power of the attacking creature card. If the opposing players HP is reduced to 0 or lower, that player loses the game.

visual basic window form

how to create an app that employees can use to manage the main warehouse. The app must allow the user to enter the spare parts by serial number, name and/or use an external par code reader and specify which parts were dispatched to which aircraft notified by its number in the fleet. The app will then calculate the quantity of items for each type of spare part along with the price of the item then the App MUST give warnings about the remaining balance of the spare parts when it reaches only 4 items left in stock. If a user attempts to quarry about a certain item he should be able to do it using items serial number, or items name, an error message will be displayed informing the user that necessary input is missing. The GUI of the App must show the logo of the company (choose one of your own design) along with company name and contact details (address, telephone number, website... etc).

Document Generation With Dynamic Image Generation

One of the fascinating aspects of Adobe Document Generation is how incredibly flexible it is. One aspect of the API that can enhance the final result is the ability to include images in your template. In a typical use case, you would provide a static image defined in your data used with the API. In this blog post, I will demonstrate a more advanced example — dynamically generating images, in our case, charts, on the fly.

The Basics

Before we get into a more advanced demo, let’s quickly cover the basics. (My coworker has an intense look into Document Generation and images you should check out.) As our docs describe, using a dynamic image in your Word template requires a few steps.

Breadcrumbs from menu mysql

I have three tables in mysql which make up the dropdown menu, as below code. I would like to get a $ breadcrumb variable with link from this menu. Example:

Home / Woman

Home / Woman / Clothes

Home / Woman / Clothes / Women T-Shirth-2

It is possible??

<div id="sitemaps" class="menu">
                            <ul>
                                <li><a href="index.php">Home</a></li>

                                <?php
                                $statement = $pdo->prepare("SELECT * FROM tbl_top_category WHERE show_on_menu=1");
                                $statement->execute();
                                $result = $statement->fetchAll(PDO::FETCH_ASSOC);
                                foreach ($result as $row) {
                                    ?>
                                    <li><a href="product-category.php?id=<?php echo $row['tcat_id']; ?>&type=top-category"><?php echo $row['tcat_name']; ?></a>
                                        <ul>
                                            <?php
                                            $statement1 = $pdo->prepare("SELECT * FROM tbl_mid_category WHERE tcat_id=?");
                                            $statement1->execute(array($row['tcat_id']));
                                            $result1 = $statement1->fetchAll(PDO::FETCH_ASSOC);
                                            foreach ($result1 as $row1) {
                                                ?>
                                                <li><a href="product-category.php?id=<?php echo $row1['mcat_id']; ?>&type=mid-category"><?php echo $row1['mcat_name']; ?></a>
                                                    <ul>
                                                        <?php
                                                        $statement2 = $pdo->prepare("SELECT * FROM tbl_end_category WHERE mcat_id=?");
                                                        $statement2->execute(array($row1['mcat_id']));
                                                        $result2 = $statement2->fetchAll(PDO::FETCH_ASSOC);
                                                        foreach ($result2 as $row2) {
                                                            ?>
                                                            <li><a href="product-category.php?id=<?php echo $row2['ecat_id']; ?>&type=end-category"><?php echo $row2['ecat_name']; ?></a></li>
                                                            <?php
                                                        }
                                                        ?>
                                                    </ul>
                                                </li>
                                                <?php
                                            }
                                            ?>
                                        </ul>
                                    </li>
                                    <?php
                                }
                                ?>

    <div class="breadcrumb" style="margin-top:20px"><a href="<?php echo BASE_URL; ?>">Home / </a> <?php echo $breadcrumb ?>
    </div>



tbl_top_category
+-------------+----------------------+--------+
| tcat_id     | tcat_name            | active |
+-------------+----------------------+--------+
|           1 | Men                  |      1 |
|           2 | Woman                |      1 |
|           3 | Kids                 |      1 |
+-------------+----------------------+--------+


tbl_mid_category
+-------------+----------------------+--------+
| mcat_id     | mcat_name            | tcat_id|
+-------------+----------------------+--------+
|           1 | Men Shoes            |      1 |
|           2 | Men Clothes          |      1 |
|           3 | Men T-Shirth         |      1 |
|           4 | Women Shoes          |      2 |
|           5 | Women Clothes        |      2 |
|           6 | Women T-Shirth       |      2 |
|           7 | Kids Shoes           |      3 |
|           8 | Kids Clothes         |      3 |
|           9 | Kids T-Shirth        |      3 |
+-------------+----------------------+--------+

tbl_end_category
+-------------+----------------------+--------+
| ecat_id     | ecat_name            | mcat_id|
+-------------+----------------------+--------+
|           1 | Men Shoes-1          |      1 |
|           2 | Men Shoes-2          |      1 |
|           3 | Men Shoes-3          |      1 |
|           4 | Men Clothes-1        |      2 |
|           5 | Men Clothes-2        |      2 |
|           6 | Men T-Shirth-1       |      3 |
|           7 | Men T-Shirth-2       |      3 |
|           8 | Women Shoes-1        |      4 |
|           9 | Women Shoes-2        |      4 |
|           10| Women Shoes-3        |      4 |
|           11| Women Clothes-1      |      5 |
|           12| Women Clothes-2      |      5 |
|           13| Women T-Shirth-1     |      6 |
|           14| Women T-Shirth-2     |      6 |
|           15| Kids Shoes-1         |      7 |
|           16| Kids Shoes-2         |      7 |
|           17| Kids Shoes-3         |      7 |
|           18| Kids Clothes-1       |      8 |
|           19| Kids Clothes-2       |      8 |
|           20| Kids T-Shirth-1      |      9 |
|           21| Kids T-Shirth-2      |      9 |
+-------------+----------------------+--------+

Awesome Standalone (Web Components)

In his last An Event Apart talk, Dave made a point that it’s really only just about right now that Web Components are becoming a practical choice for production web development. For example, it has only been about a year since Edge went Chromium. Before that, Edge didn’t support any Web Component stuff. If you were shipping them long ago, you were doing so with fairly big polyfills, or in a progressive-enhancement style, where if they failed, they did so gracefully or in a controlled environment, say, an intranet where everyone has the same computer (or in something like Electron).

In my opinion, Web Components still have a ways to go to be compelling to most developers, but they are getting there. One thing that I think will push their adoption along is the incredibly easy DX of pre-built components thanks to, in part, ES Modules and how easy it is to import JavaScript.

I’ve mentioned this one before: look how silly-easy it is to use Nolan Lawson’s emoji picker:

That’s one line of JavaScript and one line of HTML to get it working, and another one line of JavaScript to wire it up and return a JSON response of a selection.

Compelling, indeed. DX, you might call it.

Web Components like that aren’t alone, hence the title of this post. Dave put together a list of Awesome Standalones. That is, Web Components that aren’t a part of some bigger more complex system1, but are just little drop-in doodads that are useful on their own, just like the emoji picker. Dave’s repo lists about 20 of them.

Take this one from GitHub (the company), a copy-to-clipboard Web Component:

Pretty sweet for something that comes across the wire at ~3KB. The production story is whatever you want it to be. Use it off the CDN. Bundle it up with your stuff. Leave it as on-demand one-off. Whatever. It’s darn easy to use. In the case of this standalone, there isn’t even any Shadow DOM to deal with.

No shade on Shadow DOM, that’s perhaps the most useful feature of Web Components (and cannot be replicated by a library since it’s a native browser feature), but the options for styling it aren’t my favorite. And if you used three different standalone components with three different opinions on how to style through the Shadow DOM, that’s going to get annoying.

What I picture is developers dipping their toes into stuff like this, seeing the benefits, and using more and more of them in what they are building, and even building their own. Building a design system from Web Components seems like a real sweet spot to me, like many big names2 already do.

The dream is for people to actually consolidate common UI patterns. Like, even if we never get native HTML “tabs” it’s possible that a Web Component could provide them, get the UI, UX, and accessibility perfect, yet leave them style-able such that literally any website could use them. But first, that needs to exist.


  1. That’s a cool way to use Web Components, too, but easy gets attention, and that matters.
  2. People always mention Lightning Design System as a Web Components-based design system, but I’m not seeing it. For example, this accordion looks like semantic HTML with class names, not Web Components. What am I missing?

The post Awesome Standalone (Web Components) appeared first on CSS-Tricks.

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

Links on Web Components

  • How we use Web Components at GitHub — Kristján Oddsson talks about how GitHub is using web components. I remember they were very early adopters, and it says here they released a <relative-time> component in 2014! Now they’ve got a whole bunch of open source components. So easy to use! Awesome! I wanted to poke around their HTML and see them in action, so I View’d Source and used the RegEx (<\w+-[\w|-|]+.*>) (thanks, Andrew) to look for them. Seven on the logged-in homepage, so they ain’t blowin’ smoke.
  • Using web components to encapsulate CSS and resolve design system conflicts — Tyler Williams says the encapsulation (Shadow DOM) of web components meant avoiding styling conflicts with an older CSS system. He also proves that companies that make sites for Git repos love web components.
  • Container Queries in Web Components — Max Böck shares that the :host of a web component can be the @container which is extremely great and is absolutely how all web components should be written.
  • Faster Integration with Web Components — Jason Grigsby does client work and says that web components don’t make integration fast or easy, they make integration fast and easy.
  • FicusJS — I remember being told once that native web components weren’t really meant to be used “raw” but meant to be low-level such that tooling could be built on top of them. We see that in competition amongst renderers, like lit-html vs htm. Then, in layers of tooling on top of that, like Ficus here, that adds a bunch of fancy stuff like state, methods, and events.
  • Shadow DOM and Its Effect on the Unofficial Styling API — Jim Nielsen expands on the idea I poked at on ShopTalk that the DOM is the styling API. It’s self-documenting, in a way. “As an author, you have to spend time and effort thinking about, architecting, and then documenting a styling API for your component. And as a consumer, you have to read, understand, and implement that API.” Yes. That’s why, to me, it feels like a good idea to have an option to “reach into the Shadow DOM from outside CSS” in an unencumbered way.
  • Awesome Standalones — I think Dave’s list here is exactly the kind of thing that gets developers feet wet and thinking about web components as actually useful.

Two years ago, hold true:


The post Links on Web Components appeared first on CSS-Tricks.

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

7 Best Applications for Making Geographical Maps

Maps are used to depict the relationship between key elements. This might include objects, space, an area, etc. Spatial information has long been interpreted using cartography since at least 7 BC. However, it isn’t known when the concept might have originally taken root.

Geographical maps in the modern era are a key aspect for understanding spatial information to collect digital data for commercial reasons associated with places, people, and activities, and educational and scientific purposes. This spatial information can be best mapped using many handy applications. Below is our pick of the 7 best applications for making geographical maps. This list covers both basic and advanced applications, catering to different types of users and applications of geographical maps.

#317: Chattin’ with Stephanie Eckles

I got to chat with Stephanie this week, a senior web engineer at Microsoft, who I’ve given the prestigious gold-star award for top front-end web development content producer this year ;). She’s got so many cool projects like Modern CSS, Style Stage, and a beginner course on making a website. So many of the sites she makes are in Eleventy, she’s taken to teaching that too, like on her site 11ty Rocks and on Egghead. She’s always teaching, like through her podcast Word Wrap or in online workshops.

Catch up with Stephanie on CodePen, GitHub, Twitter, and her personal website.

Sponsor: Jetpack Backup

Jetpack offers Full Site Backup (database, theme, assets… everything), but it doesn’t just back everything up, it goes above and beyond. For one thing, you can get real-time backups if you need, meaning everything is backed up as it happens, not day-by-day. You can also restore your site to any previous backup with the click of a button. That’s above and beyond right there. But if you’re a WooCommerce user, you’ll rest easy knowing that you won’t lose eCommerce sales and product changes when you restore to a historical point. Those changes are then “replayed” on top of the backup.

The post #317: Chattin’ with Stephanie Eckles appeared first on CodePen Blog.

10 Rules To Integrate Third-Party Scripts

Introduction

Third-party scripts can cause negative load-time effects. Why is this an issue? Well, in Google’s view, a poorly-optimized page should not rank highly. Instead, search results should favor pages with fundamental design strengths — including JavaScript minification, rapid execution time, and render-friendly scripting. 

In reflection of this belief, Google has planned the gradual release of a major update to its search algorithm that is scheduled for June through August of 2021. This update will increase the importance of a page’s loading speed as a contributing factor to a web page’s overall ranking on Google’s search results page. As a result, how third-party scripts impact page load times is becoming more important than ever. 

CSS Clogging

I recently visited a blog called "Does CSS loading cause blockage?" I opened it with a learning attitude, but it seemed that what was said was not completely correct, so I searched all kinds of information everywhere, and then I summarized it myself, 

Will CSS Loading Cause Blockage?

First of all, the answer is definitely yes. The loading of css will not only block the parsing of HTML, but also block the execution of JS.

11 Best Practices To Secure Your WooCommerce Store

WooCommerce security is an important topic which every WooCommerce store owner must know. If your WooCommerce store is not secured, you spend a lot of time-wasting on fixing the bugs and facing the risk of your website’s revenue being stolen (through phishing).

23% of the worldwide online stores are built on the WooCommerce platform as of 2021. Since the market share of WooCommerce is enormous, the threat of WooCommerce stores being hacked is also high. So, to keep your websites highly secured, we have listed some of the best security measures to follow.

A Thorough Analysis of CSS-in-JS

Wondering what’s even more challenging than choosing a JavaScript framework? You guessed it: choosing a CSS-in-JS solution. Why? Because there are more than 50 libraries out there, each of them offering a unique set of features.

We tested 10 different libraries, which are listed here in no particular order: Styled JSX, styled-components, Emotion, Treat, TypeStyle, Fela, Stitches, JSS, Goober, and Compiled. We found that, although each library provides a diverse set of features, many of those features are actually commonly shared between most other libraries.

So instead of reviewing each library individually, we’ll analyse the features that stand out the most. This will help us to better understand which one fits best for a specific use case.

Note: We assume that if you’re here, you’re already familiar with CSS-in-JS. If you’re looking for a more elementary post, you can check out “An Introduction to CSS-in-JS.”

Common CSS-in-JS features

Most actively maintained libraries that tackle CSS-in-JS support all the following features, so we can consider them de-facto.

Scoped CSS

All CSS-in-JS libraries generate unique CSS class names, a technique pioneered by CSS modules. All styles are scoped to their respective component, providing encapsulation without affecting any styling defined outside the component.

With this feature built-in, we never have to worry about CSS class name collisions, specificity wars, or wasted time spent coming up with unique class names across the entire codebase.

This feature is invaluable for component-based development.

SSR (Server-Side Rendering)

When considering Single Page Apps (SPAs) — where the HTTP server only delivers an initial empty HTML page and all rendering is performed in the browser — Server-Side Rendering (SSR) might not be very useful. However, any website or application that needs to be parsed and indexed by search engines must have SSR pages and styles need to be generated on the server as well.

The same principle applies to Static Site Generators (SSG), where pages along with any CSS code are pre-generated as static HTML files at build time.

The good news is that all libraries we’ve tested support SSR, making them eligible for basically any type of project.

Automatic vendor prefixes

Because of the complex CSS standardization process, it might take years for any new CSS feature to become available in all popular browsers. One approach aimed at providing early access to experimental features is to ship non-standard CSS syntax under a vendor prefix:

/* WebKit browsers: Chrome, Safari, most iOS browsers, etc */
-webkit-transition: all 1s ease;

/* Firefox */
-moz-transition: all 1s ease;

/* Internet Explorer and Microsoft Edge */
-ms-transition: all 1s ease;

/* old pre-WebKit versions of Opera */
-o-transition: all 1s ease;

/* standard */
transition: all 1s ease; 

However, it turns out that vendor prefixes are problematic and the CSS Working Group intends to stop using them in the future. If we want to fully support older browsers that don’t implement the standard specification, we’ll need to know which features require a vendor prefix.

Fortunately, there are tools that allow us to use the standard syntax in our source code, generating the required vendor prefixed CSS properties automatically. All CSS-in-JS libraries also provide this feature out-of-the-box.

No inline styles

There are some CSS-in-JS libraries, like Radium or Glamor, that output all style definitions as inline styles. This technique has a huge limitation, because it’s impossible to define pseudo classes, pseudo-elements, or media queries using inline styles. So, these libraries had to hack these features by adding DOM event listeners and triggering style updates from JavaScript,  essentially reinventing native CSS features like :hover, :focus and many more.

It’s also generally accepted that inline styles are less performant than class names. It’s usually a discouraged practice to use them as a primary approach for styling components.

All current CSS-in-JS libraries have stepped away from using inline styles, adopting CSS class names to apply style definitions.

Full CSS support

A consequence of using CSS classes instead of inline styles is that there’s no limitation regarding what CSS properties we can and can’t use. During our analysis we were specifically interested in:

  • pseudo classes and elements;
  • media queries;
  • keyframe animations.

All the libraries we’ve analyzed offer full support for all CSS properties.

Differentiating features

This is where it gets even more interesting. Almost every library offers a unique set of features that can highly influence our decision when choosing the appropriate solution for a particular project. Some libraries pioneered a specific feature, while others chose to borrow or even improve certain features.

React-specific or framework-agnostic?

It’s not a secret that CSS-in-JS is more prevalent within the React ecosystem. That’s why some libraries are specifically built for React: Styled JSX, styled-components, and Stitches.

However, there are plenty of libraries that are framework-agnostic, making them applicable to any project: Emotion, Treat, TypeStyle, Fela, JSS or Goober.

If we need to support vanilla JavaScript code or frameworks other than React, the decision is simple: we should choose a framework-agnostic library. But when dealing with a React application, we have a much wider range of options which ultimately makes the decision more difficult. So let’s explore other criteria.

Styles/Component co-location

The ability to define styles along with their components is a very convenient feature, removing the need to switch back-and-forth between two different files: the .css or .less/.scss file containing the styles and the component file containing the markup and behavior.

React Native StyleSheets, Vue.js SFCs, or Angular Components support co-location of styles by default, which proves to be a real benefit during both the development and the maintenance phases. We always have the option to extract the styles into a separate file, in case we feel that they’re obscuring the rest of the code.

Almost all CSS-in-JS libraries support co-location of styles. The only exception we encountered was Treat, which requires us to define the styles in a separate .treat.ts file, similarly to how CSS Modules work.

Styles definition syntax

There are two different methods we can use to define our styles. Some libraries support only one method, while others are quite flexible and support both of them.

Tagged Templates syntax

The Tagged Templates syntax allows us to define styles as a string of plain CSS code inside a standard ES Template Literal:

// consider "css" being the API of a generic CSS-in-JS library
const heading = css`
  font-size: 2em;
  color: ${myTheme.color};
`;

We can see that:

  • CSS properties are written in kebab case just like regular CSS;
  • JavaScript values can be interpolated;
  • we can easily migrate existing CSS code without rewriting it.

Some things to keep in mind:

  • In order to get syntax highlight and code suggestions, an additional editor plugin is required; but this plugin is usually available for popular editors like VSCode, WebStorm, and others.
  • Since the final code must be eventually executed in JavaScript, the style definitions need to be parsed and converted to JavaScript code. This can be done either at runtime, or at build time, incurring a small overhead in bundle size, or computation.
Object Styles syntax

The Object Styles syntax allows us to define styles as regular JavaScript Objects:

// consider "css" being the API of a generic CSS-in-JS library
const heading = css({
  fontSize: "2em",
  color: myTheme.color,
});

We can see that:

  • CSS properties are written in camelCase and string values must be wrapped in quotes;
  • JavaScript values can be referenced as expected;
  • it doesn’t feel like writing CSS, as instead we define styles using a slightly different syntax but with the same property names and values available in CSS (don’t feel intimidated by this, you’ll get used to it in no time);
  • migrating existing CSS would require a rewrite in this new syntax.

Some things to keep in mind:

  • Syntax highlighting comes out-of-the-box, because we’re actually writing JavaScript code.
  • To get code completion, the library must ship CSS types definitions, most of them extending the popular CSSType package.
  • Since the styles are already written in JavaScript, there’s no additional parsing or conversion required.
LibraryTagged templateObject styles
styled-components
Emotion
Goober
Compiled
Fela🟠
JSS🟠
Treat
TypeStyle
Stitches
Styled JSX

✅  Full support         🟠  Requires plugin          ❌  Unsupported

Styles applying method

Now that we know what options are available for style definition, let’s have a look at how to apply them to our components and elements.

Using a class attribute / className prop

The easiest and most intuitive way to apply the styles is to simply attach them as classnames. Libraries that support this approach provide an API that returns a string which will output the generated unique classnames:

// consider "css" being the API of a generic CSS-in-JS library
const heading_style = css({
  color: "blue"
});

Next, we can take the heading_style, which contains a string of generated CSS class names, and apply it to our HTML element:

// Vanilla DOM usage
const heading = `<h1 class="${heading_style}">Title</h1>`;

// React-specific JSX usage
function Heading() {
  return <h1 className={heading_style}>Title</h1>;
}

As we can see, this method pretty much resembles the traditional styling: first we define the styles, then we attach the styles where we need them. The learning curve is low for anyone who has written CSS before.

Using a <Styled /> component

Another popular method, that was first introduced by the styled-components library (and named after it), takes a different approach.

// consider "styled" being the API for a generic CSS-in-JS library
const Heading = styled("h1")({
  color: "blue"
});

Instead of defining the styles separately and attaching them to existing components or HTML elements, we use a special API by specifying what type of element we want to create and the styles we want to attach to it.

The API will return a new component, having classname(s) already applied, that we can render like any other component in our application. This basically removes the mapping between the component and its styles.

Using the css prop

A newer method, introduced by Emotion, allows us to pass the styles to a special prop, usually named css. This API is available only for JSX-based syntax.

// React-specific JSX syntax
function Heading() {
  return <h1 css={{ color: "blue" }}>Title</h1>;
}

This approach has a certain ergonomic benefit, because we don’t have to import and use any special API from the library itself. We can simply pass the styles to this css prop, similarly to how we would use inline styles.

Note that this custom css prop is not a standard HTML attribute, and needs to be enabled and supported via a separate Babel plugin provided by the library.

LibraryclassName<Styled />css prop
styled-components
Emotion
Goober🟠 2
Compiled🟠 1
Fela
JSS🟠 2
Treat
TypeStyle
Stitches🟠 1
Styled JSX

✅  Full support          🟠 1  Limited support          🟠 2  Requires plugin          ❌  Unsupported

Styles output

There are two mutually exclusive methods to generate and ship styles to the browser. Both methods have benefits and downsides, so let’s analyze them in detail.

<style>-injected DOM styles

Most CSS-in-JS libraries inject styles into the DOM at runtime, using either one or more <style> tags, or using the CSSStyleSheet API to manage styles directly within the CSSOM. During SSR, styles are always appended as a <style> tag inside the <head> of the rendered HTML page.

There are a few key advantages and preferred use cases for this approach:

  1. Inlining the styles during SSR provides an increase in page loading performance metrics such as FCP (First Contentful Paint), because rendering is not blocked by fetching a separate .css file from the server.
  2. It provides out-of-the-box critical CSS extraction during SSR by inlining only the styles required to render the initial HTML page. It also removes any dynamic styles, thus further improving loading time by downloading less code.
  3. Dynamic styling is usually easier to implement, as this approach appears to be more suited for highly interactive user interfaces and Single-Page Applications (SPA), where most components are client-side rendered.

The drawbacks are generally related to the total bundle size:

  • an additional runtime library is required for handling dynamic styling in the browser;
  • the inlined SSR styles won’t be cached out-of-the-box and they will need to be shipped to the browser upon each request since they’re part of the .html file rendered by the server;
  • the SSR styles that are inlined in the .html page will be sent to the browser again as JavaScript resources during the rehydration process.
Static .css file extraction

There’s a very small number of libraries that take a totally different approach. Instead of injecting the styles in the DOM, they generate static .css files. From a loading performance point of view, we get the same advantages and drawbacks that come with writing plain CSS files.

  1. The total amount of shipped code is much smaller, since there is no need for additional runtime code or rehydration overhead.
  2. Static .css files benefit from out-of-the-box caching inside the browser, so subsequent requests to the same page won’t fetch the styles again.
  3. This approach seems to be more appealing when dealing with SSR pages or Static Generated pages since they benefit from default caching mechanisms.

However, there are some important drawbacks we need to take note of:

  • The first visit to a page, with an empty cache, will usually have a longer FCP when using this method compared to the one mentioned previously; so deciding if we want to optimize for first-time users or returning visitors could play a crucial role when choosing this approach.
  • All dynamic styles that can be used on the page will be included in the pre-generated bundle, potentially leading to larger .css resources that need to be loaded up front.

Almost all the libraries that we tested implement the first method, injecting the styles into the DOM. The only tested library which supports static .css file extraction is Treat. There are other libraries that support this feature, like Astroturf, Linaria, and style9, which were not included in our final analysis.

Atomic CSS

Some libraries took optimizations one step further, implementing a technique called atomic CSS-in-JS, inspired by frameworks such as Tachyons or Tailwind.

Instead of generating CSS classes containing all the properties that were defined for a specific element, they generate a unique CSS class for each unique CSS property/value combination.

/* classic, non-atomic CSS class */
._wqdGktJ {
  color: blue;
  display: block;
  padding: 1em 2em;
}

/* atomic CSS classes */
._ktJqdG { color: blue; }
._garIHZ { display: block; }
/* short-hand properties are usually expanded */
._kZbibd { padding-right: 2em; }
._jcgYzk { padding-left: 2em; }
._ekAjen { padding-bottom: 1em; }
._ibmHGN { padding-top: 1em; }

This enables a high degree of reusability because each of these individual CSS classes can be reused anywhere in the code base.

In theory, this works really great in the case of large applications. Why? Because there’s a finite number of unique CSS properties that are needed for an entire application. Thus, the scaling factor is not linear, but rather logarithmic, resulting in less CSS output compared to non-atomic CSS.

But there is a catch: individual class names must be applied to each element that requires them, resulting in slightly larger HTML files:

<!-- with classic, non-atomic CSS classes -->
<h1 class="_wqdGktJ">...</h1>

<!-- with atomic CSS classes -->
<h1 class="_ktJqdG _garIHZ _kZbibd _jcgYzk _ekAjen _ibmHGN">...</h1>

So basically, we’re moving code from CSS to HTML. The resulting difference in size depends on too many aspects for us to draw a definite conclusion, but generally speaking, it should decrease the total amount of bytes shipped to the browser.

Conclusion

CSS-in-JS will dramatically change the way we author CSS, providing many benefits and improving our overall development experience.

However, choosing which library to adopt is not straightforward and all choices come with many technical compromises. In order to identify the library that is best suited for our needs, we have to understand the project requirements and its use cases:

  • Are we using React or not? React applications have a wider range of options, while non-React solutions have to use a framework agnostic library.
  • Are we dealing with a highly interactive application, with client-side rendering? In this case, we probably aren’t very concerned about the overhead of rehydration, or care that much about extracting static .css files.
  • Are we building a dynamic website with SSR pages? Then, extracting static .css files may probably be a better option, as it would allow us to benefit from caching.
  • Do we need to migrate existing CSS code? Using a library that supports Tagged Templates would make the migration easier and faster.
  • Do we want to optimize for first-time users or returning visitors? Static .css files offer the best experience for returning visitors by caching the resources, but the first visit requires an additional HTTP request that blocks page rendering.
  • Do we update our styles frequently? All cached .css files are worthless if we frequently update our styles, thus invalidating any cache.
  • Do we re-use a lot of styles and components? Atomic CSS shines if we reuse a lot of CSS properties in our codebase.

Answering the above questions will help us decide what features to look for when choosing a CSS-in-JS solution, allowing us to make more educated decisions.


The post A Thorough Analysis of CSS-in-JS appeared first on CSS-Tricks.

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