跳到主要内容

用Svelte和Sapper构建一个快速的反应性博客

Svelte and Sapper
+$(Image Credit: Svelte)

+$Sapper is a framework built on top of Svelte. It focuses on speed out of the box with server rendering, link preloading, and the ability to create service workers. Combined with Svelte, the end result is a highly customisable, lightning fast site with a small footprint.

+$In this tutorial, we will be using Sapper to build a lightweight blogging site using Svelte components (see our如何开始博客+$post for some less technical tips on blogging). Svelte is a framework with a difference. It analyses the code at compile time and creates a set of modules in vanilla JavaScript, which avoids the need for a runtime. If you need further help with layouts then check out our post on how to get the perfect网站布局

+$Download the tutorial files on FileSilo here

+$01. Install Dependencies

+$Firstly, we need to download and install dependencies. It relies on Svelte to work and requires another framework to build the server, but the rest depends on the application being built. In this case, we need a few packages to help extract Markdown files later on.

+$Download the tutorial files (above(, find them on the command line and install the dependencies.

+$> Npm Install

+$02. Build Out Server

+$Sapper is built in two parts – the client-side framework and the server-side rendering of that framework. This helps get that extra speed boost for those on slower networks. It is built using Node, which allows the Sapper middleware to do all the heavy lifting for us.

+$Open server.js and create the server with Express. Using their recommendations, we include+$compression+$to shrink the files we send and+$sirv+$to serve static files.

+$express() .use( compression({ threshold: 0 }), sirv(“static”, { dev }), sapper.middleware() ) .listen(PORT);

+$03. Mount The Application

+$On the client side, we need to tell Sapper where to mount the application. This is similar to React DOM’s给予+$or Vue’s+$$mount+$methods. Inside client.js, start Sapper and mount it to the root

+$element. That element is included in the template file, which we will come to later on.

+$import * as sapper from “@sapper/app”; sapper.start({ target: document.getElementById( “root”) });

+$04. Start the development server

Command line

+$Any errors during the development build process are flagged on the command line.

(图片来源:马特·克劳奇)

+$With the basic server and client files set up, we can start the development server. This kicks off a build of the server, client and service worker files, and it will start up on port 3000 by default. Whenever a file changes, it will rebuild the part of the application that changed.

+$Run the server on the command line. Keep this window open while developing the site.

+$> Npm Run Dev

+$05. Create a server route

+$Anything inside the “routes” directory will turn into a route for the application. Files with the.js文件+$extension will become what are called server routes. These routes have no UI, but instead are requested by the application to fetch data. In our case, we will use them to load up blog posts.

+$routes/blog/index.json.js+$file will create the+$/blog.json+$endpoint on our server. Import the blog posts and create some JSON from them.

+$import posts from “./_posts.js”; const contents = JSON.stringify( posts.map(post => ({ author: post.author, image: post.image, title: post.title, slug: post.slug })) );

+$06. Return the blog posts

+$Server routes export functions that correspond with HTTP methods. For example, to respond to a GET request, we would export a function called得到+$from the server route file. Create a得到+$function that responds with the data that we collected in the previous step in a JSON format. Open+$http://localhost:3000/blog.json+$in the browser and check the posts are coming through.

+$export function get(req, res) { res.writeHead(200, { “Content-Type”: “application/json” }); res.end(contents); }

+$07. Create Index Page

+$Pages in Sapper are regular Svelte components. Each component is a single file with a+$.svelte+$extension, and contain all the logic and styling for managing itself. Any JavaScript this component needs to run will live inside a

+$08. Fetch blog post data

+$With the page set up, we can start bringing in blog posts. We need to do this as soon as the page is loaded. In order for the server to be aware of this and then request this data when it renders the page, it needs to go in a separate+$

+$09. Display Post Summaries

+$In Svelte, variables are reactive by default. This means that, as they update, our components will also update too. As the帖子+$variable now holds an array of blog posts, we can loop over these and display them.

+$We can do this using an+$#each+$block. These will repeat what is inside the brackets for each item in an array. At the bottom of the component, outside of any tags, add the HTML to display the posts.

+$ 
    {#each posts as post}
  • {/each}

+$10. Style The Container

+$We can use components to contain any repeated logic and use them wherever they are needed – styles included. The+$+$component currently does not do anything, but we can use it to give a maximum width to the content inside it.

打开+$components/Container.svelte+$, and add some styles inside a

+$11. Define A

+$If a component is designed to be the parent to other components, we need a way to pass those components through. The+$+$element does just that, and can be placed anywhere that makes sense inside a component’s markup.

+$+$, we are wrapping the contents in a styled

+$. Use+$在 - 的里面
+$to let everything else through.

+$

+$12. Expose PostSummary Props

+$Not every component is going to fetch some data. As we are loading the posts from the main page component, it can be passed through to the components it renders through its attributes.

打开+$components/PostSummary.svelte+$and define some attributes at the top of the file. These are getting filled in by the spread operator we added in step 09.

+$

+$13. Display blog post summary

+$When the attributes are populated, they are then accessed like any other variable. By having separate attributes for each part of the post summary, we make the markup easier to read.

+$At the bottom of the component, add some HTML to create the summary. The classes relate to the pre-defined styles.

+$
{author.name}

{title}

by {author.name}

+$14.  Link to blog post

Sapper blog

+$Sapper can fetch the information for a link as the user hovers over it for a perceived performance benefit

(图片来源:马特·克劳奇)

+$Unlike similar frameworks such as Next.js, Sapper works with regular anchor links. At build time, it is able to detect internal links, and also to make its own optimisations.

+$Update the markup from the previous step by wrapping it in a link. There is no need for you to create template strings in order to compose the slugged URL.

+$ 

+$15. Fetch a post by slug

+$Sapper is able to create pages based on URL parameters. In our case, we link to+$/blog/slug,+$which means it renders the component at+$/routes/blog/[slug].svelte

+$Inside that component, fetch the blog data like we did for the index page. ThePARAMS+$object contains the parameters from the URL, which in this case is the slug.

+$

+$16. Error if post is not found

+$Unlike the index page, there is a chance there isn’t a blog post at the URL. In that case, we should display an error. Along with预紧+$method Also Includes错误+$that changes the response to an error page instead.

+$At the end of the preload method, show an error if there is no post found. Otherwise, set the岗位+$variable for the page.

+$if (res.status === 200) { return { post: data }; } else { this.error(res.status, data.message); }

+$17. Display the blog post

Internal links

+$Any internal links can be loaded asynchronously. This includes those written in Markdown.

(图片来源:马特·克劳奇)

+$With the data fetched, we can now show the post on the page. Similar to the PostSummary component, we display each part of the post’s content inside curly brackets. At the bottom of the component, add some markup to display on the page.

+$

{post.title}

by {post.author.name}
”” {post.html}

+$18. Display HTML Instead

+$Looking at the page now, everything displays correctly apart from the actual post content. The markdown conversion generates HTML, but we see that printed as text on the post itself. Sapper has a HTML parser built in for this case. Placing+$@html+$in front of it will use this parser.

+${@html Post.html}

+$19. Set page value</h2><p>+$Our blog functions correctly, but there are a couple of changes needed to finish it. One of those is to update the<strong><html><title> </ HTML></strong>+$on the page to relabel the tab it’s displayed in.</p><p>+$Svelte Supports A<strong>+$<svelte:head></strong>+$element, which injects anything inside of it into the<strong><head></strong>+$of the page. Use this to set the title of the post as<strong><html><title> </ HTML></strong>。</p><pre class="line-numbers language-html" language="html"><code>+$<svelte:head> <title>{post.title} | Sapper Blog

+$20. Updating The </h2><p>+$Every page goes through a template in order to stamp out the HTML for the rest of the page. This is where any setup such as font imports and meta tags would be entered. Open up template.html, and add in a hook for the contents of the<strong>+$<svelte:head></strong>+$element from the previous step. Add this in just before the closing<strong></head></strong>标签。</p><pre class="line-numbers language-html" language="html"><code>+$<head> […] %sapper.head% </head>The final thing we need to add is a layout for the blog. Instead of wrapping each page in a component, Sapper will look for a “_layout.svelte” file to do this job for us. Inside _layout.svelte, import the <Header> component and show that at the top of every page. It provides a convenient link back to the homepage.</code></pre><h2 id="21-add-permanent-header">+$21. Add Permanent Header</h2><p>+$The final thing we need to add is a layout for the blog. Instead of wrapping each page in a component, Sapper will look for a<strong>+$_layout.svelte</strong>+$file to do this job for us. Inside<strong>+$_layout.svelte</strong>+$, import the <Header> component and show that at the top of every page. It provides a convenient link back to the homepage.</p><pre class="line-numbers language-javascript" language="javascript"><code>+$<script> import Header from “../components/Header.svelte”; </script> <main> <Header /> <slot /> </main></code></pre><p><em>本文最初发表于创意网页设计杂志</em><a href="https://www.n2v.net/web-designer-magazine" target="_blank"><em>网页设计者</em></a><em>。</em><a href="https://www.myfavouritemagazines.co.uk/web-designer-print-back-issues/web-designer-issue-290/" rel="nofollow" target="_blank"><em>+$Buy Issue 290 Now.</em></a></p><ul><li><a href="https://www.n2v.net/features/web-components" target="_blank">Web组件:终极指南</a></li><li><a href="https://www.n2v.net/web-design/google-chrome-extensions-21410570" target="_blank">30个面向网页设计师和开发者的Chrome扩展程序</a></li><li><a href="https://www.n2v.net/features/best-web-design-tools" target="_blank">52个网页设计工具,帮助你在2019年更聪明地工作。</a></li></ul> </div> <div class="box"> <a class="block-link full" href="https://www.n2v.net/tag/web-design"><span class="chunk category">请参阅更多Web设计文章</span><div class="block-icon"><span class="icon icon-arrow-right"></span></div></a> </div> <div id="this-will-be-used-for-mpu-2"></div> <div class="box" id="articleTag"> <h3 class="separator-heading">话题</h3> <div class="tag"> <a href="https://www.n2v.net/tag/web-components">Web组件</a> </div> <div class="tag"> <a href="https://www.n2v.net/tag/sapper">工兵</a> </div> <div class="tag"> <a href="https://www.n2v.net/tag/magcontent">Magcontent</a> </div> <div class="tag"> <a href="https://www.n2v.net/tag/svelte">苗条</a> </div> <div class="tag"> <a href="https://www.n2v.net/web-designer">网页设计者</a> </div> <div class="tag"> <a href="https://www.n2v.net/tag/web-design">网页设计</a> </div> </div> <div class="box"> <h4 class="separator-heading">相关文章</h4> <ul class="media-list"> <li> <a href="https://www.n2v.net/features/best-antivirus-software"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="The best antivirus software in 2019" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/5NxXz3VAQSZK4WEKkFgAyR-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/5NxXz3VAQSZK4WEKkFgAyR-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/5NxXz3VAQSZK4WEKkFgAyR-450-80.jpg 450w, https://cdn.mos.cms.futurecdn.net/5NxXz3VAQSZK4WEKkFgAyR-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/5NxXz3VAQSZK4WEKkFgAyR-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/5NxXz3VAQSZK4WEKkFgAyR.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/5NxXz3VAQSZK4WEKkFgAyR.jpg" /> <span>2019年最好的杀毒软件</span> </a> </li> <li> <a href="https://www.n2v.net/features/best-laptop-for-programming"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="The best laptops for programming in 2019" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/cKeX4dLiRQapafC24N5QAP-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/cKeX4dLiRQapafC24N5QAP-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/cKeX4dLiRQapafC24N5QAP-450-80.jpg 450w, https://cdn.mos.cms.futurecdn.net/cKeX4dLiRQapafC24N5QAP-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/cKeX4dLiRQapafC24N5QAP-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/cKeX4dLiRQapafC24N5QAP.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/cKeX4dLiRQapafC24N5QAP.jpg" /> <span>2019年最好的笔记本电脑</span> </a> </li> <li> <a href="https://www.n2v.net/features/black-friday-cyber-monday-2019"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="Black Friday and Cyber Monday 2019: all the best deals for artists and designers" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/dkiwdNgCzJqLEN3w8fHbde-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/dkiwdNgCzJqLEN3w8fHbde-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/dkiwdNgCzJqLEN3w8fHbde-450-80.jpg 450w, https://cdn.mos.cms.futurecdn.net/dkiwdNgCzJqLEN3w8fHbde-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/dkiwdNgCzJqLEN3w8fHbde-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/dkiwdNgCzJqLEN3w8fHbde.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/dkiwdNgCzJqLEN3w8fHbde.jpg" /> <span>黑色星期五和网络星期一2019年:所有的艺术家和设计师最好的交易</span> </a> </li> <li> <a href="https://www.n2v.net/how-to/grav"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="Get started with Grav CMS" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/WaxBF6xxZd7RCUGTnfbWfF-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/WaxBF6xxZd7RCUGTnfbWfF-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/WaxBF6xxZd7RCUGTnfbWfF-450-80.jpg 450w, https://cdn.mos.cms.futurecdn.net/WaxBF6xxZd7RCUGTnfbWfF-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/WaxBF6xxZd7RCUGTnfbWfF-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/WaxBF6xxZd7RCUGTnfbWfF.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/WaxBF6xxZd7RCUGTnfbWfF.jpg" /> <span>开始使用GravCMS</span> </a> </li> </ul> </div> </section> <script> window._taboola = window._taboola || []; var taboola_lists = []; function taboola_is_device(device) { if ((! device) || device === null || (typeof device) === 'undefined') return true if (device === 'amp') return false if (device === 'desktop' && window.screen.width >= 700) return true if (device === 'mobile' && window.screen.width < 700) return true return false } </script> <footer class="van_taboola" id="taboola-below-article-thumbnails"></footer> <script> if (taboola_is_device("")) { taboola_lists.push({ mode: "thumbnails-e", container: "taboola-below-article-thumbnails", placement: "Below Article Thumbnails", target_type: "mix" }); } </script> <footer class="van_taboola" id=""></footer> <script> if (taboola_is_device("amp")) { taboola_lists.push({ mode: "thumbnails-a", container: "", placement: "below-main-column", target_type: "" }); } </script> <script> for(var i = 0; i < taboola_lists.length; i++){ _taboola.push(taboola_lists[i]); } </script> <footer id="comment-jump"> </footer> </article> <aside id="sidebar"> <section class="recommended-content"> <div class="recommendation-container"> <h3>推荐的</h3> <div class="recommendation-articles"> <div class="recommended-article item-1"> <a href="https://www.n2v.net/news/creative-bloqs-job-of-the-week"> <div class="article-image-container item-1"> <div class="article-image item-1"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/8qT2rPnRnC4uQBzSf42EmW-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/8qT2rPnRnC4uQBzSf42EmW-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/8qT2rPnRnC4uQBzSf42EmW-600-80.jpg 600w, https://cdn.mos.cms.futurecdn.net/8qT2rPnRnC4uQBzSf42EmW-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/8qT2rPnRnC4uQBzSf42EmW-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/8qT2rPnRnC4uQBzSf42EmW.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/8qT2rPnRnC4uQBzSf42EmW.jpg" data-pin-nopin="true" /> </div> </div> <h4 class="article-name item-1">设计工作:在CreativeBloq中找到你梦寐以求的角色</h4> </a> </div> <div class="recommended-article item-2"> <a href="https://www.n2v.net/graphic-design-tips/best-free-fonts-for-designers-1233380"> <div class="article-image-container item-2"> <div class="article-image item-2"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/a5UrGBqnq8ARPppz49xpGd-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/a5UrGBqnq8ARPppz49xpGd-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/a5UrGBqnq8ARPppz49xpGd-600-80.jpg 600w, https://cdn.mos.cms.futurecdn.net/a5UrGBqnq8ARPppz49xpGd-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/a5UrGBqnq8ARPppz49xpGd-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/a5UrGBqnq8ARPppz49xpGd.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/a5UrGBqnq8ARPppz49xpGd.jpg" data-pin-nopin="true" /> </div> </div> <h4 class="article-name item-2">78款最适合设计师的免费字体</h4> </a> </div> <div class="sponsored-post"><div style="width:100%"></div></div> </div> </div> </section> <section class="box newsletter-signup"> <h3 class="separator-heading"> <span> <i class="icon icon-envelope white"></i><span class="newsletter-title">获取每周提示和灵感</span> </span> </h3> <div class="grey-box"> <p>请在下面注册以获取Creative Bloq的最新信息,以及独家特别优惠,直接到您的收件箱!</p> <iframe style="width:100%" height="100" sandbox="allow-scripts allow-forms" data-lazy-src="//futureplc.slgnt.eu/optiext/optiextension.dll?ID=s6XsWnyjpNGgHmS9IDSe4kGMs9Z0hv5kXjNQUQiRO2tDkDpIITWHetB5caZtol9br5fEOvs9fVr9oPM92i&BRAND=CBQ" data-lazy-priority="low" scrolling="no"> </iframe> <footer> <small>没有垃圾邮件,我们保证。您可以随时取消订阅,未经您的许可,我们绝不会分享您的详细信息。</small> </footer> </div> </section> <section class="popular-box"> <div id="popular-box-wrapper" class="style1"> <div class="most-popular-tab-bar"> <input type="radio" name="popradio" id="popradio-1" checked /> <input type="radio" name="popradio" id="popradio-2" /> <div id="popularcontent"> <div class="flex-row"> <label class="poplabel" id="poplabel-1" for="popradio-1"> <span>最阅读</span> </label> <label class="poplabel" id="poplabel-2" for="popradio-2"> <span>最共享的</span> </label> </div> <ol class="popular-list active" id="poplist-1"> <li class="most-popular-item first-article"> <div style="width:100%"> <a href="https://www.n2v.net/features/best-camera-phone" aria-label="The best camera phones in 2019"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/Z6qQLRBS6CkqEdXessh7v9-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/Z6qQLRBS6CkqEdXessh7v9-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/Z6qQLRBS6CkqEdXessh7v9-450-80.jpg 450w, https://cdn.mos.cms.futurecdn.net/Z6qQLRBS6CkqEdXessh7v9-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/Z6qQLRBS6CkqEdXessh7v9-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/Z6qQLRBS6CkqEdXessh7v9.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/Z6qQLRBS6CkqEdXessh7v9.jpg" data-pin-nopin="true" /> </a> <div class="popular-listings"> <span class="number-1">1</span><h4><a href="https://www.n2v.net/features/best-camera-phone">2019年最好的拍照手机</a></h4> </div> </div> </li> <li class="most-popular-item "> <div style="width:100%"> <a href="https://www.n2v.net/news/download-photoshop" aria-label="Download Adobe Photoshop: how to try Photoshop free or with Creative Cloud"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/joEFCsqnbDQyBYqX8UMFRB-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/joEFCsqnbDQyBYqX8UMFRB-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/joEFCsqnbDQyBYqX8UMFRB-450-80.jpg 450w, https://cdn.mos.cms.futurecdn.net/joEFCsqnbDQyBYqX8UMFRB-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/joEFCsqnbDQyBYqX8UMFRB-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/joEFCsqnbDQyBYqX8UMFRB.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/joEFCsqnbDQyBYqX8UMFRB.jpg" data-pin-nopin="true" /> </a> <div class="popular-listings"> <span class="number-2">2</span><h4><a href="https://www.n2v.net/news/download-photoshop">下载Adobe Photoshop:如何免费试用Photoshop或使用Creative Cloud</a></h4> </div> </div> </li> <li class="most-popular-item "> <div style="width:100%"> <a href="https://www.n2v.net/features/best-video-editing-software-for-designers" aria-label="The best video editing software in 2019"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/g2e9mBsVzgijThf3e7qpxH-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/g2e9mBsVzgijThf3e7qpxH-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/g2e9mBsVzgijThf3e7qpxH-450-80.jpg 450w, https://cdn.mos.cms.futurecdn.net/g2e9mBsVzgijThf3e7qpxH-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/g2e9mBsVzgijThf3e7qpxH-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/g2e9mBsVzgijThf3e7qpxH.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/g2e9mBsVzgijThf3e7qpxH.jpg" data-pin-nopin="true" /> </a> <div class="popular-listings"> <span class="number-3">3</span><h4><a href="https://www.n2v.net/features/best-video-editing-software-for-designers">2019年最好的视频编辑软件</a></h4> </div> </div> </li> <li class="most-popular-item "> <div style="width:100%"> <a href="https://www.n2v.net/features/best-drawing-tablet" aria-label="The best drawing tablet: Our pick of the best graphics tablets in 2019"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/8LtwVjsqpUK4Fy7Evjabrj-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/8LtwVjsqpUK4Fy7Evjabrj-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/8LtwVjsqpUK4Fy7Evjabrj-450-80.jpg 450w, https://cdn.mos.cms.futurecdn.net/8LtwVjsqpUK4Fy7Evjabrj-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/8LtwVjsqpUK4Fy7Evjabrj-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/8LtwVjsqpUK4Fy7Evjabrj.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/8LtwVjsqpUK4Fy7Evjabrj.jpg" data-pin-nopin="true" /> </a> <div class="popular-listings"> <span class="number-4">4</span><h4><a href="https://www.n2v.net/features/best-drawing-tablet">最好的绘图板:我们在2019年选择最好的图形平板电脑</a></h4> </div> </div> </li> <li class="most-popular-item "> <div style="width:100%"> <a href="https://www.n2v.net/photoshop/alternatives-1131641" aria-label="The 13 best alternatives to Photoshop"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/BCXA6u6MvgNdwDoU6fcW79-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/BCXA6u6MvgNdwDoU6fcW79-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/BCXA6u6MvgNdwDoU6fcW79-450-80.jpg 450w, https://cdn.mos.cms.futurecdn.net/BCXA6u6MvgNdwDoU6fcW79-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/BCXA6u6MvgNdwDoU6fcW79-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/BCXA6u6MvgNdwDoU6fcW79.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/BCXA6u6MvgNdwDoU6fcW79.jpg" data-pin-nopin="true" /> </a> <div class="popular-listings"> <span class="number-5">5</span><h4><a href="https://www.n2v.net/photoshop/alternatives-1131641">Photoshop的13个最佳替代方案</a></h4> </div> </div> </li> </ol> <ol class="popular-list " id="poplist-2"> <li class="most-popular-item first-article"> <div style="width:100%"> <a href="https://www.n2v.net/features/5-times-classic-brands-were-revived-successfully-and-2-when-it-was-a-disaster" aria-label="5 times classic brands were revived successfully (and 2 when it was a disaster)"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/C9gtqWjgsgFjJv9BCLC98U-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/C9gtqWjgsgFjJv9BCLC98U-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/C9gtqWjgsgFjJv9BCLC98U-450-80.jpg 450w, https://cdn.mos.cms.futurecdn.net/C9gtqWjgsgFjJv9BCLC98U-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/C9gtqWjgsgFjJv9BCLC98U-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/C9gtqWjgsgFjJv9BCLC98U.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/C9gtqWjgsgFjJv9BCLC98U.jpg" data-pin-nopin="true" /> </a> <div class="popular-listings"> <span class="number-1">1</span><h4><a href="https://www.n2v.net/features/5-times-classic-brands-were-revived-successfully-and-2-when-it-was-a-disaster">5次经典品牌成功复兴(2次是灾难)</a></h4> </div> </div> </li> <li class="most-popular-item "> <div style="width:100%"> <a href="https://www.n2v.net/advice/everything-you-need-to-know-about-going-freelance" aria-label="Everything you need to know about going freelance"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/xbkVkjWfhYQnGGAsHMThTm-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/xbkVkjWfhYQnGGAsHMThTm-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/xbkVkjWfhYQnGGAsHMThTm-450-80.jpg 450w, https://cdn.mos.cms.futurecdn.net/xbkVkjWfhYQnGGAsHMThTm-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/xbkVkjWfhYQnGGAsHMThTm-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/xbkVkjWfhYQnGGAsHMThTm.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/xbkVkjWfhYQnGGAsHMThTm.jpg" data-pin-nopin="true" /> </a> <div class="popular-listings"> <span class="number-2">2</span><h4><a href="https://www.n2v.net/advice/everything-you-need-to-know-about-going-freelance">关于自由职业者需要知道的一切</a></h4> </div> </div> </li> <li class="most-popular-item "> <div style="width:100%"> <a href="https://www.n2v.net/news/under-armour-vs-hotsuit-copycat-logo-design" aria-label="Under Armour sues Hotsuit for 'copycat' logo... but are they really that similar? "> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/VRrBHLSs8jPf6tgw8baycD-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/VRrBHLSs8jPf6tgw8baycD-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/VRrBHLSs8jPf6tgw8baycD-450-80.jpg 450w, https://cdn.mos.cms.futurecdn.net/VRrBHLSs8jPf6tgw8baycD-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/VRrBHLSs8jPf6tgw8baycD-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/VRrBHLSs8jPf6tgw8baycD.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/VRrBHLSs8jPf6tgw8baycD.jpg" data-pin-nopin="true" /> </a> <div class="popular-listings"> <span class="number-3">3</span><h4><a href="https://www.n2v.net/news/under-armour-vs-hotsuit-copycat-logo-design">在盔甲下起诉“模仿”标志的热身..。但它们真的有那么相似吗?</a></h4> </div> </div> </li> <li class="most-popular-item "> <div style="width:100%"> <a href="https://www.n2v.net/features/8-of-the-best-new-creative-tools-of-2019" aria-label="8 of the best new creative tools of 2019"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/j3y9XsfnUBG8KdChAEdtvT-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/j3y9XsfnUBG8KdChAEdtvT-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/j3y9XsfnUBG8KdChAEdtvT-450-80.jpg 450w, https://cdn.mos.cms.futurecdn.net/j3y9XsfnUBG8KdChAEdtvT-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/j3y9XsfnUBG8KdChAEdtvT-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/j3y9XsfnUBG8KdChAEdtvT.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/j3y9XsfnUBG8KdChAEdtvT.jpg" data-pin-nopin="true" /> </a> <div class="popular-listings"> <span class="number-4">4</span><h4><a href="https://www.n2v.net/features/8-of-the-best-new-creative-tools-of-2019">8.2019年最优秀的新创意工具之一</a></h4> </div> </div> </li> <li class="most-popular-item "> <div style="width:100%"> <a href="https://www.n2v.net/graphic-design/celebrities-were-designers-81412563" aria-label="9 celebrities you didn't know were designers"> <img src="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" alt="" class=" lazy-image lazy-image-loading lazyload optional-image" onerror="if(this.src && this.src.indexOf('missing-image.svg') !== -1){return true;};this.parentNode.replaceChild(window.missingImage(),this)" sizes="auto" data-normal="https://vanilla.futurecdn.net/creativebloq/media/img/missing-image.svg" data-src="https://cdn.mos.cms.futurecdn.net/LWzVsAmnVqMFkxXRXNuEVH-320-80.jpg" data-srcset="https://cdn.mos.cms.futurecdn.net/LWzVsAmnVqMFkxXRXNuEVH-320-80.jpg 320w, https://cdn.mos.cms.futurecdn.net/LWzVsAmnVqMFkxXRXNuEVH-450-80.jpg 450w, https://cdn.mos.cms.futurecdn.net/LWzVsAmnVqMFkxXRXNuEVH-970-80.jpg 970w, https://cdn.mos.cms.futurecdn.net/LWzVsAmnVqMFkxXRXNuEVH-1024-80.jpg 1024w" data-sizes="auto" data-original-mos="https://cdn.mos.cms.futurecdn.net/LWzVsAmnVqMFkxXRXNuEVH.jpg" data-pin-media="https://cdn.mos.cms.futurecdn.net/LWzVsAmnVqMFkxXRXNuEVH.jpg" data-pin-nopin="true" /> </a> <div class="popular-listings"> <span class="number-5">5</span><h4><a href="https://www.n2v.net/graphic-design/celebrities-were-designers-81412563">9位你不认识的名人是设计师</a></h4> </div> </div> </li> </ol> </div> </div> </div> </section> </aside> </div> <script id="hawklinks-script"> function loadHawklinks(src) { !function (e, f, u) { e.async = 1; e.src = u; f.parentNode.insertBefore(e, f); }(document.createElement('script'), document.getElementsByTagName('script')[0], src); } window.reliableDOMContentLoaded.then(function() { loadHawklinks("https://gizmos.files-hawk.co.uk/hl/hawklinks.js"); }); </script> <link rel="preload" href="https://gizmos.files-hawk.co.uk/hl/hawklinks.js" as="script" /> <!-- SP NOPE --> <script type="text/javascript"> window.vanilla.tiberius = { enabled: false, } </script> <footer id="document-footer" class="container full"> <div id="document-footer-content"> <p>Creative Bloq是Future plc的一部分,Future plc是一家国际媒体集团和领先的数字出版商。<a href="http://www.futureplc.com" target="_blank">访问我们的公司网站</a>。</p> <nav> <ul> <li><a href="https://www.n2v.net/features/about-us" target="_blank">关于我们</a></li> <li><a href="http://www.futureplc.com/terms-conditions/" target="_blank">条款和条件</a></li> <li><a href="http://www.futureplc.com/privacy-policy/" target="_blank">隐私政策</a></li> <li><a href="http://www.futureplc.com/cookies-policy/" target="_blank">Cookies政策</a></li> <li><a href="https://www.n2v.net/advertising" target="_blank">和我们一起做广告</a></li> </ul> </nav> <p><span> <span> <span>Future Publishing Limited</span> </span> <span>Quay House,The Ambury</span>,<span>浴</span> <span>BA1 1UA</span></span>。版权所有。英格兰和威尔士公司注册号2008885。</p> </div> </footer> <script> window.vanL10N = []; </script><script> if (document.cookie.indexOf("EuConsent") < 0) { if (!window._comscore) { window._comscore = window._comscore || []; } window._comscore.push({ c1: "2", c2: "10055482", cs_ucfr: '' }); (function() { var s = document.createElement("script"), el = document.getElementsByTagName("script")[0]; s.async = true; s.src = (document.location.protocol == "https:" ? "https://sb" : "http://b") + ".scorecardresearch.com/beacon.js"; el.parentNode.insertBefore(s, el); })(); } else { window.reliableConsentGiven.then(function(value) { if (!window._comscore) { window._comscore = window._comscore || []; } var cs_ucfr_value = ''; if (value.consent && value.consent.purposeConsents[5]) { cs_ucfr_value = 1; } else { cs_ucfr_value = 0; } window._comscore.push({ c1: "2", c2: "10055482", cs_ucfr: cs_ucfr_value }); (function() { var s = document.createElement("script"), el = document.getElementsByTagName("script")[0]; s.async = true; s.src = (document.location.protocol == "https:" ? "https://sb" : "http://b") + ".scorecardresearch.com/beacon.js"; el.parentNode.insertBefore(s, el); })(); }); } </script> <script> var dfp_config = { "keystone": "", "ad_unit": "10518929/Design_CreativeBloQ/", "live_ad_unit": "10518929/Design_CreativeBloQ/", "test_ad_unit": "10518929/Design_CreativeBloQ_Test/", "recovery_ad_unit": "", "recovery_test_ad_unit": "", "incremental": true, "gptBeta": "", "max_incremental_ads": 20, "max_incremental_ads_mobile": 20, "max_concurrent_ads": 4, "refresh": true, "site_platform": "vanilla", "tiberius": false, "tiberius_mode": "", "keywords": "serversidehawk,Web design,Web Designer,Web Components,Sapper,magcontent,Svelte", "article_id": "J53ebMpLqsYcDNxMGZgPxJ", "vanilla_article_id": "J53ebMpLqsYcDNxMGZgPxJ", "page_type": "how-to", "product_brand": "", "product_category": "", "product": "", "vertical": "web-design", "source": "web-designer", "provertical": "", "single_request": true, "onscroll": { "refresh" : "", "mpu": "" }, "jwplayer": "carousel" } </script> <script> dfp_config.gallery_refresh_interval = 2; </script> <script>window.vanillaComponents = [{"trackable":[{"type":"click","identifier":".menuitems a","name":"Link clicked","countTotal":true}],"name":"Primary Nav","excludeHidden":false,"identifier":".primary-nav"},{"trackable":[{"type":"click","identifier":".feature-block-item-wrapper a","name":"Article clicked","countTotal":false}],"name":"Featured articles","excludeHidden":false,"identifier":".top-featured"},{"trackable":[{"type":"click","identifier":"a","name":"Logo clicked","countTotal":false}],"name":"Site Logo","identifier":".logo"},{"trackable":[{"type":"click","identifier":".most-popular-item","name":"Most read article clicked","countTotal":true}],"name":"Most Popular - Popular","identifier":"#poplist-1"},{"trackable":[{"type":"click","identifier":".most-popular-item","name":"Most shared article clicked","countTotal":true}],"name":"Most Popular - Shared","identifier":"#poplist-2"},{"trackable":[{"type":"click","identifier":"a","name":"Link clicked","countTotal":false}],"name":"Prev/Next","identifier":".next-prev-container"},{"trackable":[{"type":"click","identifier":"a","name":"Number clicked","countTotal":true}],"name":"Paginated Review Numerical pagination - Number","identifier":".pagination-numerical-list"},{"trackable":[{"type":"click","identifier":".prev,.next","name":"Prev/Next clicked","countTotal":false}],"name":"Paginated Review Numerical pagination - Prev/Next","identifier":".navigation-sequential"},{"trackable":[{"type":"click","identifier":"a","name":"Link clicked","countTotal":true}],"name":"Inline Pagination","identifier":".swipe-pages-wrapper"},{"trackable":[{"type":"click","identifier":"a","name":"Link clicked","countTotal":true}],"name":"Article Tags","identifier":"#articleTag"},{"trackable":[{"type":"click","identifier":".recommended-article a","name":"Link clicked","countTotal":true}],"name":"Recommended article","identifier":".recommendation-articles"},{"trackable":[{"type":"click","identifier":"a","name":"Link clicked","countTotal":true}],"name":"Trending bar","identifier":".trending-items"},{"trackable":[{"type":"click","identifier":"a","name":"Link clicked","countTotal":true}],"name":"Boilerplate-1","identifier":".club-boilerplate-1"},{"trackable":[{"type":"click","identifier":"a","name":"Link clicked","countTotal":true}],"name":"Boilerplate-2","identifier":".club-boilerplate-2"},{"trackable":[{"type":"click","identifier":"a","name":"Link clicked","countTotal":true}],"name":"Boilerplate-3","identifier":".club-boilerplate-3"},{"trackable":[{"type":"click","identifier":"a","name":"Link clicked","countTotal":true}],"name":"Boilerplate-4","identifier":".club-boilerplate-4"},{"trackable":[{"type":"click","identifier":"a","name":"Link clicked","countTotal":true}],"name":"Inline links","identifier":"#article-body"},{"trackable":[{"type":"click","identifier":"a","name":"Link clicked","countTotal":true}],"name":"Social links","identifier":".socialite-widget"},{"trackable":[{"type":"click","identifier":"a","name":"Link clicked","countTotal":true}],"name":"Avatar","identifier":"#club-login"},{"trackable":[{"type":"click","identifier":".fwd-link","name":"FWD link clicked","countTotal":true}],"name":"Forward Linker","identifier":"#article-body"},{"trackable":[{"type":"click","identifier":"div .brands-lead","name":"Extending Trending Bar","countTotal":true}],"name":"Trending Bar Parent","excludeHidden":false,"identifier":"div .trending-bar"},{"trackable":[{"type":"click","identifier":"a[data-event-label=elkInjectedRelatedBlock]","name":"Link clicked","countTotal":true}],"name":"ELK Injected Related Block","identifier":"#article-body"}]</script> <script> var require = {waitSeconds:0}; </script> <!-- Google Tag Manager --> <script></script> <!-- End Google Tag Manager --> <script type="text/javascript"> (function(){ if(typeof window._taboola !== 'undefined' && typeof taboola_lists !== 'undefined' && Array.isArray(taboola_lists) && taboola_lists.length) { function loadTaboola() { !function (e, f, u) { e.async = 1; e.src = u; f.parentNode.insertBefore(e, f); }(document.createElement('script'), document.getElementsByTagName('script')[0], '//cdn.taboola.com/libtrc/futureplc-creativebloq/loader.js'); _taboola.push({article: 'auto'}); _taboola.push({flush: true}); } // Can't be in asset loader until we can call custom loader functions (window.Promise ? Promise.all([window.reliablePageLoad, window.reliableConsentGiven]) : window.reliableConsentGiven ).then(function(){ setTimeout(loadTaboola, 6000); }); } })(); </script> <script>window.addEventListener("load",function(){if(!window.askForConsent){var e=document.createElement("script");e.src="https://vanilla.futurecdn.net/creativebloq/cookieconsent.min.js",e.onload=function(){var e=window.innerWidth>=700?"bottom":"top";window.cookieconsent.initialise({palette:{popup:{background:"#000"},button:{background:"#666666"}},position:e,content:{message:"We use cookies on this website to deliver content to you, personalise content and ads, provide social media features, and analyse our traffic. Click 'I accept' to consent to the use of cookies. More information on cookies and how to manage them",link:"click here",href:"http://www.futureplc.com/cookies-policy/",dismiss:"I accept"}})},document.body.appendChild(e);var o=document.createElement("link");o.rel="stylesheet",o.type="text/css",o.href="https://vanilla.futurecdn.net/creativebloq/cookieconsent.min.css",document.body.appendChild(o);var t=document.createElement("style");t.appendChild(document.createTextNode(".cc-window {z-index:10000000}")),document.body.appendChild(t)}});</script> <!-- document assets - added by the article itself --> <script> window.vanilla.addCss({"href":"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/prism\/1.8.4\/themes\/prism.min.css"}) window.vanilla.addJs({"src":"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/prism\/1.8.4\/prism.min.js"}, 1000, 1) window.vanilla.addJs({"id":"main-js","src":"\/\/vanilla.futurecdn.net\/creativebloq\/144796\/media\/js\/main.min.js"}, null, 0) window.vanilla.addCss({"href":"\/\/vanilla.futurecdn.net\/creativebloq\/144796\/media\/css\/creativebloq.min.css"}) </script> <script> window.ffte = {"site":"creativebloq","endpoint":"\/\/api.vanilla.futurecdn.net\/article","locale":"GB","gaCode":"UA-48905440-1","debug":[],"serverEnvironment":"live","regionLink":"","isGlobal":false,"properties":{"articleProduct":[],"articleProductHandle":[],"articleType":"how-to","articleTemplate":"standard","articleTagHandle":["web-components","sapper","magcontent","svelte","web-designer","web-design"],"articleTagType":["freeform","freeform","freeform","freeform","source"],"articleControlTag":["serversidehawk"],"articleVerticalHandle":["web-design"],"articleCategoryHandle":[],"subSite":"","articleVertical":"web design","id":"J53ebMpLqsYcDNxMGZgPxJ","legacyId":"J53ebMpLqsYcDNxMGZgPxJ"}} </script> <script> window.xkeys = ["creativebloq-platform-responsive","creativebloq-core-version-21.4.5","creativebloq-core-ftefrontprodblue","creativebloq-article-J53ebMpLqsYcDNxMGZgPxJ","creativebloq-articletype-how-to","creativebloq-article-age-ancient","creativebloq-region-GB","creativebloq-language-en","creativebloq-author-teFvMQ9VVtmRE4Z5JbPHoZ","creativebloq-tag-aHbSwk32desfH4WPSXCSdB","creativebloq-tag-gAgSBtWHh8gQQ3hkSHKbaQ","creativebloq-tag-4cfHyNcsu4JUveFABaMSER","creativebloq-tag-TYAFhdjFkzwYHMydsPpRDH","creativebloq-tag-qpyFAWvkyEi7XTDLuX9NeP"]; window.templateVariables = {}; </script> <div><script>var lang_is_tranlated='快八哥正在翻译';var website_tranlate_plan_id = '1';</script><script src="//sys.fastmyna.com/api/kbg.js?v=1.0"></script></div><div> <script type="text/javascript"> var _paq = _paq || []; _paq.push(["trackPageView"]); _paq.push(["enableLinkTracking"]); (function() { var u="//ptrack.qifeiye.com/"; _paq.push(["setTrackerUrl", u+"piwik.php"]); _paq.push(["setSiteId", "50"]); var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0]; g.type="text/javascript"; g.async=true; g.defer=true; g.src=u+"piwik.js"; s.parentNode.insertBefore(g,s); })(); </script></div></body> <script> window.ftr_request_id = ""; </script> </html> <br><br><div style='font-size:14px;color:#ffffff;background-color:#000000;text-align:center;'>翻译字数超限</div><br><br>