Selenium C# Tutorial: Using Implicit Wait in Selenium
Strategy

Selenium C# Tutorial: Using Implicit Wait in Selenium


While designing test automation scripts, it is quite imperative that we consider all the major challenges that might come while performing Selenium test automation. There are certain scenarios where the test script is trying to perform an operation on an element that is not loaded (or not yet visible) and the test ends up failing due to this. This happens as the web elements on the page are loaded dynamically via AJAX (Asynchronous JavaScript and XML) and JavaScript or any other front-end framework.

To tackle this issue we have ‘Wait’, which is one of the most important and widely used commands in Selenium test automation. It helps us to provide us ample wait or pause time in our script execution. Thereby ensuring that our scripts don’t fail while performing automation testing with Selenium.

In this article we will talk about what are Selenium waits, why are they important, & how to implement an Implicit Wait in Selenium C# with examples.

What Are Waits In Selenium?

Selenium WebDriver is said to have a blocking API. It is an out-of-process library that instructs the web browser what exactly needs to be done. On the other hand, the web platform has an asynchronous nature. This is the primary reason why the Selenium WebDriver does not track the real-time state of the DOM (Document Object Model).

Race conditions could occur in a scenario where the developer uses a Selenium command to navigate to a particular URL (or web page) and gets a No Element Found error while trying to locate the element. To overcome such issues that can lead to race conditions between the web browser and the WebDriver script, the WebDriverWait class in Selenium C# can be used.

Waits in Selenium enable the test execution to be paused for a specified time (ideally in a few seconds) to address issues that can occur due to time lag. The added delay is a counter-mechanism to ensure that the particular web element is loaded before any action is performed on the element.

Why Are Selenium ‘Waits’ Important?

The front-end of most of the web applications are built on JavaScript or AJAX, using frameworks such as React, Angular, or others that take a certain time for the web elements to load entirely on the browser.

When Selenium comes across operations on web elements that are still loading, it throws the ElementNotVisibleException. Selenium waits can resolve such problems.

In the code snippet, the test scenario for our Selenium C# tutorial is for flight search on a flight booking website, which generates a ‘NoSuchElementException’ when the search operation is performed using Selenium test automation script.

As the page load is not complete i.e. the search for flights from source to destination is in progress, the script fails to find the ‘Book Now’ button. This results in the ‘NoSuchElementException’ for our Selenium test automation script. 

There are different types of waits in Selenium C# namely – Implicit wait, Explicit wait, and Fluent Wait. In this Selenium C# tutorial, we will have cover the Implicit wait in Selenium C#.

What Are Implicit Waits In Selenium C#?

Now moving ahead with our Selenium C# tutorial, Some developers use the System.Threading.Thread.Sleep(msecs) command to suspend the execution of the currently executing thread for a specified duration (specified in milliseconds). Usage of System.Threading.Thread.Sleep is considered to be a bad practice. The downside of this approach is that the Selenium WebDriver waits for irrespective of whether the web element is found or not. Usage of System.Threading.Thread.Sleep is considered to be a bad practice.

The shortcomings of the System.Threading.Thread.Sleep can be overcome using Implicit wait in Selenium C#. Implicit wait in Selenium halts the execution of the WebDriver for a specified duration of time until the desired web element is located on the page.

Unlike System.Threading.Thread.Sleep, the Implicit wait in Selenium does not wait for the complete time duration. Implicit wait in Selenium is also referred to as dynamic wait. If the particular web element is located before the expiry of the specified duration, it proceeds to execute the next line of code in the implementation.

If the particular web element is not located within the time duration, ElementNotVisibleException or NoSuchElementException is raised. Hence, implicit wait in Selenium tells the Selenium WebDriver to wait for a particular time duration (passed as a parameter), before the exception is raised.

The advantage of using implicit wait in Selenium C# is that it is applicable for all the web elements specified in the Selenium test automation script till the time WebDriver instance (or IWebDriver object) is alive.

Syntax of implicit wait in Selenium C#

The default time value for the implicit wait is zero. Implicit wait polls for the presence of the web element every 500 milliseconds. Now to take our Selenium C# tutorial further, we move on to the features of implicit wait in Selenium test automation.

When To Use Implicit Wait In Selenium?

Though there are different types of Selenium waits (explicit wait and fluent wait), there are some key features that differentiate implicit wait in Selenium from other types of waits.

a. Implicit wait applies to all the web elements in the test script

b. It is ideal for test scenarios when we are sure that the web elements will be loaded (or visible) within a specified duration

Example of Implicit Wait in Selenium C#

To demonstrate implicit wait in Selenium C#, we take the same example of EaseMyTrip. The major difference is that we have added an implicit wait of 30 seconds.

As an implicit wait is added, a wait of 30 seconds is added to locate the ‘Book Now’ button. 

Due to this wait, the page load gets completed and we proceed with the flight ticket booking for our Selenium C# tutorial. 

Conclusion

In this Selenium C# tutorial, we had a look at why implicit wait in Selenium is necessary for Selenium test automation. The primary usage of Implicit wait in Selenium is to add a certain amount of delay of loading of the required web elements before an operation is performed on the element. Happy testing!



Source link

The Fastest Google Fonts – CSS Wizardry – Web Performance Op...
Strategy

The Fastest Google Fonts – CSS Wizardry – Web Performance Op…


Written by on CSS Wizardry.

Table of Contents
  1. Testing
  2. Default/Legacy
  3. font-display: swap;
  4. Async CSS
  5. preload
  6. preconnect
  7. Bonus: font-display: optional;
  8. Comparisons and Visualisations
  9. Findings
  10. Google Fonts Async Snippet

For the most part, web fonts nowadays are faster than ever. With more
standardised FOUT/FOIT behaviour from browser vendors, to the newer
font-display specification, performance—and therefore the user—seems to have
been finally been put front-and-centre.

It’s widely accepted that self-hosted fonts are the fastest option: same origin
means reduced network negotiation, predictable URLs mean we can preload,
self-hosted means we can set our own cache-control
directives
, and
full ownership mitigates the risks that come with leaving static assets on
third-party
origins
.

That said, the convenience of a service like Google Fonts cannot be overstated.
Their ability to serve the tiniest possible font files tailored to specific user
agents and platforms is amazing, and with such a huge, freely-available library
served from Google-grade CDNs… I definitely see why people continue to turn to
it.

On this site, in which performance is the only name of the game, I forgo web
fonts entirely, opting instead to make use of the visitor’s system font. This is
fast, incredibly well suited to the device in question, and has almost zero
engineering overhead. But, on harry.is, I really wanted to
throw caution to the wind. To hell with it! Let’s have a web font!

However, I still needed to be fast.

While prototyping, I turned to Google Fonts, and with their recent ability to
support font-display via a URL parameter (&display=swap), I knew that things
would stay pretty speedy. Then I had an idea.

It started with a tweet:

While font-display: swap; is a huge win, there are still a lot of things
leaving me feeling uneasy. What else could I do to make Google Fonts fast?

Suffice to say, I ended up going down a little rabbit hole…

Testing

I ran the same suite of tests against the harry.is and
csswizardry.com homepages. I started out with
harry.is because that’s where I was using Google Fonts, but I felt it was a page
too simple to be realistic. So, I cloned the CSS Wizardry homepage a bunch of
times and implemented the various different methods there. For each of section
of this post, I will list the results for both sites. My variants are:

  • Legacy: Google Fonts with no font-display.
  • font-display: swap;: Using Google Fonts’ new-default.
  • Async CSS: Loading the Google Fonts File asynchronously.
  • preload: preloading the CSS file to increase its priority.
  • preconnect: Warming up the fonts.gstatic.com origin myself.

Further, each variant is additive—it includes the previous variant as well as
its own additions. I didn’t try just preload or just async, because it
would be pointless—we know that a combination will fare better than any on their
own.

For each test, I captured the following metrics:

  • First Paint (FP): To what extent is the critical path affected?
  • First Contentful Paint (FCP): How soon can we actually read something,
    whether it’s a web font or not?
  • First Web Font (FWF): At what point has the first web font loaded?
  • Visually Complete (VC): When has everything settled down (a proxy, but not
    equivalent to, Last Web Font)?
  • Lighthouse Score: Does it even count if it wasn’t on Lighthouse?

N.B. All tests were conducted using a private WebPageTest instance
(WebPageTest is down right now so I was unable to use the public instance, which
means I can’t share any URLs—apologies). The specific profile was a Samsung
Galaxy S4 over 3G.

To make the snippets easier to read, I’m going to replace all instances of
https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,700;1,400;1,700
with $CSS.

Default/Legacy

Google Fonts played a really great move in the last year or so. By default, any
newly created Google Font snippet comes with the &display=swap parameter that
injects font-display: swap; into all of the @font-face at-rules. The value
of the parameter can be any of swap, optional, fallback, or block. You
can read more on
MDN
.

For my baseline, however, I was going to trim the font-display back off. This
is the legacy format that a lot of sites will likely still use, and it makes for
a more suitable baseline to compare against.

Snippet:

<link rel="stylesheet"
      href="$CSS" />

There are two key issues here:

  1. A synchronous, ergo render-blocking, CSS file on a third-party origin.
  2. A file containing @font-face at-rules with no font-display descriptors.

It’s synchronous on top of synchronous—not good.

Results (s) – harry.is:

FP FCP FWF VC Lighthouse
3.4 4.6 4.9 5.0 98

Results (s) – CSS Wizardry:

FP FCP FWF VC Lighthouse
3.4 4.3 4.4 4.4 96

Alright. Here’s our baseline. The Google Fonts file is the only render-blocking
external resource either of the two tests has, and we can see they both have the
exact same first paint. One thing I was happily surprised by during these
experiments was the consistency of Google Fonts.

At this point, Lighthouse is giving one error and one warning:

  • (Error) Ensure text remains visible during webfont load
  • (Warning) Eliminate render-blocking resources

The first is a result of not having a web font loading solution (e.g.
font-display); the second is a result of the synchronous Google Fonts CSS
file.

Now, let’s start adding some progressive changes and, hopefully, improvements.

font-display: swap;

For this test, I added the &display=swap back in. In effect, this makes the
font files themselves asynchronous—the browser immediately displays our fallback
text before swapping to the web font whenever it arrives. This means we’re not
going to leave users looking at any invisible text (FOIT), which makes for both
a faster and more pleasant experience.

N.B. It’s only more pleasant if you make the effort to define a suitable
fallback to display in the interim—flashing a page full of Times New Roman
before settling on Open Sans would likely be a net worse experience. Thankfully,
Monica has made this process not only easy,
but surprisingly fun. I wouldn’t be able to do this bit without her Font Style
Matcher
.

Snippet:

<link rel="stylesheet"
      href="$CSS&display=swap" />

Results – harry.is:

  FP FCP FWF VC Lighthouse
  3.4 3.4 5.0 5.2 99
Change from Baseline: 0 -1.2 +0.6 +0.2 +1

Results – CSS Wizardry:

  FP FCP FWF VC Lighthouse
  3.6 3.6 4.6 4.6 95
Change from Baseline: +0.2 -0.7 +0.2 +0.2 -1

We haven’t removed any render-blocking resources from the critical path, so
I wasn’t expecting to see any improvements in first paint. In fact, while
harry.is remained identical, CSS Wizardry got 200ms slower. What we do see,
however, is a dramatic improvement in first contentful paint—over a second
on harry.is! First web font improved by 100–200ms, yet visually complete was
200ms slower.

I’m happy to say, for the metrics that matter the most, we are 700–1,200ms
faster
.

While this does massively improve the time it takes the web font to render, it’s
still defined inside a synchronous CSS file—we can only expect so much
improvement from this move.

Predictably, Lighthouse now only gives one warning:

  • (Warning) Eliminate render-blocking resources

Therefore, the next step is to solve the synchronous CSS file.

To quote, err, myself: If you’re going to use font-display for your Google
Fonts then it makes sense to asynchronously load the whole request chain.
It
was this initial thought that led to my tweet in the first place—if I’ve
effectively made the contents of the CSS file asynchronous, then it kinda sucks
to leave the CSS file itself fully synchronous.

font-display: swap; is a good idea.

Async CSS

Making your CSS asynchronous is one of the key techniques involved in employing
Critical CSS. While there are a number of ways to achieve this, I’d dare say the
simplest and most ubiquitous is Filament Group’s print media type
trick
.

This will implicitly tell the browser to load the CSS file in a non-blocking
fashion, applying the styles only to the print context. However, the moment the
file arrives, we tell the browser to apply it to all contexts, thus styling
the rest of the page.

Snippet:

<link rel="stylesheet"
      href="$CSS&display=swap"
      media="print" onload="this.media='all'" />

While the trick is devilishly simple—which is what makes it so cool—I’ve long
had my reservations
. Y’see, a regular, synchronous stylesheet blocks
rendering, so a browser will assign it Highest priority. A print stylesheet
(or any stylesheet that doesn’t match the current context) is assigned the
priority at the complete opposite end of the spectrum: Idle.

This means that as browsers begin making requests, the asynchronous CSS file
often gets grossly under-prioritised (or rather, it’s prioritised correctly, but
probably way less than you expect). Take for example Vitamix, a client for whom
I implemented asynchronous CSS for their own font provider(s):

While Chrome can do asynchronous DNS/TCP/TLS, it will serialise and
stall non-critical requests on slower connections.

The browser is doing exactly what we told it: request these CSS files with
a print-stylesheet’s worth of priority. Thus, on a 3G connection, it takes over
nine seconds to download each file. The browser puts almost everything else,
including in-body resources, ahead of our print stylesheets. This means that
the page in question didn’t render its custom font until an eyewatering 12.8s on
3G.

Thankfully, while dealing with web fonts, this isn’t the end of the world:

  • they should always be considered an enhancement anyway, so we need to be able
    to cope without them;
  • we can and should design decent fallbacks for use during their absence, and;
  • if we expect delays of such severity, we should use font-display: optional;.

For below the fold CSS, however, delays of almost 10 seconds are
unacceptable—it’s almost 100% certain that a user will have scrolled within that
timeframe.

Still! What happens to Google Fonts if we load it asynchronously?

Results – harry.is:

  FP FCP FWF VC Lighthouse
  1.8 1.8 5.0 5.1 100
Change from Baseline: -1.6 -2.8 +0.6 +0.1 +2
Change from Previous: -1.6 -1.6 0 -0.1 +1

Results – CSS Wizardry:

  FP FCP FWF VC Lighthouse
  1.7 2.2 4.9 5.0 99
Change from Baseline: -1.7 -2.1 +0.5 +0.6 +3
Change from Previous: -1.9 -1.4 +0.3 +0.4 +4

These results are tremendous.

I’m really happy with these outcomes. First paint was a staggering 1.6–1.7s
improvement
on our baseline, and up to a 1.9s improvement on the previous
variant
in the case of CSS Wizardry. First contentful paint was improved as
much as 2.8s
against our baseline, and Lighthouse scores hit 100 for the
first time.

As far as the critical path is concerned, this was a huge win.

However—and this is a big however—as a result of lowering the priority of the
CSS file, our first web font is up to 500ms slower in the case of CSS
Wizardry against our baseline. This is the danger of the print media hack.

Asynchronously loading Google Fonts is a net good idea, but reducing the
priority of the CSS file has actually slowed down the rendering of our custom
font.

I’m going to say that asynchronous CSS is an overall good idea but I need to
somehow mitigate the priority issue.

preload

Okay, so if print CSS is too low priority, what we need is a high priority
asynchronous fetch. Enter preload.

Complementing our media-trick stylesheet with a preload ensures we get the
best of all worlds:

  1. an asynchronous high priority fetch that will work in almost all modern
    browsers, and;
  2. a very widely supported method for reapplying CSS that we loaded
    asynchronously.

N.B. We can’t go full preload as it isn’t widely enough supported. In
fact, at the time of writing, about 20% of this site’s visitors would be unable
to make use of it. Consider the print stylesheet a fallback.

Snippet:

<link rel="preload"
      as="style"
      href="$CSS&display=swap" />

<link rel="stylesheet"
      href="$CSS&display=swap"
      media="print" onload="this.media='all'" />

N.B. In future, we should be able to use Priority Hints to solve this issue.

Results – harry.is:

  FP FCP FWF VC Lighthouse
  1.8 1 .8 5.0 5.3 100
Change from Baseline: -1.6 -2.8 +0.6 +0.3 +2
Change from Previous: 0 0 0 +0.2 0

Results – CSS Wizardry:

  FP FCP FWF VC Lighthouse
  2.0 2.0 4.3 4.3 98
Change from Baseline -1.4 -2.3 -0.1 -0.1 +2
Change from Previous +0.3 -0.2 -0.6 -0.7 -1

While first paint either remained the same or got slower, first contentful
paint either remained the same or got faster
, and in the case of CSS Wizardry,
first web font was a staggering 600ms faster than the previous iteration.

In the case of harry.is, almost nothing changed since our previous variant.
Visually complete was 200ms faster, but any first- metrics were untouched.
It was seeing these results that actually spurred me to also test against CSS
Wizardry. Because harry.is is such a small and simple page, there wasn’t much
network contention for a print stylesheet to yield to—changing its priority
didn’t really help it out much at all.

In the case of CSS Wizardry, we see first paint 300ms slower, which is
unexpected but unrelated (there is no render blocking CSS, so changing the
priority of an asynchronous CSS file can have no bearing here—I’m going to chalk
it up to an anomaly in testing). Happily, first contentful paint improved by
200ms
, first web font was 600ms faster, and visually complete was 700ms
faster
.

preloading Google Fonts is a good idea.

preconnect

The last piece of the puzzle I wanted to solve the trip to yet-another origin.
While we link out to fonts.googleapis.com for our CSS, the font files
themselves are hosted on fonts.gstatic.com. On a high-latency connection, this
spells bad news.

Google Fonts are good to us—they preconnect the fonts.gstatic.com origin
preemptively via an HTTP header attached to the fonts.googleapis.com response:

While not all that effective in these demos, I wish more third-party
providers would do things like this.

However, the execution of this header is bound by the response’s TTFB, which on
high-latency networks can be very, very high. The median TTFB (including request
queueing, DNS, TCP, TLS, and server time) for the Google Fonts CSS file across
all tests was 1406ms. Conversely, the median download time for the CSS file was
just 9.5ms—it took 148× longer to get to the headers of the file than it did to
download the file itself.

Put another way: even though Google are preconnecting the fonts.gstatic.com
origin for us, they’re only gaining about a 10ms head-start. Put another-other
way, this file is latency-bound, not
bandwidth-bound
.

If we implement a first-party preconnect, we should stand to make some pretty
huge gains. Let’s see what happens.

Snippet:

<link rel="preconnect"
      href="https://fonts.gstatic.com"
      crossorigin />

<link rel="preload"
      as="style"
      href="$CSS&display=swap" />

<link rel="stylesheet"
      href="$CSS&display=swap"
      media="print" onload="this.media='all'" />

We can visualise the benefits well in WebPageTest:

See just how much we can bring connection overhead forward with
preconnect.

Results – harry.is:

  FP FCP FWF VC Lighthouse
  1.8 1.8 3.8 4.4 100
Change from Baseline -1.6 -2.8 -0.6 -0.6 +2
Change from Previous 0 0 -1.2 -0.9 0

Results – CSS Wizardry:

  FP FCP FWF VC Lighthouse
  1.9 1.9 3.5 3.6 99
Change from Baseline -1.5 -2.4 -0.9 -0.8 +3
Change from Previous -0.1 -0.1 -0.8 -0.7 +1

Here we go! First (contentful) paint is realistically untouched. Any changes
here are unrelated to our preconnect at the preconnect only impacts
resources after the critical path. Our focus is on first web font and visually
complete, both of which show tremendous improvement. 800–1,200ms improvement on
first web font
and 700–900ms improvement on visually complete against our
previous variant, and 600–900ms and 600–800ms respective improvements against
our baseline. Lighthouse scores are sitting pretty at 100 and 99.

preconnecting fonts.gstatic.com is a good idea.

Bonus: font-display: optional;

Using asynchronous CSS and font-display leaves us susceptible to FOUT (or,
hopefully, FOFT if we’ve designed our Fallbacks properly). To try and
mitigate this, I decided to run a test using font-display: optional;.

This variation tells the browser that web fonts are considered optional, and if
we can’t get hold of the font files during our extremely small block
period
then we offer no swap period. The practical upshot of which is
that in the event that the web fonts takes too long to load, that pageview won’t
utilise it at all. This helps to prevent the FOUT which will in turn lead to
a more stable experience for your user—they won’t see text restyle part-way
through their pageview—and a better Cumulative Layout Shift score.

However, this proved consistently troublesome when using asynchronous CSS. When
the print stylesheet gets turned into an all stylesheet, the browser updates
the CSSOM then applies it against the DOM. In this moment, the page is told it
needs some web fonts, and the extremely small block period kicks in,
showing a FOIT midway through the page load lifecycle. To make things worse, the
browser will replace the FOIT with the same fallback it started with, so the
user doesn’t even get the benefit of a new font. It basically looks like a bug.

It’s much easier to visualise it than it is to explain, so here’s a screenshot
of the filmstrip:

Screenshot
showing missing text midway through two separate page loads.
Note the FOIT at 3.4–3.5s and 3.2s respectively.

And a video showing the issue in DevTools:

Can’t see the
video? Click here.

I would not recommend using font-disply: optional; alongside asynchronous
CSS
; I would recommend using asynchronous. Ergo, I would not recommend
font-display: optional;. It’s better overall to have non-blocking CSS with
a FOUT than it is to have the needless FOIT.

Comparisons and Visualisations

In these slow-motion videos, you can see the differences quite clearly.

harry.is

Can’t see
the video? Click here.
  • Async, preload, and preconnect all start rendering at 1.8s.
    • This also represents their first contentful paints—useful information in the
      first render.
  • Legacy and swap both start rendering at 3.4s.
    • Though legacy is missing any text—FOIT.
  • preconnect loads its web font at 3.8s.
    • It’s deemed visually complete at 4.4s.
  • Legacy makes its first contentful and first web font paint at 4.5s.
    • They’re one and the same as everything is synchronous.
  • Legacy’s visually complete is at 5s.
  • Async’s visually complete comes in at 5.1s.
  • swap is deemed complete at 5.2s.
  • preload is deemed visually complete at 5.3s.

CSS Wizardry

Can’t
see the video? Click here.

  • Async starts rendering at 1.7s.
  • preconnect starts rendering at 1.9s.
    • Its first contentful paint is also 1.9s—useful information in the first
      render.
  • preload starts rendering at 2s.
    • Its first contentful paint is also at 2s.
  • Async renders content at 2.2s.
  • Legacy starts rendering at 3.4s.
  • swap makes it first- and first contentful paint at 3.6s.
  • preconnect is deemed visually complete at 3.6s.
  • Legacy makes its first contentful paint at 4.3s.
  • preload is visually complete at 4.3s.
  • Legacy is considered visually complete at 4.4s.
  • swap completes at 4.6s.
  • Async comes in last at 5s.

preconnect is fastest across all metrics

Findings

While self-hosting your web fonts is likely to be the overall best solution to
performance and availability problems, we’re able to design some fairly
resilient measures to help mitigate a lot of these issues when using Google
Fonts.

A combination of asynchronously loading CSS, asynchronously loading font files,
opting into FOFT, fast-fetching asynchronous CSS files, and warming up external
domains makes for an experience several seconds faster than the baseline.

This is something that I strongly recommend adopting if you are a Google Fonts
user.

If Google Fonts isn’t your only render-blocking resource, if and you’re
violating any of the other principles for fast
CSS
(e.g. if
you’re @importing your Google Fonts CSS file), then your mileage will vary.
These optimisations are most beneficial on project where Google Fonts is posing
one of your biggest performance bottlenecks.

Google Fonts Async Snippet

There a lot of techniques combined here, but the resulting code is still slim
and maintainable enough that it should’t pose a problem. The snippet doesn’t
need breaking apart and can all be kept together in the <head> of your
document.

Here is the optimum snippet to use for fast Google Fonts:

<!--
  - 1. Preemptively warm up the fonts’ origin.
  -
  - 2. Initiate a high-priority, asynchronous fetch for the CSS file. Works in
  -    most modern browsers.
  -
  - 3. Initiate a low-priority, asynchronous fetch that gets applied to the page
  -    only after it’s arrived. Works in all browsers with JavaScript enabled.
  -
  - 4. In the unlikely event that a visitor has intentionally disabled
  -    JavaScript, fall back to the original method. The good news is that,
  -    although this is a render-blocking request, it can still make use of the
  -    preconnect which makes it marginally faster than the default.
  -->

<!-- [1] -->
<link rel="preconnect"
      href="https://fonts.gstatic.com"
      crossorigin />

<!-- [2] -->
<link rel="preload"
      as="style"
      href="$CSS&display=swap" />

<!-- [3] -->
<link rel="stylesheet"
      href="$CSS&display=swap"
      media="print" onload="this.media='all'" />

<!-- [4] -->
<noscript>
  <link rel="stylesheet"
        href="$CSS&display=swap" />
</noscript>


☕️ Did this help? Buy me a coffee!





Source link

Post image
Strategy

Aligning text lines across columns-InDesign CC : graphic_des…


Is there a way to align the lines of text across the columns in InDesign? I want the lines in all columns to be even with the green line in the photo. Is there a setting I can change to make that happen, or is it a spacing issue, or the font (font can’t change)? It’s bothering me because the bottom text of the page isn’t always aligning so it looks ragged. I can’t figure out the correct wording to google search and find what I want.

I’m using Museo Sans 300 – size 8/12 – paragraph style is set to first line indent .0725, space before .0825, no hyphenation, left align. A no break GREP style set to force at least 16 characters on the last line of a paragraph. No special character styles in this particular story of the magazine.

Post image



Source link

Announcing Codepen Support For Flutter: How That Works For D...
Strategy

Announcing Codepen Support For Flutter: How That Works For D…


What to expect when the front end development playground meets the best app development framework?

If you are a coder or a developer, then you would have already encountered inspirational issues. CodePen has been for the developers or designers what Dribble is. When developers run out of feature ideas, they go to CodePen. But, when CodePen announced support for Flutter, things got interesting!

According to AppBrain, Flutter based apps amount to 0.52% of new apps developed today. It also has an overall market share of 0.24%. It is quite popular as a UI framework. With official support for the CodePen, It will be a great framework for developers.

But, before we dive into how the fusion of these two giants of development can work for you, let’s get to know them independently.

What is CodePen?

 

 

It is a social platform for frontend developers. It is an open-source platform. Here, users can upload their custom CSS, Javascript, and HTML snippets. They can test and share these snippets. These snippets or Pens are shareable in an open environment. It has a free version and a professional paid version for frontend development teams.

Pens or snippets are synced with the changes made by developers in real-time. So, developers can visualize the changes they make. Developers can even change public pens. 

They can browse these snippets through a huge collection on site. It is a great platform for designers and developers to explore new coding ideas. They can even learn new forms of snippets.

What Is Flutter?

Flutter is an amazing development framework. It is a framework with the Dart programming language base.  The Dart language has a Javascript base. So, CodePen remains an ideal partner for Flutter. Because CodePen allows developers/designers to test and share Javascript snippets,

It helps developers visualize their user interface through widget-trees. The UI components are in the form of widgets. Any change in the widget is effectively integrated into the application. Thus, any developer can easily create widgets to change features.

It has extensive support to the frontend through the sound backend. It is an ideal framework due to Firebase. Firebase is a Backend as a Service (BaaS). So, choosing flutter app development services for your project is not a bad idea! And the combination of CodePen with Flutter can prove to be worth a go. Let’s discover how?

Flutter Editor in Codepen:

Flutter has been disrupting the app development markets. Since, its inception, it has partnered with Adobe and SuperNova through Flutter interactive events. But, partnering with CodePen will be more creative prowess. Now, developers can access Flutter environments based on CodePen. It can mean a huge difference. As it will help them visualize the design, and showcase new features.

Flutter editor in CodePen is built on the same scale as that of a DartPad. The backend services offered by Dart to DartPad are excellent. And it uses the same backend services. Flutter introduced DartPad for similar purposes as that of CodePen.

With DartPad, developers can learn, code, test, and share snippets. It is an open-source editor. So, the exchange od snippet idea becomes easy. Flutter wanted DartPad to be the ideal tool for platforms like CodePen.

CodePen’s Flutter editor works best for design inspiration. The editor will allow you to use the CodePen’s platform to experiment with new ideas. Thes ideas can boost designs and feature inspiration. while you can use DartPad to rapidly test the code ideas and create greater technical features. 

As we understood what is exactly a Flutter editor and DartPad? Let’s understand step by step guide for using the editor in CodePen.

Using Flutter Editor: Step 1

You may need to signup or if an existing member then login to your CodePen account. Once logged in, you can start to create your Flutter Pen or a snippet from scratch. You can change the format, visualize the snippet, and even test them in Flutter.

Flutter editor in Codepen

Another way of creating a Flutter pen is by editing an existing template. As the CodePen is an open-source community, there are millions of Pens to edit. You can choose anyone and edit them. You can tweak them for your use. You can even view it as a compilation and test them in Flutter environments.

Flutter editor in codepen

Take an example of the above template. Here, you can edit the colors and design through a tweak in the code. For, example if you change the color of page indicator circle from “White” to “Purple” in code line 326, you can see the effects in real-time. You can even change the color of the border of those page indicators in code line 328.

Flutter editor in codepen

Compiler and Analyzer: Step 2

The editor comes with an in-built compiler and analyzer. If you want to see all the snippets in a compiled view, then you need to tap on to the menu and select “View CompiledJS”. Once you select the option, it will automatically show a compilation of the entire code.

Compiled code

Now, if you want to analyze your Flutter Pen for any errors than got to the menu → Select “Analyze Flutter”. Once you select the option for the analyzer, the system will analyze snippets. As the analysis is over, it shows a message stating that there are no errors. 

Code analysis

If there is any error, the editor indicates that with a red bar. So, you can make the necessary changes.

Conclusion

Flutter was already a cool framework for developers. And now it has become more exciting. Developers can enjoy experimenting with Flutter animations, designs, and creating widgets. But, for a business point of view, Flutter is now more powerful than ever.

Feel free to share with us in the below comment section!



Source link

1,609 requests, 55.8 megabytes transferred, 57.5 megabytes resources, load time of 30.45 seconds.
Strategy

Let’s Make One of Those Fancy Scrolling Animations Used on A…


Apple is well-known for the sleek animations on their product pages. For example, as you scroll down the page products may slide into view, MacBooks fold open and iPhones spin, all while showing off the hardware, demonstrating the software and telling interactive stories of how the products are used.

Just check out this video of the mobile web experience for the iPad Pro:

A lot of the effects that you see there aren’t created in just HTML and CSS. What then, you ask? Well, it can be a little hard to figure out. Even using the browser’s DevTools won’t always reveal the answer, as it often can’t see past a <canvas> element.

Let’s take an in-depth look at one of these effects to see how it’s made so you can recreate some of these magical effects in our own projects. Specifically, let’s replicate the AirPods Pro product page and the shifting light effect in the hero image.

The basic concept

The idea is to create an animation just like a sequence of images in rapid succession. You know, like a flip book! No complex WebGL scenes or advanced JavaScript libraries are needed.

By synchronizing each frame to the user’s scroll position, we can play the animation as the user scrolls down (or back up) the page.

Start with the markup and styles

The HTML and CSS for this effect is very easy as the magic happens inside the <canvas> element which we control with JavaScript by giving it an ID.

In CSS, we’ll give our document a height of 100vh and make our <body> 5⨉ taller than that to give ourselves the necessary scroll length to make this work. We’ll also match the background color of the document with the background color of our images.

The last thing we’ll do is position the <canvas>, center it, and limit the max-width and height so it does not exceed the dimensions of the viewport.

html {
  height: 100vh;
}


body {
  background: #000;
  height: 500vh;
}


canvas {
  position: fixed;
  left: 50%;
  top: 50%;
  max-height: 100vh;
  max-width: 100vw;
  transform: translate(-50%, -50%);
}

Right now, we are able to scroll down the page (even though the content does not exceed the viewport height) and our <canvas> stays at the top of the viewport. That’s all the HTML and CSS we need.

Let’s move on to loading the images.

Fetching the correct images

Since we’ll be working with an image sequence (again, like a flip book), we’ll assume the file names are numbered sequentially in ascending order (i.e. 0001.jpg, 0002.jpg, 0003.jpg, etc.) in the same directory.

We’ll write a function that returns the file path with the number of the image file we want, based off of the user’s scroll position.

const currentFrame = index => (
  `https://www.apple.com/105/media/us/airpods-pro/2019/1299e2f5_9206_4470_b28e_08307a42f19b/anim/sequence/large/01-hero-lightpass/${index.toString().padStart(4, '0')}.jpg`
)

Since the image number is an integer, we’ll need to turn it in to a string and use padStart(4, '0') to prepend zeros in front of our index until we reach four digits to match our file names. So, for example, passing 1 into this function will return 0001.

That gives us a way to handle image paths. Here’s the first image in the sequence drawn on the <canvas> element:

As you can see, the first image is on the page. At this point, it’s just a static file. What we want is to update it based on the user’s scroll position. And we don’t merely want to load one image file and then swap it out by loading another image file. We want to draw the images on the <canvas> and update the drawing with the next image in the sequence (but we’ll get to that in just a bit).

We already made the function to generate the image filepath based on the number we pass into it so what we need to do now is track the user’s scroll position and determine the corresponding image frame for that scroll position.

Connecting images to the user’s scroll progress

To know which number we need to pass (and thus which image to load) in the sequence, we need to calculate the user’s scroll progress. We’ll make an event listener to track that and handle some math to calculate which image to load.

We need to know:

  • Where scrolling starts and ends
  • The user’s scroll progress (i.e. a percentage of how far the user is down the page)
  • The image that corresponds to the user’s scroll progress

We’ll use scrollTop to get the vertical scroll position of the element, which in our case happens to be the top of the document. That will serve as the starting point value. We’ll get the end (or maximum) value by subtracting the window height from the document scroll height. From there, we’ll divide the scrollTop value by the maximum value the user can scroll down, which gives us the user’s scroll progress.

Then we need to turn that scroll progress into an index number that corresponds with the image numbering sequence for us to return the correct image for that position. We can do this by multiplying the progress number by the number of frames (images) we have. We’ll use Math.floor() to round that number down and wrap it in Math.min() with our maximum frame count so it never exceeds the total number of frames.

window.addEventListener('scroll', () => {  
  const scrollTop = html.scrollTop;
  const maxScrollTop = html.scrollHeight - window.innerHeight;
  const scrollFraction = scrollTop / maxScrollTop;
  const frameIndex = Math.min(
    frameCount - 1,
    Math.floor(scrollFraction * frameCount)
  );
});

Updating <canvas> with the correct image

We now know which image we need to draw as the user’s scroll progress changes. This is where the magic of  <canvas> comes into play. <canvas> has many cool features for building everything from games and animations to design mockup generators and everything in between!

One of those features is a method called requestAnimationFrame that works with the browser to update <canvas> in a way we couldn’t do if we were working with straight image files instead. This is why I went with a <canvas> approach instead of, say, an <img> element or a <div> with a background image.

requestAnimationFrame will match the browser refresh rate and enable hardware acceleration by using WebGL to render it using the device’s video card or integrated graphics. In other words, we’ll get super smooth transitions between frames — no image flashes!

Let’s call this function in our scroll event listener to swap images as the user scrolls up or down the page. requestAnimationFrame takes a callback argument, so we’ll pass a function that will update the image source and draw the new image on the <canvas>:

requestAnimationFrame(() => updateImage(frameIndex + 1))

We’re bumping up the frameIndex by 1 because, while the image sequence starts at 0001.jpg, our scroll progress calculation starts actually starts at 0. This ensures that the two values are always aligned.

The callback function we pass to update the image looks like this:

const updateImage = index => {
  img.src = currentFrame(index);
  context.drawImage(img, 0, 0);
}

We pass the frameIndex into the function. That sets the image source with the next image in the sequence, which is drawn on our <canvas> element.

Even better with image preloading

We’re technically done at this point. But, come on, we can do better! For example, scrolling quickly results in a little lag between image frames. That’s because every new image sends off a new network request, requiring a new download.

We should try preloading the images new network requests. That way, each frame is already downloaded, making the transitions that much faster, and the animation that much smoother!

All we’ve gotta do is loop through the entire sequence of images and load ‘em up:

const frameCount = 148;


const preloadImages = () => {
  for (let i = 1; i < frameCount; i++) {
    const img = new Image();
    img.src = currentFrame(i);
  }
};


preloadImages();

Demo!

A quick note on performance

While this effect is pretty slick, it’s also a lot of images. 148 to be exact.

No matter much we optimize the images, or how speedy the CDN is that serves them, loading hundreds of images will always result in a bloated page. Let’s say we have multiple instances of this on the same page. We might get performance stats like this:

1,609 requests, 55.8 megabytes transferred, 57.5 megabytes resources, load time of 30.45 seconds.

That might be fine for a high-speed internet connection without tight data caps, but we can’t say the same for users without such luxuries. It’s a tricky balance to strike, but we have to be mindful of everyone’s experience — and how our decisions affect them.

A few things we can do to help strike that balance include:

  • Loading a single fallback image instead of the entire image sequence
  • Creating sequences that use smaller image files for certain devices
  • Allowing the user to enable the sequence, perhaps with a button that starts and stops the sequence

Apple employs the first option. If you load the AirPods Pro page on a mobile device connected to a slow 3G connection and, hey, the performance stats start to look a whole lot better:

8 out of 111 requests, 347 kilobytes of 2.6 megabytes transferred, 1.4 megabytes of 4.5 megabytes resources, load time of one minute and one second.

Yeah, it’s still a heavy page. But it’s a lot lighter than what we’d get without any performance considerations at all. That’s how Apple is able to get get so many complex sequences onto a single page.


Further reading

If you are interested in how these image sequences are generated, a good place to start is the Lottie library by AirBnB. The docs take you through the basics of generating animations with After Effects while providing an easy way to include them in projects.





Source link

Post image
Strategy

Business card design concept : graphic_design


How are you guys doing? So i just started learning about the fundamentals of graphic design. I’ve made my first attempt to use actual strategy behind my art and i’d love some feedback on them. They are for a fictional business that offers design and programming services.

Post image

In the front i used splatter effects with triadic colors to symbolize art. The logo is a coding tag with a pencil instead of a slash (to symbolize art and coding) inside a honeycomb form (often used in sci-fi art). the coding wall is kinda glitching through to symbolize that there is programming behind it. In the back i used a rather formal style but with splatters of paint upper right (to mix formality with art).

Post image

In the second one, i used the image of Mona Lisa in ASCII to mix computing and art. I highlighted the phrase “programming meets art” in blue because blue symbolizes trust and because some lines of code (like functions in PHP) has this color. In the back i tried something simple and formal. There are three variation of the positioning of the logo (I couldn’t decide which one was the best).

Post image

In the last one, i tried something completely subtle and serious. I used triangular forms in the background because geometric forms often are related to mathematics. I’ve also chosen these fonts to give a mature aspect to the information.

This is my very first post in this subreddit, so if it was too long or too redundant i apologize and thank you for your patience.



Source link

Post image
Strategy

I created a Covid-19 3D Earth Data Visualisation Website : w…


Post image

I want to receive some feedback

About the Website

This is my first completed website: www.covid19earth.live

Let me know what you think!

This project took me roughly two weeks of full time programming to complete, involving the following:

  • Programming Language: Python

  • Framework: Django

  • JavaScript Libraries: Three.js

  • Paas: Heroku

  • Interaction with a couple of APIs: Google Maps (Reverse Geocoding), and a Covid-19 data API

The Intention

Covid-19 Earth 3D was created with the purpose of visualising correlations between Covid-19 case data, and additional global issues including:

  • Global Corruption

  • Systems of Government

  • Current Climate, and Climate Change

  • Global Wealth Distribution

  • Air Pollution

  • Population Density

Our perceptions of the pandemic are generated based on reported Covid-19 case data. Available data sets influence important decisions at all levels of society, determining pandemic prevention strategies all across the globe.

I believe it’s important to analyse the role global issues play in determining our understanding of the virus – allowing pandemic response plans to become more intelligent, and receptive to possible distortions in referenced case data.

Programming Problems

Personally, I enjoy experimenting with the capabilities of Three.js and WebGL despite encountering various performance issues. Load times for the website are reasonable, but certainly not desirable.

Known Issues:

  • Globe textures can take several moments to load

  • Selected data for some countries will not appear

  • Website is optimised for Desktop over Mobile



Source link

IPhone app presentation mockup
Strategy

IPhone app presentation mockup


IPhone app presentation mockup

I found that picture online and I am wondering if you guys know a Platform (free or not) that will allow me to upload a picture or a web-link and generate a great mockup like this?

https://preview.redd.it/iz42z64j3a051.png?width=960&format=png&auto=webp&s=065ac90c3e12d6a933bfa6fa65dc1042226731fa

submitted by /u/Klutzy-Jicama
[comments]



Source link

built my site using Hugo, but my logo does not appear
Strategy

built my site using Hugo, but my logo does not appear


built my site using Hugo, but my logo does not appear

I've build my site using Hugo, however, I'm having a hard time getting my logo to appear (which should be a straight forward html thing).

logo.png

header.html code:

https://preview.redd.it/rojdms09n7051.png?width=935&format=png&auto=webp&s=23528417c0a457d4545d6df3813892145d0278b1

Any suggestions?

submitted by /u/nightcrawler99
[comments]



Source link