【问题标题】:Image stretches to 100% while loading when server-side rendering在服务器端渲染时加载时图像拉伸到 100%
【发布时间】:2020-01-03 19:47:19
【问题描述】:

我有以下代码,它使用 Angular Material 使我的图像响应:

<picture [ngStyle.xs]="{'width': '100%'}" [ngStyle.gt-xs]="{'width': '448px', 'height': '60px'}">
  <source srcset="/assets/images/logo-text-lg.webp" type="image/webp" [ngStyle.xs]="{'width': '100%'}" [ngStyle.gt-xs]="{'width': '448px', 'height': '60px'}">
  <source srcset="/assets/images/logo-text-lg.png" type="image/png" [ngStyle.xs]="{'width': '100%'}" [ngStyle.gt-xs]="{'width': '448px', 'height': '60px'}">
  <img src="/assets/images/logo-text-lg.png" alt="TechScore" [ngStyle.xs]="{'width': '100%'}" [ngStyle.gt-xs]="{'width': '448px', 'height': '60px'}">
</picture>

我们的目标是让它精确到 448x60,除非它在一个超小的屏幕上。那么它应该是页面宽度的 100%。这个方法除了,因为我通过 Angular Universal 实现了服务器端渲染,即使在更大的屏幕上,我也能以 100% 的速度获得图像的闪光。

如果我查看源代码(禁用缓存),我可以看到来自服务器的标记包括 style="width: 100%",这意味着服务器端渲染版本认为屏幕特别小。

我如何让 Angular Universal 知道屏幕分辨率是多少,以及如何将该信息传递给 Angular Material 并覆盖它认为的分辨率,以便它选择正确的宽度?

更新

我认为我通过用户代理字符串检测它是否是移动浏览器然后设置默认断点,如下所述:https://github.com/angular/flex-layout/wiki/Using-SSR-with-Flex-Layout

FlexLayoutModule.withConfig({ssrObserveBreakpoints: [isMobile() ? 'xs' : 'md']})

但我一定做错了,因为我没有看到任何效果。

【问题讨论】:

  • 当您的页面通过 SSR 提供​​时,我认为 Angular 中的内容不可用。稍后,当水合作用发生时,所有的 ng 规则都会启动,你会得到预期的结果。我会建议,通过可以加载 SSR 的 CSS 来执行此操作并查看需求,它看起来并不多
  • 我同意 Praveen 的观点,我认为您将不得不为此使用 css。媒体查询是一种选择,您也可以使用max-width,尽管如果没有可重现的 sn-p,很难更具体。

标签: css angular responsive-design angular-material angular-universal


【解决方案1】:

您可以考虑使用 CSS 媒体查询来处理图像的响应式样式。然后不会将硬编码的内联样式发送到客户端。浏览器将确定如何最初呈现图像。在应用适当的样式之前,您不必等待 JavaScript 执行(flash!)。

这是一个例子:

<picture class="my-picture">
  <source srcset="/assets/images/logo-text-lg.webp" type="image/webp">
  <source srcset="/assets/images/logo-text-lg.png" type="image/png" >
  <img src="/assets/images/logo-text-lg.png" alt="TechScore">
</picture>
.my-picture, .my-picture img, .my-picture source {
  width: 448px;
  height: 60px;
}

@media only screen and (min-width : 480px) {
  .my-picture, .my-picture img, .my-picture source {
    width: 100%;
    height: auto;
  }
}

【讨论】:

  • 明尼苏达州的汤姆?我们一起工作了吗?我希望有一个解决方案适用于使用媒体断点的站点中的任何地方,但如果我无法弄清楚,这至少适用于该特定图像。谢谢。
  • 哈!嘿,亚当。多么疯狂的巧合!你不必给我同情票,因为你认识我 IRL。有人可能会用一个很好的方法来让 SSR 成型。但是,如果您积极缓存 SSR 资产的输出,则可能很难根据客户信息获得可变性。
  • 谢谢汤姆。您的解决方案非常适合图像,但我将添加一个赏金,看看我是否可以学习如何让断点为整个网站的内容工作。
  • 很公平。让我们看看人们怎么说。
【解决方案2】:

请尝试下面的 CSS 将保持比例。

 .img-fluid {
    max-width: 100%;
    height: auto;
     }

【讨论】:

    【解决方案3】:

    FlexLayout 可以 support server side rendering 有一定的限制。

    如果不先阅读此文档,我不会尝试使用它

    Angular Flex Layout - Server Side Rendering

    【讨论】:

      【解决方案4】:

      您可以在 Typescript 中设置一个变量来说明屏幕是否处于移动状态(按宽度),然后更改类。

      这是一个例子:

      isMobile = false;
      ngOnInit() {
          if (window.screen.width <= 480) { // 768px portrait
            this.isMobile = true;
          }
      }
      

      然后在您的模板中:

      <picture [ngClass.xs] = "isMobile">
       ...
      </picture>
      

      编辑:

      我看到您希望将屏幕尺寸输入服务器。除非您向他发送此数据并保存,否则服务器无法获取屏幕大小。您可以在客户端启动时将window.screen.width 发送到服务器,然后以您拥有的屏幕尺寸为特定用户提供服务。

      【讨论】:

      • 如果我从客户端发送它,那么进行服务器端渲染就没有意义了,因为客户端已经被渲染了。问题是如何在初始页面加载时通过 SSR 执行此操作。我不一定需要 exact 尺寸...我开始使用user-agent 字符串解决问题的方法会足够好,如果我可以让它工作的话。
      【解决方案5】:

      如果您想在整个站点中保持相同的大小。比它可能对你有帮助。

       <picture>
                <source srcset="/assets/images/logo-text-lg.webp" class="my-picture" type="image/webp">
                <source srcset="/assets/images/logo-text-lg.png" class="my-picture" type="image/png" >
                <img src="/assets/images/logo-text-lg.png" class="my-picture" alt="TechScore">
       </picture>
      
      <style>
              .my-picture {
                width: 448px;
                height: 60px;
              }
      
              @media only screen and (max-width : 480px) {
                .my-picture {
                  width: 100%;
                  height: auto;
                }
              }
      
             @media only screen and (max-width : 667px) {
                .my-picture {
                  width: 50%;
                  height: auto;
                }
              }
      
             @media only screen and (min-width : 668px) {
                .my-picture {
                  width: 448px;
                 height: 60px;
                }
              }
      
      </style>
      

      您可以根据自己的要求更改尺寸。

      【讨论】:

      • 这个答案似曾相识。
      猜你喜欢
      • 2021-03-23
      • 2022-10-01
      • 2018-09-26
      • 2019-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-05
      • 2018-05-30
      相关资源
      最近更新 更多