emGee Software Solutions Custom Database Applications

Share this

Web Technologies

CrossUI Web App Builder

Echo JS - Tue, 05/14/2019 - 20:44
Categories: Web Technologies

Why I don't use React?

Echo JS - Tue, 05/14/2019 - 20:44
Categories: Web Technologies

A practical guide to ES6 Symbol

Echo JS - Tue, 05/14/2019 - 20:44
Categories: Web Technologies

PSR-14: Example - layered caching - larry@garfieldtech.com

Planet PHP - Tue, 05/14/2019 - 12:18
PSR-14: Example - layered caching

So far we've looked at a number of complete, practical examples of using PSR-14 Events in various ways, both conventional and unconventional. In our final (probably) installment, I want to offer a highly unconventional but still practical use of PSR-14 that really shows off just how flexible Events can be: Layered caching.

"But wait, isn't caching the realm of PSR-6 and PSR-16?" Yes. Yes it is. But neither of those offer a built-in way to compose multiple cache backends together. It's certainly possible, but doing so is left as an exercise for the implementer. Let's use PSR-14 to get some exercise.

Continue reading this post on SteemIt.

Larry 14 May 2019 - 2:18pm
Categories: Web Technologies

425 Too Early - Evert Pot

Planet PHP - Tue, 05/14/2019 - 08:00

When a HTTP client makes a connection to a HTTPS server, it uses TLS to create a secure connection. TLS can have a bit of a complicated ‘handshake’ to establish the connection. Because there’s a bunch of back and forward, this can take a long time, especially when there’s a lot of latency between server and client.

There are ways for clients to optimize this setup by sending a bunch of data very early in the process, before the full TLS connection is completely setup.

In some cases this can cause security problems. In those cases a the server can tell the client to retry a specific HTTP request after the TLS connection has been fully set up

In these situations, it will return the 425 Too Early status code.

Normally, you would never have to deal with this status code as a developer, unless you are creating HTTP(s) servers from scratch.

References
Categories: Web Technologies

Integrating Third-Party Animation Libraries to a Project

CSS-Tricks - Tue, 05/14/2019 - 07:28

Creating CSS-based animations and transitions can be a challenge. They can be complex and time-consuming. Need to move forward with a project with little time to tweak the perfect transition? Consider a third-party CSS animation library with ready-to-go animations waiting to be used. Yet, you might be thinking: What are they? What do they offer? How do I use them?

Well, let’s find out.

A (sort of) brief history of :hover

Once there was a time that the concept of a hover state was a trivial example of what is offered today. In fact, the idea of having a reaction to the cursor passing on top of an element was more-or-less nonexistent. Different ways to provide this feature were proposed and implemented. This small feature, in a way, opened the door to the idea of CSS being capable of animations for elements on the page. Over time, the increasing complexity possible with these features have led to CSS animation libraries.

Macromedia’s Dreamweaver was introduced in December 1997 and offered what was a simple feature, an image swap on hover. This feature was implemented with a JavaScript function that would be embedded in the HTML by the editor. This function was named MM_swapImage() and has become a bit of web design folklore. It was an easy script to use, even outside of Dreamweaver, and it’s popularity has resulted in it still being in use even today. In my initial research for this article, I found a question pertaining to this function from 2018 on Adobe’s Dreamweaver (Adobe acquired Macromedia in 2005) help forum.

The JavaScript function would swap an image with another image through changing the src attribute based on mouseover and mouseout events. When implemented, it looked something like this:

<a href="#" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('ImageName','','newImage.jpg',1)"> <img src="originalImage.jpg" name="ImageName" width="100" height="100" border="0"> </a>

By today’s standards, it would be fairly easy to accomplish this with JavaScript and many of us could practically do this in our sleep. But consider that JavaScript was still this new scripting language at the time (created in 1995) and sometimes looked and behaved differently from browser to browser. Creating cross-browser JavaScript was not always an easy task and not everyone creating web pages even wrote JavaScript. (Though that has certainly changed.) Dreamweaver offered this functionality through a menu in the editor and the web designer didn’t even need to write the JavaScript. It was based around a set of "behaviors" that could be selected from a list of different options. These options could be filtered by a set of targeted browsers; 3.0 browsers, 4.0 browsers, IE 3.0, IE 4.0, Netscape 3.0, Netscape 4.0. Ah, the good old days.

Choosing Behaviors based on browser versions, circa 1997. The Swap Image Behaviors panel in Macromedia Dreamweaver 1.2a

About a year after Dreamweaver was first released, the CSS2 specification from W3C mentioned :hover in a working draft dated January 1998. It was specifically mentioned in terms of anchor links, but the language suggests it could have possibly been applied to other elements. For most purposes it would seem this pseudo selector would be the beginning of an easy alternative to MM_swapImage(), since background-image was in the same draft. Although browser support was an issue as it took years before enough browsers properly supported CSS2 to make it a viable option for many web designers. There was finally a W3C recommendation of CSS2.1, this could be considered to be the basis of "modern" CSS as we know it, which was published in June 2011.

In the middle of all this, jQuery came along in 2006. Thankfully, jQuery went a long way in simplifying JavaScript among the different browsers. One thing of interest for our story, the first version of jQuery offered the animate() method. With this method, you could animate CSS properties on any element at any time; not just on hover. By its sheer popularity, this method exposed the need for a more robust CSS solution baked into the browser — a solution that wouldn’t require a JavaScript library that was not always very performant due to browser limitations.

The :hover pseudo-class only offered a hard swap from one state to another with no support for a smooth transition. Nor could it animate changes in elements outside of something as basic as hovering over an element. jQuery’s animate() method offered those features. It paved the way and there was no going back. As things go in the dynamic world of web development, a working draft for solving this was well underway before the recommendation of CSS2.1 was published. The first working draft for CSS Transitions Module Level 3 was first published by the W3C in March 2009. The first working draft for CSS Animations Module Level 3 was published at roughly the same time. Both of these CSS modules are still in a working draft status as of October 2018, but of course, we are already making heavy use of them

So, what first started as a JavaScript function provided by a third-party, just for a simple hover state, has led to transitions and animations in CSS that allow for elaborate and complex animations — complexity that many developers wouldn’t necessarily wish to consider as they need to move quickly on new projects. We have gone full circle; today many third-party CSS animation libraries have been created to offset this complexity.

Three different types of third-party animation libraries

We are in this new world capable of powerful, exciting, and complex animations in our web pages and apps. Several different ideas have come to the forefront on how to approach these new tasks. It’s not that one approach is better than any other; indeed, there is a good bit of overlap in each. The difference is more about how we implement and write code for them. Some are full-blown JavaScript-only libraries while others are CSS-only collections.

JavaScript libraries

Libraries that operate solely through JavaScript often offer capabilities beyond what common CSS animations provide. Usually, there is overlap as the libraries may actually use CSS features as part of their engine, but that would be abstracted away in favor of the API. Examples of such libraries are Greensock and Anime.js. You can see the extent of what they offer by looking at the demos they provide (Greensock has a nice collection over on CodePen). They’re mostly intended for highly complex animations, but can be useful for more basic animations as well.

JavaScript and CSS libraries

There are third-party libraries that primarily include CSS classes but provide some JavaScript for easy use of the classes in your projects. One library, Micron.js, provides both a JavaScript API and data attributes that can be used on elements. This type of library allows for easy use of pre-built animations that you can just select from. Another library, Motion UI, is intended to be used with a JavaScript framework. Although, it also works on a similar notion of a mixture of a JavaScript API, pre-built classes, and data attributes. These types of libraries provide pre-built animations and an easy way to wire them up.

CSS libraries

The third kind of library is CSS-only. Typically, this is just a CSS file that you load via a link tag in your HTML. You then apply and remove specific CSS classes to make use of the provided animations. Two examples of this type of library are Animate.css and Animista. That said, there are even major differences between these two particular libraries. Animate.css is a total CSS package while Animista provides a slick interface to choose the animations you want with provided code. These libraries are often easy to implement but you have to write code to make use of them. These are the type of libraries this article will focus on.

Three different types of CSS animations

Yes, there’s a pattern; the rule of threes is everywhere, after all.

In most cases, there are three types of animations to consider when making use of third-party libraries. Each type suits a different purpose and has different ways to make use of them.

Hover animations

These animations are intended to be involved in some sort of hover state. They’re often used with buttons, but another possibility is using them to highlight sections the cursor happens to be on. They can also be used for focus states.

Attention animations

These animations are intended to be used on elements that are normally outside of the visual center of the person viewing the page. An animation is applied to a section of the display that needs attention. Such animations could be subtle in nature for things that need eventual attention but not dire in nature. They could also be highly distracting for when immediate attention is required.

Transition animations

These animations are often intended to have an element replace another in the view, but can be used for one element as well. These will usually include an animation for "leaving" the view and mirror animation for "entering" the view. Think of fading out and fading in. This is commonly needed in single page apps as one section of data would transition to another set of data, for example.

So, let’s go over examples of each of these type of animations and how one might use them.

Let’s hover it up!

Some libraries may already be set for hover effects, while some have hover states as their main purpose. One such library is Hover.css, which is a drop-in solution that provides a nice range of hover effects applied via class names. Sometimes, though, we want to make use of an animation in a library that doesn’t directly support the :hover pseudo-class because that might conflict with global styles.

For this example, I shall use the tada animation that Animate.css provides. It’s intended more as an attention seeker, but it will nicely suffice for this example. If you were to look through the CSS of the library, you’ll find that there’s no :hover pseudo-class to be found. So, we’ll have to make it work in that manner on our own.

The tada class by itself is simply this:

.tada { animation-name: tada; }

A low-lift approach to make this react to a hover state is to make our own local copy of the class, but extend it just a bit. Normally, Animate.css is a drop-in solution, so we won’t necessarily have the option to edit the original CSS file; although you could have your own local copy of the file if you wish. Therefore, we only create the code we require to be different and let the library handle the rest.

.tada-hover:hover { animation-name: tada; }

We probably shouldn’t override the original class name in case we actually want to use it elsewhere. So, instead, we make a variation that we can place the :hover pseudo-class on the selector. Now we just use the library’s required animated class along with our custom tada-hover class to an element and it will play that animation on hover.

If you wouldn’t want to create a custom class in this way, but prefer a JavaScript solution instead, there’s a relatively easy way to handle that. Oddly enough, it’s a similar method to the MM_imageSwap() method from Dreamweaver we discussed earlier.

// Let's select elements with ID #js_example var js_example = document.querySelector('#js_example'); // When elements with ID #js_example are hovered... js_example.addEventListener('mouseover', function () { // ...let's add two classes to the element: animated and tada... this.classList.add('animated', 'tada'); }); // ...then remove those classes when the mouse is not on the element. js_example.addEventListener('mouseout', function () { this.classList.remove('animated', 'tada'); });

There are actually multiple ways to handle this, depending on the context. Here, we create some event listeners to wait for the mouse-over and mouse-out events. These listeners then apply and remove the library’s animated and tada classes as needed. As you can see, extending a third-party library just a bit to suit our needs can be accomplished in relatively easy fashion.

Can I please have your attention?

Another type of animation that third-party libraries can assist with are attention seekers. These animations are useful for when you wish to draw attention to an element or section of the page. Some examples of this could be notifications or unfilled required form inputs. These animations can be subtle or direct. Subtle for when something needs eventual attention but does not need to be resolved immediately. Direct for when something needs resolution now.

Some libraries have such animations as part of the whole package, while some are built specifically for this purpose. Both Animate.css and Animista have attention seeking animations, but they are not the main purpose for those libraries. An example of a library built for this purpose would be CSShake. Which library to use depends on the needs of the project and how much time you wish to invest in implementing them. For example, CSShake is ready to go with little trouble on your part — simply apply classes as needed. Although, if you were already using a library such as Animate.css, then you’re likely not going to want to introduce a second library (for performance, reliance on dependencies, and such).

So, a library such as Animate.css can be used but needs a little more setup. The library’s GitHub page has examples of how to go about doing this. Depending on the needs of a project, implementing these animations as attention seekers is rather straightforward.

For a subtle type of animation, we could have one that just repeats a set number of times and stops. This usually involves adding the library’s classes, applying an animation iteration property to CSS, and waiting for the animation end event to clear the library’s classes.

Here’s a simple example that follows the same pattern we looked at earlier for hover states:

var pulse = document.querySelector('#pulse'); function playPulse () { pulse.classList.add('animated', 'pulse'); } pulse.addEventListener('animationend', function () { pulse.classList.remove('animated', 'pulse'); }); playPulse();

The library classes are applied when the playPulse function is called. There’s an event listener for the animationend event that will remove the library’s classes. Normally, this would only play once, but you might want to repeat multiple times before stopping. Animate.css doesn’t provide a class for this, but it’s easy enough to apply a CSS property for our element to handle this.

#pulse { animation-iteration-count: 3; /* Stop after three times */ }

This way, the animation will play three times before stopping. If we needed to stop the animation sooner, we can manually remove the library classes outside of the animationend function. The library’s documentation actually provides an example of a reusable function for applying the classes that removes them after the animation; very similar to the above code. It would even be rather easy to extend it to apply the iteration count to the element.

For a more direct approach, let’s say an infinite animation that won’t stop until after some sort of user interaction takes place. Let’s pretend that clicking the element is what starts the animation and clicking again stops it. Keep in mind that however you wish to start and stop the animation is up to you.

var bounce = document.querySelector('#bounce'); bounce.addEventListener('click', function () { if (!bounce.classList.contains('animated')) { bounce.classList.add('animated', 'bounce', 'infinite'); } else { bounce.classList.remove('animated', 'bounce', 'infinite'); } });

Simple enough. Clicking the element tests if the library’s "animated" class has been applied. If it has not, we apply the library classes so it starts the animation. If it has the classes, we remove them to stop the animation. Notice that infinite class on the end of the classList. Thankfully, Animate.css provides this for us out-of-the-box. If your library of choice doesn’t offer such a class, then this is what you need in your CSS:

#bounce { animation-iteration-count: infinite; }

Here’s a demo showing how this code behaves:

See the Pen
3rd Party Animation Libraries: Attention Seekers
by Travis Almand (@talmand)
on CodePen.

Moving stuff out of the way

When researching for this article, I found that transitions (not to be confused with CSS transitions) are easily the most common type of animations in the third-party libraries. These are simple animations that are built to allow an element to enter or leave the page. A very common pattern seen in modern Single Page Applications is to have one element leave the page while another replaces it by entering the page. Think of the first element fading out and the second fading in. This could be replacing old data with new data, moving to the next panel in a sequence, or moving from one page to another with a router. Both Sarah Drasner and Georgy Marchuk have excellent examples of these types of transitions.

For the most part, animation libraries will not provide the means to remove and add elements during the transition animations. The libraries that provide additional JavaScript may actually have this functionality, but since most do not, we’ll discuss how to handle this functionality now.

Inserting a single element

For this example, we’ll again use Animate.css as our library. In this case, I’ll be using the fadeInDown animation.

Now, please keep in mind there are many ways to handle inserting an element into the DOM and I don’t wish to cover them here. I’ll just be showing how to leverage an animation to make the insertion nicer and more natural than the element simply popping into view. For Animate.css (and likely many other libraries), inserting an element with the animation is quite easy.

let insertElement = document.createElement('div'); insertElement.innerText = 'this div is inserted'; insertElement.classList.add('animated', 'fadeInDown'); insertElement.addEventListener('animationend', function () { this.classList.remove('animated', 'fadeInDown'); }); document.body.append(insertElement);

However you decide to create the element doesn’t much matter; you just need to be sure the needed classes are already applied before inserting the element. Then it’ll nicely animate into place. I also included an event listener for the animationend event that removes the classes. As usual, there are several ways to go about doing this and this is likely the most direct way to handle it. The reason for removing the classes is to make it easier to reverse the process if we wish. We wouldn’t want the entering animation competing with a leaving animation.

Removing a single element

Removing a single element is sort of similar to inserting an element. The element already exists, so we just apply the desired animation classes. Then at the animationend event we remove the element from the DOM. In this example, we’ll use the fadeOutDown animation from Animate.css because it works nicely with the fadeInDown animation.

let removeElement = document.querySelector('#removeElement'); removeElement.addEventListener('animationend', function () { this.remove(); }); removeElement.classList.add('animated', 'fadeOutDown');

As you can see, we target the element, add the classes, and remove the element at the end of the animation.

An issue with all this is that with inserting and removing elements this way will cause the other elements on the page to jump around to adjust. You’ll have to account for that in some way, most likely with CSS and the layout of the page to keep a constant space for the elements.

Get out of my way, I’m coming through!

Now we are going to swap two elements, one leaving while another enters. There are several ways of handling this, but I’ll provide an example that’s essentially combining the previous two examples.

See the Pen
3rd Party Animation Libraries: Transitioning Two Elements
by Travis Almand (@talmand)
on CodePen.

I’ll go over the JavaScript in parts to explain how it works. First, we cache a reference to a button and the container for the two elements. Then, we create two boxes that’ll be swapped inside the container.

let button = document.querySelector('button'); let container = document.querySelector('.container'); let box1 = document.createElement('div'); let box2 = document.createElement('div');

I have a generic function for removing the animation classes for each animationEnd event.

let removeClasses = function () { box1.classList.remove('animated', 'fadeOutRight', 'fadeInLeft'); box2.classList.remove('animated', 'fadeOutRight', 'fadeInLeft'); }

The next function is the bulk of the swapping functionality. First, we determine the current box being displayed. Based on that, we can deduce the leaving and entering elements. The leaving element gets the event listener that called the switchElements function removed first so we don’t find ourselves in an animation loop. Then, we remove the leaving element from the container since its animation has finished. Next, we add the animation classes to the entering element and append it to the container so it’ll animate into place.

let switchElements = function () { let currentElement = document.querySelector('.container .box'); let leaveElement = currentElement.classList.contains('box1') ? box1 : box2; let enterElement = leaveElement === box1 ? box2 : box1; leaveElement.removeEventListener('animationend', switchElements); leaveElement.remove(); enterElement.classList.add('animated', 'fadeInLeft'); container.append(enterElement); }

We need to do some general setup for the two boxes. Plus, we append the first box to the container.

box1.classList.add('box', 'box1'); box1.addEventListener('animationend', removeClasses); box2.classList.add('box', 'box2'); box2.addEventListener('animationend', removeClasses); container.appendChild(box1);

Finally, we have a click event listener for our button that does the toggling. How these sequences of events are started is technically up to you. For this example, I decided on a simple button click. I figure out which box is currently being displayed, which will be leaving, to apply the appropriate classes to make it animate out. Then I apply an event listener for the animationEnd event that calls the switchElements function shown above that handles the actual swap.

button.addEventListener('click', function () { let currentElement = document.querySelector('.container .box'); if (currentElement.classList.contains('box1')) { box1.classList.add('animated', 'fadeOutRight'); box1.addEventListener('animationend', switchElements); } else { box2.classList.add('animated', 'fadeOutRight'); box2.addEventListener('animationend', switchElements); } }

One obvious issue with this example is that it is extremely hard-coded for this one situation. Although, it can be easily extended and adjusted for different situations. So, the example is useful in terms of understanding one way of handling such a task. Thankfully, some animation libraries, like MotionUI, provide some JavaScript to help with element transitions. Another thing to consider is that some JavaScript frameworks, such as VueJS have functionality to assist with animating element transitions.

I have also created another example that provides a more flexible system. It consists of a container that stores references to leave and enter animations with data attributes. The container holds two elements that will switch places on command. The way this example is built is that the animations are easily changed in the data attributes via JavaScript. I also have two containers in the demo; one using Animate.css and the other using Animista for animations. It’s a large example, so I won’t examine code here; but it is heavily commented, so take a look if it is of interest.

See the Pen
3rd Party Animation Libraries: Custom Transition Example
by Travis Almand (@talmand)
on CodePen.

Take a moment to consider...

Does everyone actually want to see all these animations? Some people could consider our animations over-the-top and unnecessary, but for some, they can actually cause problems. Some time ago, WebKit introduced the prefers-reduced-motion media query to assist with possible Vestibular Spectrum Disorder issues. Eric Bailey also posted a nice introduction to the media query, as well as a follow-up with considerations for best practices. Definitely read these.

So, does your animation library of choice support the prefers-reduced-motion? If the documentation doesn’t say that it does, then you may have to assume it does not. Although, it is rather easy to check the code of the library to see if there is anything for the media query. For instance, Animate.css has it in the _base.scss partial file.

@media (print), (prefers-reduced-motion) { .animated { animation: unset !important; transition: none !important; } }

This bit of code also provides an excellent example of how to do this for yourself if the library doesn’t support it. If the library has a common class it uses — like Animate.css uses "animated" — then you can just target that class. If it does not support such a class then you’ll have to target the actual animation class or create your own custom class for that purpose.

.scale-up-center { animation: scale-up-center 0.4s cubic-bezier(0.390, 0.575, 0.565, 1.000) both; } @keyframes scale-up-center { 0% { transform: scale(0.5); } 100% { transform: scale(1); } } @media (print), (prefers-reduced-motion) { .scale-up-center { animation: unset !important; transition: none !important; } }

As you can see, I just used the example as provided by Animate.css and targeted the animation class from Animista. Keep in mind that you’ll have to repeat this for every animation class you choose to use from the library. Although, in Eric’s follow-up piece, he suggests treating all animations as progressive enhancement and that could be one way to both reduce code and make a more accessible user experience.

Let a framework do the heavy lifting for you

In many ways, the various frameworks such as React and Vue can make using third-party CSS animation easier than with vanilla JavaScript, mainly because you don’t have to wire up the class swaps or animationend events manually. You can leverage the functionality the frameworks already provide. The beauty of using frameworks is that they also provide several different ways of handling these animations depending on the needs of the project. The examples below is only a small example of options.

Hover effects

For hover effects, I would suggest setting them up with CSS (as I suggested above) as the better way to go. If you really need a JavaScript solution in a framework, such as Vue, it would be something like this:

<button @mouseover="over($event, 'tada')" @mouseleave="leave($event, 'tada')"> tada </button> methods: { over: function(e, type) { e.target.classList.add('animated', type); }, leave: function (e, type) { e.target.classList.remove('animated', type); } }

Not really that much different than the vanilla JavaScript solution above. Also, as before, there are many ways of handling this.

Attention seekers

Setting up the attention seekers is actually even easier. In this case, we’re just applying the classes we require, again, using Vue as an example:

<div :class="{animated: isPulse, pulse: isPulse}">pulse</div> <div :class="[{animated: isBounce, bounce: isBounce}, 'infinite']">bounce</div>

In the pulse example, whenever the boolean isPulse is true, the two classes are applied. In the bounce example, whenever the boolean isBounce is true the animated and bounce classes are applied. The infinite class is applied regardless so we can have our never-ending bounce until the isBounce boolean goes back to false.

Transitions

Thankfully, Vue’s transition component provides an easy way to use third-party animation classes with custom transition classes. Other libraries, such as React, could offer similar features or add-ons. To make use of the animation classes in Vue, we just implement them in the transition component.

<transition enter-active-class="animated fadeInDown" leave-active-class="animated fadeOutDown" mode="out-in" > <div v-if="toggle" key="if">if example</div> <div v-else key="else">else example</div> </transition>

Using Animate.css, we merely apply the necessary classes. For enter-active, we apply the required animated class along with fadeInDown. For leave-active, we apply the required animated class along with fadeOutDown. During the transition sequence, these classes are inserted at the appropriate times. Vue handles the inserting and removing of the classes for us.

For a more complex example of using third-party animation libraries in a JavaScript framework, explore this project:

See the Pen
KLKdJy
by Travis Almand (@talmand)
on CodePen.

Join the party!

This is a small taste of the possibilities that await your project as there are many, many third-party CSS animation libraries out there to explore. Some are thorough, eccentric, specific, obnoxious, or just straight-forward. There are libraries for complex JavaScript animations such as Greensock or Anime.js. There are even libraries that will target the characters in an element.

Hopefully all this will inspire you to play with these libraries on the way to creating your own CSS animations.

The post Integrating Third-Party Animation Libraries to a Project appeared first on CSS-Tricks.

Categories: Web Technologies

Google Fonts is Adding font-display

CSS-Tricks - Tue, 05/14/2019 - 07:20

Google announced at I/O that their font service will now support the font-display property which resolves a number of web performance issues. If you're hearing cries of joy, that's probably Chris as he punches the air in celebration. He's wanted this feature for some time and suggests that all @font-face blocks ought to consider using the property.

Zach Leatherman has the lowdown:

This is big news—it means developers now have more control over Google Fonts web font loading behavior. We can enforce instant rendering of fallback text (when using font-display: swap) rather than relying on the browser default behavior of invisible text for up to 3 seconds while the web font request is in-flight.

It’s also a bit of trailblazing, too. To my knowledge, this is the first web font host that’s shipping support for this very important font-display feature.

Yes, a big deal indeed! You may recall that font-display instructs the browser how (and kinda when) to load fonts. That makes it a possible weapon to fight fight FOUT and FOIT issues. Chris has mentioned how he likes the optional value for that exact reason.

@font-face { font-family: "Open Sans Regular"; src: url("..."); font-display: optional; }

Oh and this is a good time to remind everyone of Monica Dinculescu’s font-display demo where she explores all the various font-display values and how they work in practice. It’s super nifty and worth checking out.

Direct Link to ArticlePermalink

The post Google Fonts is Adding font-display appeared first on CSS-Tricks.

Categories: Web Technologies

Changes - Adam Culp

Planet PHP - Tue, 05/14/2019 - 06:42

It was 6 years ago when I was last looking for a change after being a freelancer for a very long time. The idea was simple. I was tired of being the accountant, salesperson, consultant, developer, collections, sysadmin, and more. As a freelance “developer” I had to be all these things to support my family and live in a manner I was accustomed. But I was growing tired of it all, and wanted to have a little more fun by doing the parts I enjoyed most…consulting.

A good friend had been working at a well-known company for about a year and was very happy doing it. He also had grown tired of being a freelance developer, and a job at the company was his answer. So, when I saw an open consulting position on their website, I applied for it.

About a week later I received a call, then went through the typical round of interviews and questions. I was hired!

It was an exciting time, filled with learning new systems, people, and experiences. I was suddenly thrust into meetings with very large companies, and large teams of developers, who needed my help. There were new problems to solve on a weekly basis, and with each problem came new challenges. The number of things I learned during my six years of consulting at the company was mind-blowing, and with each day I discovered there was more and more I didn’t know. I basically went from knowing a bunch of things to village idiot overnight when I was hired.

“I went from knowing a bunch of things to village idiot overnight when I was hired.”

As I transitioned from one customer to another, it also led to traveling quite a bit. I spent half of each year away from home as I went onsite to meet new teams, learn network and application infrastructures, and build relationships with hundreds of people.

I continued to learn a great deal, and with each engagement, I spent less time on search engines and could draw from my own knowledge more often. (Of course, there was still a bunch of searching, but it was less. I’m still the village idiot learning daily.)

As a user group organizer, and speaker, I’ve always enjoyed teaching and sharing, and it was wonderful that my employer encouraged this activity. So I tended to share my knowledge with anyone who would listen, as I began speaking at conferences, user groups, and online from blog posts, podcasts, and videos, as well as through code via online source code repositories.

Through the process, I also did a fair amount of evangelism around products, libraries, and frameworks I believed in and witnessed some real growth from these efforts which drove me to do more.

However, as times change and acquisitions happen, so do the directions companies take. For good, or bad, companies are forced to make decisions and make changes to help them move forward and grow. I’ve witnessed and lived through some events these past couple years that have left me feeling dissatisfied and a little disconnected from the things I’ve come to hold dear.

This doesn’t mean the company is bad. It simply means our paths have diverged for the time being. Therefore, I will be leaving my current employer, as it is time once again for a change.

Categories: Web Technologies

Interview with Omni Adams - Voices of the ElePHPant

Planet PHP - Tue, 05/14/2019 - 06:05

@omnicolor Show Notes Audio

This episode is sponsored by


The post Interview with Omni Adams appeared first on Voices of the ElePHPant.

Categories: Web Technologies

Change Color of SVG on Hover

CSS-Tricks - Mon, 05/13/2019 - 07:44

There are a lot of different ways to use SVG. Depending on which way, the tactic for recoloring that SVG in different states or conditions — :hover, :active, :focus, class name change, etc. — is different.

Let's look at the ways.

Inline SVG

Inline SVG is my favorite way to use SVG anyway, in part because of how easy it is to access and style the SVG.

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

If you're used to working with icon fonts, one thing you might enjoy about them is how easy it is to change the color. You're largely limited to a single color with icon fonts in a way that SVG isn't, but still, it is appealingly easy to change that single color with color. Using inline SVG allows you to set the fill, which cascades to all the elements within the SVG, or you can fill each element separately if needed.

SVG Symbol / Use

There is such thing as an SVG sprite, which is a group of SVGs turned into <symbol> elements such that any given icon can be referenced easily with a <use> element.

See the Pen
Use SVG Hovers
by Chris Coyier (@chriscoyier)
on CodePen.

You can still set the fill color from outside CSS rather easily this way, but there are caveats.

  • The internal SVG elements (like the <path>) can have no fill themselves. This allows the fill set from the parent SVG to cascade into the Shadow DOM created by <use>. As soon as you have something like <path fill="blue" ... /> in the <symbol>, you've lost outside CSS control.
  • Likewise, the fill of individual elements cannot be controlled within the SVG like you could with inline SVG. This means you're pretty firmly in single-color territory. That covers most use cases anyway, but still, a limitation nonetheless.
SVG background images

SVG can be set as a background image just like PNG, JPG, or whatever other graphics format. At this point, you've sort of given up on being able to change the fill. One possibility, which I'd argue isn't a particularly good one, is to have two versions of every icon, in the respective colors, and swap between them:

See the Pen
Background SVG Hovers
by Chris Coyier (@chriscoyier)
on CodePen.

I don't blame you if you'd rather not swap sources, so another possibility is to get gnarly with filters.

See the Pen
Background SVG Hovers with Filters
by Chris Coyier (@chriscoyier)
on CodePen.

Trying to finagle the right filters to get the color right is tricky stuff. Fortunately, Barrett Sonntag made a tool to calculate the filters for you! Turning black to red ends up a whacky combination like this: invert(27%) sepia(51%) saturate(2878%) hue-rotate(346deg) brightness(104%) contrast(97%);.

SVG also has object, which is kinda neat in that it had a built-in fallback back in the day — although browser support is so good these days, I honestly have never used it. But if you're using it, you would probably have to use this filter technique to swap color on hover.

See the Pen
Background SVG Object Hovers
by Chris Coyier (@chriscoyier)
on CodePen.

Use a mask instead of a background image

This way, the SVG is still in charge of essentially drawing the shape, but the color comes from the background-color (or image! or gradient!) behind it rather than the SVG itself.

See the Pen
Background SVG Hovers with Mask
by Chris Coyier (@chriscoyier)
on CodePen.

SVG background images as data URLs

This doesn't change that much from above, but it does open up one interesting possibility: Using a variable for the internal fills. Here that is with Sass keeping the URLs as variables:

See the Pen
Background SVG Hovers with Data URL variables
by Chris Coyier (@chriscoyier)
on CodePen.

You can also do this with native CSS custom properties!

The post Change Color of SVG on Hover appeared first on CSS-Tricks.

Categories: Web Technologies

SVG Properties and CSS

CSS-Tricks - Mon, 05/13/2019 - 07:44

There are many Scalable Vector Graphics (SVG), but only certain attributes can be applied as CSS to SVG. Presentation attributes are used to style SVG elements and can be used as CSS properties. Some of these attributes are SVG-only while others are already shared in CSS, such as font-size or opacity.

For example, to change the color of a <circle> element to red, use the fill property in CSS. The fill attribute is a presentation attribute, therefore it can be used as a CSS property:

circle { fill: red; }

See the Pen
vMqaay
by Geoff Graham (@geoffgraham)
on CodePen.

So, with that, let's take a deep and thorough dive into all of the SVG elements that are available to us as well as the CSS properties for them. We'll also look at various styling approaches, including general presentational styles and animations.

SVG Elements by Category

The presentation attributes that can be used as CSS properties can be found below. For reference, supported elements will be classified by category. This does not include deprecated elements.

Element Type Elements Container elements <a>
<defs>
<g>
<marker>
<mask>
<pattern>
<svg>
<switch>
<symbol> Filter primitive elements <feBlend>
<feColorMatrix>
<feComponentTransfer>
<feComposite>
<feConvolveMatrix>
<feDiffuseLighting>
<feDisplacementMap>
<feFlood>
<feGaussianBlur>
<feImage>
<feMerge>
<feMorphology>
<feOffset>
<feSpecularLighting>
<feTile>
<feTurbulence> Gradient elements <linearGradient>
<radialGradient>
<stop> Graphics elements <circle>
<ellipse>
<image>
<line>
<path>
<polygon>
<polyline>
<rect>
<text>
<use> Shape elements <circle>
<ellipse>
<line>
<path>
<polygon>
<polyline>
<rect> Text content elements <text>
<textPath>
<tspan> Properties shared between CSS and SVG Font properties Presentation attribute Supported elements font Text content elements font-family Text content elements font-size Text content elements font-size-adjust Text content elements font-stretch Text content elements font-style Text content elements font-variant Text content elements font-weight Text content elements Text properties Presentation attribute Supported elements direction <text>
<tspan> letter-spacing Text content elements text-decoration Text content elements unicode-bidi Text content elements word-spacing Text content elements writing-mode <text> Masking properties Presentation attribute Supported elements overflow <foreignObject>
<image>
<marker>
<pattern>
<svg>
<symbol> Interactivity properties Presentation attribute Supported elements cursor Container elements
Graphics elements Color properties Presentation attribute Supported elements color Applies to elements using:
fill
stroke
stop-color
flood-color
lighting-color Visibility properties Presentation attribute Supported elements display Graphics elements
Text content elements
<a>
<foreignObject>
<g>
<svg>
<switch> visibility Graphics elements
Text content elements SVG CSS Properties Text properties Presentation attribute Supported elements alignment-baseline <textPath>
<tspan> baseline-shift <textPath>
<tspan> dominant-baseline Text content elements glyph-orientation-horizontal Text content elements glyph-orientation-vertical Text content elements kerning Text content elements text-anchor Text content elements Clip properties Presentation attribute Supported elements clip <foreignObject>
<image>
<marker>
<pattern>
<svg>
<symbol> clip-path Container elements
Graphics elements clip-rule <clipPath> Masking properties Presentation attribute Supported elements mask Container elements
Graphics elements opacity Graphics elements
<a>
<defs>
<g>
<marker>
<pattern>
<svg>
<switch>
<symbol> Filter effects Presentation attribute Supported elements enable-background Container elements filter Container elements
Graphics elements flood-color <feFlood> flood-opacity <feFlood> lighting-color <feDiffuseLighting>
<feSpecularLighting> Gradient properties Presentation attribute Supported elements stop-color <stop> stop-opacity <stop> Interactivity properties Presentation attribute Supported elements pointer-events Graphics elements Color properties Presentation attribute Supported elements color-profile <image> referring to raster image Painting properties Presentation attribute Supported elements color-interpolation Container elements
Graphics elements color-interpolation-filters Filter primitive elements color-rendering Container elements
Graphics elements fill Shape elements
Text content elements fill-rule Shape elements
Text content elements fill-opacity Shape elements
Text content elements image-rendering <image> marker <line>
<path>
<polygon>
<polyline> marker-start <line>
<path>
<polygon>
<polyline> marker-mid <line>
<path>
<polygon>
<polyline> marker-end <line>
<path>
<polygon>
<polyline> shape-rendering Shape elements stroke Shape elements
Text content elements stroke-dasharray Shape elements
Text content elements stroke-dashoffset Shape elements
Text content elements stroke-linecap Shape elements
Text content elements stroke-linejoin Shape elements
Text content elements stroke-miterlimit Shape elements
Text content elements stroke-opacity Shape elements
Text content elements stroke-width Shape elements
Text content elements text-rendering <text> SVG 2

While presentation attributes can be used as CSS properties to style SVG, what about controlling the coordinates and dimensions of SVG elements using CSS? SVG 2, which is in Candidate Recommendation at the time of this writing, makes it is possible to style and animate these properties.

The SVG 2 specification states:

Some styling properties can be specified not only in style sheets and 'style' attributes, but also in presentation attributes. These are attributes whose name matches (or is similar to) a given CSS property and whose value is parsed as a value of that property."

Not only does it mean that SVG properties can be styled using CSS as presentation attributes or in style sheets, but this also can be applied to CSS pseudo-classes such as :hover or :active.

SVG 2 also introduces more presentation attributes that can be used as styling properties. These attributes can be found in SVG 2 specification.

Element-specific properties

It is important to note that not every SVG element will support the same CSS properties. Much like how there are CSS properties that can be applied to certain SVG elements, there are specific properties that are supported by certain SVG elements.

For example, the <circle>or <ellipse> elements support the cxand cyproperties as coordinates of the center of the shape. The <ellipse> element also supports the rx and ry properties as the radius, but the <circle> element cannot use these properties.

Geometry properties

In SVG 2, properties such as rx and ry are defined as geometry properties. Geometry properties can be used as CSS properties, just like presentation attributes such as fill or stroke properties. These CSS properties and the corresponding SVG elements include:

SVG Element Geometry Property <circle> cx
cy
r <ellipse> cx
cy
rx
ry <rect> rx
ry
height
width
x
y <path> path <image> height
width
x
y <foreignObject> height
width
x
y <svg> code>height
width
x
y Positioning SVG elements

SVG 2 also makes it is possible to position SVG elements using CSS. Let’s begin with drawing a rectangle shape having the following SVG:

<svg width="170" height="170"> <rect x="10" y="10" width="150" height="150" /> </svg>

And the following CSS:

rect { fill: #6e40aa; }

See the Pen
QPeNGj
by Geoff Graham (@geoffgraham)
on CodePen.

This will produce a rectangle shape with its coordinates set to 10, 10. With SVG 2, x and y can be applied as CSS properties:

/* This will work with SVG 2 */ rect { x: 10; y: 10; ... }

The SVG code would be reduced to this:

<svg width="170" height="170"> <rect width="150" height="150" /> </svg>

You can even set the width and height for the <rect> element using CSS like so:

rect { ... width: 150px; height: 150px; ... }

That leaves us with just the following for SVG markup:

<svg width="170" height="170"> <rect /> </svg>

See the Pen
Positioning SVG elements
by Katherine Kato (@kathykato)
on CodePen.

At the time of writing, the following demos will work in Blink (e.g. Chrome and Opera) and WebKit (e.g. Safari) browsers as these browsers support SVG 2 features. Until then, let’s dive into how to override SVG properties using CSS.

SVG shape morphing

The <path> element can be overridden with CSS to create shape morphing.

The SVG paths that morph one into the other must have the same commands and same number of points or else the morphing will not work.

Let’s start with drawing a <path> element in the shape of a triangle. Using the d property will specify the shape of the <path> element:

<svg height="220" width="300"> <path d="M150 10 L40 200 L260 200Z" /> </svg>

To get the triangle to morph into a different shape, let’s override the SVG <path> element with the d property with CSS:

path { d: path("M150, 10 L40, 200 L260, 200Z"); fill: #4c6edb; }

Let’s also add a :active pseudo-class to the <path> property so when the element is clicked, the shape will morph into a square and change its fill color. Let’s also add a transition property to make the shape morphing action appear smooth. Here is the CSS:

path:active { d: path("M150, 10 L40, 200 L260, 200 L260, 200Z"); fill: #4c6edb; transition: all 0.35s ease; }

And the SVG would be:

<svg height="220" width="300"> <path /> </svg>

See the Pen
SVG shape morphing
by Katherine Kato (@kathykato)
on CodePen.

Want another demo? Here is a cool demo from Chris Coyier demonstrating SVG shape morphing on hover!

See the Pen
Simple Path Examples
by Chris Coyier (@chriscoyier)
on CodePen.

Animating SVG properties

SVG properties can be animated using CSS through CSS animations and transitions.

In this demo, we will draw various SVG <circle> elements and create a wave animation. Start by drawing five <circle> elements:

<svg width="350" height="250"> <circle class="shape" /> <circle class="shape" /> <circle class="shape" /> <circle class="shape" /> <circle class="shape" /> </svg>

We’ll be using CSS variables and :nth-child() CSS pseudo-class to define each .shape class. The .shape class will have a cy of 50 and a r of 20. Each of the .shape classes will have their own cx and fill CSS properties set:

:root { --color-1: #6e40aa; --color-2: #4c6edb; --color-3: #24aad8; --color-4: #1ac7c2; --color-5: #1ddea3; } .shape { cy: 50; r: 20; } .shape:nth-child(1) { cx: 60; fill: var(--color-1); } .shape:nth-child(2) { cx: 120; fill: var(--color-2); } .shape:nth-child(3) { cx: 180; fill: var(--color-3); } .shape:nth-child(4) { cx: 240; fill: var(--color-4); } .shape:nth-child(5) { cx: 300; fill: var(--color-5); }

Here is how it should look so far.

See the Pen
Animating SVG properties: Pre-animation
by Geoff Graham (@geoffgraham)
on CodePen.

Now it’s time to animate! Start by using @keyframes rule to define the moveCircle animation:

@keyframes moveCircle { 50% { cy: 150; r: 13; } }

This will get each <circle> element to change their cy coordinates from 50 to 150 and r from 20 to 13. Add the following to the CSS to the .shape class get the animation running infinitely:

.shape { ... animation: moveCircle 1250ms ease-in-out both infinite; }

Finally, add an animation-delay to each of the .shape classes to the CSS with the exception of .shape:nth-child(1) like this:

.shape:nth-child(2) { ... animation-delay: 100ms; } .shape:nth-child(3) { ... animation-delay: 200ms; } .shape:nth-child(4) { ... animation-delay: 300ms; } .shape:nth-child(5) { ... animation-delay: 400ms; }

See the Pen
Animating SVG properties
by Katherine Kato (@kathykato)
on CodePen.

Shapes in SVG <pattern> elements can also be animated using CSS. Here is a cool demo by Dudley Storey showcasing that!

See the Pen
Screen
by Dudley Storey (@dudleystorey)
on CodePen.

Wrapping up

As SVG 1.1 is the current standard, few browsers currently support SVG 2 features. It is not recommended to put these techniques into production yet. SVG 2 implementation is currently at Candidate Recommendation stage, thus support for styling SVG geometry properties with CSS should improve in the future.

The post SVG Properties and CSS appeared first on CSS-Tricks.

Categories: Web Technologies

Deploying a Client-Side Rendered create-react-app to Microsoft Azure

CSS-Tricks - Fri, 05/10/2019 - 12:54

Deploying a React app to Microsoft Azure is simple. Except that... it isn’t. The devil is in the details. If you're looking to deploy a create-react-app — or a similar style front-end JavaScript framework that requires pushState-based routing — to Microsoft Azure, I believe this article will serve you well. We’re going to try to avoid the headaches of client and server side routing reconciliation.

First, a quick story.

Back in 2016, when Donovan Brown, a Senior DevOps Program Manager at Microsoft, had given a "but it works on my machine speech" at Microsoft Connect that year, I was still in my preliminary stages as a web developer. His talk was about micro-services and containers.

[...] Gone are the days when your manager comes running into your office and she is frantic and she has found a bug. And no matter how hard I try, I can't reproduce it and it works perfectly on my machine. She says: fine Donovan, then we are going to ship your machine because that is the only place where it works. But I like my machine, so I'm not going to let her ship it...

I had a similar sort of challenge, but it had to do with routing. I was working on a website with a React front end and ASP.NET Core back end, hosted as two separate projects that were deployed to Microsoft Azure. This meant we could deploy both apps separately and enjoy the benefits that comes with separation of concern. We also know who to git blame if and when something goes wrong. But it had downsides as well, as front-end vs. back-end routing reconciliation was one of those downsides.

One day I pushed some new code to our staging servers. I received a message shortly after telling me the website was failing on page refresh. It was throwing a 404 error. At first, I didn’t think it was my responsibility to fix the error. It had to be some server configuration issue. Turns out I was both right and wrong.

I was right to know it was a server configuration issue (though at the time, I didn’t know it had to do with routing). I was wrong to deny it my responsibility. It was only after I went on a web searching rampage that I found a use case for deploying a create-react-app to Azure under the Deployment tab on the official documentation page.

Building React for production

When building a React app for production (assuming we’re are using create-react-app), it’s worth noting the folders that get generated. Running npm run build will generate a build folder where an optimized static version of the application lives. To get the application on a live server, all we need do is feed the server the content of the build folder. If we were working on localhost, there is no live server involved, so it is not always equivalent to having the application on a live server.

Generally, the build folder will have this structure:

→ build → static → css → css files → js → js files → media → media files → index.html → other files... Client-side routing with React Router

React Router uses the HTML5 pushState history API internally. What pushState does is quite interesting. For example, navigating (or using Link in react router) from the page https://css-tricks.com to the page https://css-tricks.com/archives/ will cause the URL bar to display https://css-tricks.com/archives/ but won't cause the browser to load the page /archives or even check that it exists. Couple this with the component-based model of React, it becomes a thing to change routes while displaying different pages based on those routes — without the all-seeing eye of the server trying to serve a page in its own directory. What happens, then, when we introduce servers by pushing the code to a live server? The docs tell it better:

If you use routers that use the HTML5 pushState history API under the hood (for example, React Router with browserHistory), many static file servers will fail. For example, if you used React Router with a route for /todos/42, the development server will respond to localhost:3000/todos/42 properly, but an Express serving a production build as above will not. This is because when there is a fresh page load for a /todos/42, the server looks for the file build/todos/42 and does not find it. The server needs to be configured to respond to a request to /todos/42 by serving index.html.

Different servers require different configuration. Express, for example, requires this:

app.get('*', (req, res) => { res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html')); });

...as documented in the create-react-app docs. Keep in mind though, this assumes that we’re hosting create-react-app at the server root, which is making use of a wildcard route (*) that catches all route and respond to all route request by serving the index.html file in the build folder which sits at the root of the server application. Also, this is tightly coupled with the back-end. If that’s the case, we would most likely have this kind of folder structure (assuming the back-end is in NodeJS):

→ Server → Client (this is where your react code goes) → build (this is the build folder, after you npm run build) → src → node_modules → package.json → other front-end files and folders → Other back-end files and folders

Since my front-end (create-react-app) and back-end (ASP.NET) were two different projects, serving static files by navigating the directory was sort of an impossibility.

In fact, since we are deploying a static app, we do not need the back-end. As Burke Holland put it: "Static" means that we aren’t deploying any server code; just the front-end files.

I keep mentioning ASP.NET here because during the course of my research, I figured configuring Azure required a configuration file in a wwwroot folder and ASP.NET's folder structure typically has a wwwroot folder. Remember the application’s back-end was in ASP.NET? But that’s just about it. The wwwroot folder seemed to be hidden somewhere on Azure. And I can’t show you without deploying a create-react-app. So let’s go do that.

Getting started with App Services on Microsoft Azure

To get started, if you do not already have a Azure account, get a free trial then head over to the Azure portal.

  1. Navigate to All services → Web → App Services
    Navigating on the Azure portal from All services, to Web, to App services

  2. We want to add a new app, give it a name, subscription (should be free if you’re on a free trial, or if you already have one), resource group (create one or use existing), then click on the Create button down at the bottom of the panel.
    Creating a new App service on the Azure portal.
  3. We should get a notification that the resource has been created. But it won’t immediately show up, so hit "Refresh" — I have other resources, but the AzureReactDemo2 is what I’m using here. You’ll click on the name of your newly created app, which is AzureReactDemo2 in my case.
    Displaying all App Services on the Azure portal.
  4. The blade shows you information about your app, the navigation to the left has everything you need to manage your application (overview, activity log, deployment center...).

For example, the Deployment Center is where the app deployment is managed, Slots is where things like staging, production, test are managed. Configuration is where things like environmental variables, node versions and — an important one — Kudu are managed.

The overview screen shows a general view of the application Status, URL... Click on the URL to see the live site.

Showing the various parts of an App Service on the Azure CLI.

The app is up and running!

Showing the default live page of an App Service.

What we’ve done is create a new App Service, but we have none of our code on Azure yet. As said earlier, all we need to do is to feed Azure the content of the build folder generated by building React for production, but we don’t have one yet. So let’s go local and get some React app.

Going local

We need to create a new React app, and install react-router as a dependency.

npx create-react-app azure-react-demo cd azure-react-demo

We also want to install react-router (react-router-dom, actually)

npm i react-router-dom

All things being equal, starting the app with npm start, we should get the default page.

Showing the default page generated by React.

Because this will be about testing routes, I needed to make some pages. I’ve modified my local version and uploaded it to GitHub. I’m banking on the fact that you can find your way around react and react-router. Download a demo.

My folder looks like this:

Showing the folders and files in the modified create-react-app app.

The changed files have the following code:

// App.js import React, { Component } from "react"; import "./App.css"; import Home from "./pages/Home"; import Page1 from "./pages/Page1"; import Page2 from "./pages/Page2"; import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; class App extends Component { render() { return ( <Router> <Switch> <Route exact path="/" component={Home} /> <Route path="/page1" component={Page1} /> <Route path="/page2" component={Page2} /> </Switch> </Router> ); } } export default App; // Page1.js import React from "react"; import { Link } from "react-router-dom"; const Page1 = () => { return ( <div className="page page1"> <div className="flagTop" /> <div className="flagCenter"> <h1 className="country">Argentina (PAGE 1)</h1> <div className="otherLinks"> <Link to="/page2">Nigeria</Link> <Link to="/">Home</Link> </div> </div> <div className="flagBottom" /> </div> ); }; export default Page1; // Page2.js import React from "react"; import { Link } from "react-router-dom"; const Page2 = () => { return ( <div className="page page2"> <div className="flagTop" /> <div className="flagCenter"> <h1 className="country">Nigeria (PAGE 2)</h1> <div className="otherLinks"> <Link to="/page1">Argentina</Link> <Link to="/">Home</Link> </div> </div> <div className="flagBottom" /> </div> ); }; export default Page2; /* App.css */ html { box-sizing: border-box; } body { margin: 0; } .page { display: grid; grid-template-rows: repeat(3, 1fr); height: 100vh; } .page1 .flagTop, .page1 .flagBottom { background-color: blue; } .page2 .flagTop, .page2 .flagBottom { background-color: green; } .flagCenter { display: flex; align-items: center; flex-direction: column; justify-content: center; text-align: center; } .page a { border: 2px solid currentColor; font-weight: bold; margin: 0 30px; padding: 5px; text-decoration: none; text-transform: uppercase; } .flags { display: flex; width: 100%; } .flags > .page { flex: 1; }

Running the app works locally, so the routes deliver when links are clicked and even when the page is refreshed.

Deploy the app to Azure

Now, let’s get it up on Azure! There are a few steps to make this happen.

Step 1: Head to the Deployment Center

On Azure, we need to go to the Deployment Center. There are quite a few options each with its pros and cons. We’ll be using Local Git (which means your local git app straight directly to Azure) for source control, Kudu for Build Provider.

Remember to click continue or finish when you select an option, or else, the portal will just keep staring at you.

Showing Deployment Center on the Azure portal and choosing a source control as the first step in deploying a new App Service. Showing the Build Provider section in the Deployment Center on Azure portal.

After the third step, Azure generates a local git repo for you. And it gives you a remote link to point your react app to.

One thing to note at this point. When you push, Azure will ask for your GitHub credentials. It is under the deployment tab. There are two: App and User. App credential will be specific to an app. User will be general to all the apps you as a user has Read/Write access to. You can do without User Credentials and use App credentials, but I find that after a while, Azure stops asking for credentials and just tells me authentication failed automatically. I set a custom User Credentials. Either way, you should get past that.

Showing the Deployment Credentials for the App Service on Azure portal.

In the React app, after modification, we need to build for production. This is important because what we want to upload is the content of the build folder.

We need to tell Kudu what node engine we’ll be using, or else, the build will most likely fail,
due to the reported fact that react-scripts requires a node version higher than the default set on Azure. There are other ways to do that, but the simplest is to add a nodes engine in package.json. I’m using version 10.0 here. Unfortunately, we can’t just add what we like, since Azure has Node versions it supports and the rest are unsupported. Check that with the CLI with the command: az webapp list-runtimes

Add the preferred node version to the package.json file, as in:

"engines": { "node": "10.0" } Displaying a list of Azure runtimes in the Azure CLI. Step 2: Build the App

To build the React app, let’s run npm build in the Terminal.

Step 3: Initialize the Git repo

Navigate into the build folder and initialize a Git repo in there. The URL to clone the repo is in the overview page. Depending on what credentials you’re using (App or User), it will be slightly different.

Showing the overview of the App Service on Azure and the Git clone URL. git init git add . git commit -m "Initial Commit" git remote add azure <git clone url> git push azure master

Now, visit the live app by using the URL on the overview page. As you can see, the app fails on /page2 refresh. Looking at the network tab, a 404 is thrown because the page tried to be fetched from the server — with client-side routing, as we have already set up, the page shouldn’t even be server fetched at all.

Showing the failed page request and the network tab to verify. Configuring Azure to reconcile client and server side routing

In the public folder, let’s add a web.config XML file with the following content:

<?xml version="1.0"?> <configuration> <system.webServer> <rewrite> <rules> <rule name="React Routes" stopProcessing="true"> <match url=".*" /> <conditions logicalGrouping="MatchAll"> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" /> </conditions> <action type="Rewrite" url="/" /> </rule> </rules> </rewrite> </system.webServer> </configuration>

I’ve intentionally decided to not format the code snippet because XML is strict about that. If you miss the formatting, the file has no effect. You can download an XML formatter for your text editor. For VSCode, that would be the XML Tools plugin.

Showing an XML formatter and an XML formatted file in VSCode.

The app can be built again at this point, although we’ll lose the Git info in the build folder since the new build overrides the old build. That means it would have to be added again, then pushed.

Now the app works as shown below! Whew.

We don’t want to have to npm run build every time — that’s where continuous deployment comes in. Check out the link below for appropriate references.

Conclusion

There is a lot to Azure, as it can do a lot for you. That’s nice because there are times when you need it to do something that seems super specific — as we’ve seen here with client and server side routing reconciliation — and it already has your back.

That said, I’ll leave you with a couple of related resources you can turn to as you look to deploying a React app to Azure.

The post Deploying a Client-Side Rendered create-react-app to Microsoft Azure appeared first on CSS-Tricks.

Categories: Web Technologies

Pages