Rewrite personal website for the third time, share some thoughts

Rewrite personal website for the third time, share some thoughts

"This article has been summoned to participate in activities of a good text, click to see: the back-end, front-end dual-track large contributors, 20,000 yuan prize pool waiting for you to challenge! "


Reading timeBrainpowerPre-knowledge

Recently, I updated a wave of personal homepages, and just organized an article to share some thoughts. This article will talk about the implementation ideas of each part of the website, as well as some of my ideas and ideas on the design.

If you also want to write your own personal homepage, I hope this article can give you some inspiration.

New homepage:

previous version

Let me show you the previous version first. v1.0 was written in 2018, and the age is really too old, so that the local node-sass is reported to be wrong.

v1.0 (2018)

v2.0 (2019)


1. let s talk about positioning. I think this is the most important part of making a personal homepage. I have seen too many people who deviate from the goal while doing it, and finally give up, commonly known as "unclear needs" .

For example, at the beginning of a blog post, all kinds of entanglements in Markdown style, and then give up, or for example, some people like to build everything by themselves, but they spend too much time on "making wheels", but the webpage is too late to build, and finally give up .

I do personal home before just to collect Jane books and Medium on the article, by the way write biography on when a home page.

At that time, I was obsessed with the idea that content is king . So my idea is simple: everything is based on blog posts. Never write the wheels by hand. I will use the default styles for whatever the wheels give me.

It can be seen that both v1.0 and v2.0 have a strong Element UI flavor, and many components are not even changed, only a slight improvement has been made on the homepage of v2.0.

And I'm also very chicken thief , I have chosen not to step on and Markdown editor of the pit, so the article links are outside the chain form, the points go to jump to simple books and Medium on.

1. it s naive, it s a ghost if someone clicks on my homepage. 2. I don t want to waste time in Markdown style. 3. I don t want to engage in back-end services and blog management.

As for the new version v3.0, I no longer publish all kinds of articles, because as long as I write a good article on the platform, people will naturally pay attention. On the other hand, others may click into my homepage just because of curiosity.

Therefore, in order to satisfy the curiosity of the audience, I position it as a personal landing page, that is, the Landing Page. Main content: highlight the individual, and be fancy.


Landing page is the most important feature of Tai and cool , so I saw a lot of the market profile, mainly fall into several categories: micro-Bo class, European and American Gangster simple class and great class.

China Weibo

The first I call the "Chinese microblogging class" because having a very strong micro-blog style, the main elements are: the article body, article directories, articles classification, labeling and so on . Masterpiece: Ruan Yifeng's web log .

This type is mainly based on the content of the article, with many and mixed elements. There are a lot of domestic use of this kind, which causes the homogeneity to be very serious, and it is difficult to come up with new ideas, and it is a very troublesome and complicated thing to do well in the style of the article, which does not match my positioning, so pass~

Big guy simple class

This kind of landing page can be regarded as a landing page in the sense, but the elements are too few, only a few lines of introduction is over. Masterpiece: You Yuxi's homepage .

There is not even a picture, it belongs to the style of "love to see, don't look to learn". However, I am not a boss, pass~

"Strange Species" category

Such general very show, almost not go in to see the content, but to play . Such as these:

European and American huge class

Foreign people prefer big picture , broad-brush sense and flavors, color style. There are a lot of design drawings of this kind on dribbble and behance .

The main features are: the lines are relatively rough, the colors are bright or elegant, and the elements are mainly "big", while maintaining a simple style.

"European and American huge category" is my favorite type. It breaks away from the domestic "weibo-like" blog homepage and has a beautiful design. The only difficulty is that I can't design such a good-looking one by myself, so I found a template on dribbble and behance, combined with some other elements, and integrated while developing.

why not?

At this time, some old iron will ask:

Why don't you go to Hexo sites and use free templates directly?

The main reason is that most of the templates above are "weibo-like style", and there are few design styles on the dribbble website. But if you don't have very special needs, I suggest that you use the ready-made ones and try not to "invent" the wheel.

Then there are also "European and American huge category" of WordPress and Wix website generators abroad?

One reason is that the access speed is too slow, but it is mainly expensive.

Technology stack

  • React
  • TypeScript
  • Sass
  • Ant Design

I believe many people will feel:

Personal website should be handwritten by yourself, so as to attract interviewers. When the interviewer asks, he can talk endlessly about how to overcome a certain technical point.

My thought is: It is not recommended to do this, you can use wheels with wheels, unless you have to do it, don't write by hand!

We should always keep in mind what is in practice or in doing product . There is nothing to say about the former, handwriting wheels + publishing technical articles, which is often seen on the Nuggets. For the latter, you should not tangle technology, but try to get the product done perfect.

There are many disadvantages of making your own wheels:

  • Like to "invent" the wheel, not "make" the wheel
  • It needs to be maintained, and it s no better than the wheels on the market.
  • The most important point is that it s easy to get into the horns of "how to solve the XX problem", and then forget whether to write the homepage or build wheels.

Please believe in another more true creed:

It is NB if it is done, and SB if it is not done.

So, let yourself go, isn't it good to stand on the shoulders of giants? Okay, let's not talk nonsense, let's talk about how I achieved it.

Navigation bar-Nav

There are many ways to implement the classic logo on the left and List layout on the right.

In the past, use

float: left
float: right
It will be more popular to implement it. However, the disadvantage of this method is that you have to manually clear the float, and float has become a thing of the past, so pass~

Here, I just used flex's space-between to finish work.

.nav { display : flex; align-items : center; justify-content : space-between;//separate the left and right sides } Copy code

Another requirement of the navigation bar is to adapt to the mobile phone, otherwise all the Nav tags will be squeezed together.

My implementation is: make two navigation bars, and then use @media media queries to control the display of both.

<!-- Level--> < ul class = "horizontal" > ... < li class = "navBtn" onclick = "Open vertical list" > vertical open button </li > </ul > <!-- Vertical--> < ul class = "vertical" > ... </ul > Copy code
//Small screen style @media screen and ( max-width : 992px ) { ul .horizontal { //Do not come out the horizontal Nav li { display : none; & .navBtn { display : block; //Toggle button comes out } } } ul .vertical { display : flex; //vertical Nav comes out } } Copy code

Very easy~ There is another demand point in the navigation bar: which tab is clicked will slide down to the corresponding Section. The first reaction of many older brothers is

<a href="#id">
Label +
Embed id in div
, Use url hash to navigate. The disadvantage is: the sliding motion is too blunt and there is no animation .

Recommended here

$el.scrollIntoView({ behavior:'smooth' })
This API has a good sliding effect on the PC side. The disadvantage is that it cannot be adapted to the mobile phone, and the small details can be ignored~

const scroll = ( toEl: string ) => { const $toEl = document .querySelector(toEl); if ($toEl) { setActiveItem(toEl); $toEl.scrollIntoView({ behavior : 'smooth' }); } }; Copy code


position: fixed
The Nav screen assembly is fixed in the head, it will be more overall sense .

.nav { position : fixed; top : 0 ; left : 0 ; right : 0 ; z-index : 3 ; box-shadow : 0 4px 8px 0 rgba( 0 , 0 , 0 , 0.1 ); } Copy code

The best in the outer box-shadow to add a shadow effect, will make navigation more three-dimensional .

But be careful, don't add it too obviously, it will make people feel a little deliberate. The best shadow effect is not visible at first glance, but only when you look carefully.

It is difficult to manually adjust such shadow effects and background gradient effects. It is best to use a GUI generator to generate CSS. Google search box-shadow generator , all kinds of styles can be adjusted at will!

What if you say: I still can't tune out the good-looking effects in the GUI? The answer is: copy . If you are not professional, it depends on what professional people do. For example, the shadow of the navigation bar of the Nuggets is good:

Advertising page-Banner

Left part, one

Add a
nailed it. Pseudo-element can be used for the underlined part
Generate two horizontal lines, and then pass
position: absolute
The marking effect can be achieved by adjusting the position.

.del { position : relative; & ::before , & ::after { content : '' ; position : absolute; background : #bd0000 ; width : 120% ; //It looks better if the width exceeds a little height : 6px ; } & ::before { left : -10% ; //handle the part that exceeds the width top : 40% ; } & ::after { left : -10% ; //Handle the part that exceeds the width bottom : 30% ; } } Copy code

Typing effect You can use the small library typed.js , which is very simple to use. This is the official small Demo:

Also included with Can BE//A Regular Script Tag Import the Typed from 'typed.js' ; var options = { strings : [ '<i>First</i> sentence.' , '& a second sentence.' ], typeSpeed : 40 }; var typed = new new the Typed ( '.element' , Options); duplicated code

Typing speed, deleting speed, and DOM element acquisition logic can all be reused, so I encapsulated it into a hook:

Import the Typed, TypedOptions {} from 'typed.js' ; const useTyped = ( strings: string [], extra?: TypedOptions ) => { const el = useRef<HTMLElement | null >( null ); //span element const typed = useRef<Typed | null >( null ); //Typed.js objects useEffect( () => { const options = { //Default attributes strings, typeSpeed : 100 , backSpeed : 60 , ...extra, }; typed.current = new Typed(el.current || '' , options); return () => typed.current?.destroy(); // Wipe the butt }, [strings]); return el; }; Copy code

It is very convenient to use:

const Home: FC = () => { const el = useTyped(strings, { loop : true }); return ( < span ref = {el}/> ); }; Copy code

Looking at the right side again, it is actually a use

Realized animation effect + Lottie animation effect. Let's talk about this "ripple" effect first. In fact, the English name is pulse . The "ripple" effect is another effect, called ripple .

@keyframes pulse { 0% { transform : scale( 1 ); border-color : #e3342f ; } 100% { transform : scale( 1.2 ); //zoom in border-color : transparent; //transparent } } .ball { & ::before { content : "" ; position : absolute; //Position on the same element width : 100% ; height : 100% ; border : 4px solid #e3342f ; //ripple border-radius : 50% ; //rounded background : transparent; //Do the background color Animation : Pulse 2S Cubic-Bezier (. 57 ,. 06 ,. 27 ,. 84 ) Infinite;//pulse animation z-index : 1 ; //put on top of the original element } } Copy code

Oh, it's the heartbeat, no, it's the feeling of the heartbeat.

Regarding the animation of this little sheep, it is not a Gif picture, but Lottie animation. This is a cross-platform complete animation effect solution open sourced by Airbnb. Speaking of people: it is the premium version of Gif . The animation content is driven by JSON files, which can be found on Lottie's official website for free, just find it yourself.

Regarding the usage, I still encapsulated a hook:

Import Lottie, AnimationConfigWithData {} from 'Web-Lottie' ; const useLottie = ( path: string , extra?: AnimationConfigWithData ) => { const lottieRef = useRef<HTMLDivElement | null >( null ); //Animation element useEffect( () => { if (lottieRef.current) { //default parameter lottie.loadAnimation({ //Load container : lottieRef.current, path, renderer : 'svg' , loop : true , autoplay : true , ...extra, }); } }, []); return lottieRef; }; Copy code

When using it, just pass in the JSON url:

const sheepLottie = ' ' ; const Home: FC = () => { const sheepLottieRef = useLottie(sheepLottie); return ( < div ref = {sheepLottieRef}/> ); }; Copy code

As for the arrow below, it is Lottie +

scrollIntoView({ behavior:'smooth' })
The combination of, do not go into details.


This part is a personal introduction. Left, center, and right are

,simple. Among them, the cube in the middle on the left is still a Lottie animation, and the "sea monster" on the right uses the HongLei font library.

Tip: In the case of strong background colors, you can still use the shadow effect to highlight the three-dimensional sense of the page, which can effectively avoid the visual "fusion" of text and background. The text here uses text-shadow, and the avatar uses box-shadow.

The next part, the Timeline component.

I have studied Ant Design's Timeline component before, and it is realized by positioning. I don't like the way that the content div is separated from the document flow, and the problem of div height collapsing often occurs. Therefore, my Timeline component does not use position, but is implemented with Flex layout . .

Let s review the align-items property of the Flex layout . The flex-start is at the top, and the flex-end is at the bottom:

If you add this div

flex-direction: column
, And the left and right div design width is 50%, can the left and right sides be displayed?

.timelineItem { width : 50% ; & .right { text-align : left; align-self : flex-end; } & .left { text-align : right; align-self : flex-start; } } Copy code

Then there is the realization of the axis body. Here, the ::before pseudo-element + position is used to achieve it, but if the width is set to 1px, the problem of "dislocation" will occur.

This is also easy to understand, because the positioned "shaft body" is protruding from the original div. Can be set

However, 1px will produce psychological asymmetry, so I set the width to 2px and it is OK, and the shaft body looks fuller.

Just pass in a ReactChild to the custom node in the middle and it will be OK, and the font and background will not be repeated.

Project-personal project

Let me talk about how the waterfall flow is implemented first. You can use the following methods to achieve it:

  • multi-column multi-column layout
  • grid layout
  • flexbox layout
  • ...

Remember what I said earlier? We are making products, not making wheels, so don't worry about how to achieve it, just use existing NPM. Recommend react-masonry-css here . By the way, the effect of waterfall flow is really not called Water Fall in English, but masonry.

const Project = () => { return ( < Masonry breakpointCols = {{ default: 3 , 992: 2 , 786: 1 }} className = {styles.projectList} columnClassName = {styles.projectListColumn} > { => ( < Item { ...project } key = {project.logo}/> ))) </Masonry > ); }; Copy code
.projectList { display : flex; list-style-type : none !important ; } .projectListColumn { background-clip : padding-box; } Copy code

This library has a name

The props can display different numbers of columns under different screen widths, which is a very practical function.

The style of the project card is not nonsense, nothing more than

some type of.

Talk about it

stars 1.2K
How did the icon come from? First of all, if you are using Travis or Coveralls, the official website is automatically generated in some places. For example, if you click this icon on Travis CI, there will be an image URL of the icon.

Then don't I want to get the icon address on every website? And some websites may not yet. It is recommended to use the website, which can generate almost all our common Shield icons automatically.

The only disadvantage is: clicking this icon will not jump to the corresponding website. However, you can automatically generate multiple types of icons, you can also set the icon style, and you can customize the shield. What kind of bicycles do you want?

Then there is the acquisition of these small icons. Just get them at . The old folks should be familiar with them.

Finally, talk about this animation effect.

English name Jello , Chinese name is Gel (zh l ) .

@keyframes jello { 0% { transform : scale( 1 , 1 ); } 25% { transform : scale( 0.9 , 1.1 ); } 50% { transform : scale( 1.2 , 0.8 ); } 75% { transform : scale( 0.95 , 1.05 ); } } Copy code

Contact-find me

Because the backgrounds of the above sections are scrolling with the page, and this page does not have too many animation effects, I set the background here as

background-attachment: fixed
, So that it will not appear so monotonous.


backgroud-attachment: fixed
It can t be used on the mobile phone, it will become the cover style, so on the mobile phone, it should be set to

style = {{backgroundAttachment:? isMobile 'initial': 'fixed'}} copy the code

At the same time, the background here I chose black and white + individual comparison of a single photo, and not many bells and whistles, but also because this element section too little.

The style implementation is very simple, so I won't say more.


I talked about all the sections above, and this part talks about animation.

The following part is strongly subjective and may not be correct

I have added a lot of entrance animations to the homepage, and the library used is react-reveal . The function of this library is: when scrolling to the current element, use the animation entry effect to display the element. A very useful library. Although it is an old library, it is still very strong in animation, and its usage is simple:

Import Fade from 'REACT-Reveal/Fade' ; class FadeExample extends React . Component { render () { return ( < div > < Fade left > < h1 > React Reveal </h1 > </Fade > </div > ); } } Copy code

Animation is not as much as possible. Good design is not fancy, but restraint. Although I am not a designer, I try to follow Ant Design's design principles .


Try not to use exaggerated animations. Although react-reveals provides a lot of fancy animations, they are all too exaggerated.

99% I use the fade-in entry effect, the transition is more natural.


For the text on the Banner page, I wanted to use typed.js to output the entire text at the beginning:

After reading it, my colleague said: "The average interviewer is impatient to finish it", which made me realize that it is so inefficient. So I changed to display 90% of the text directly, and only the last words are printed in a loop.

Another scenario is that I used fade in from bottom to show each item:

There are many texts, pictures, and icons in each ProjectItem, so using upward animation will make it difficult to notice the content at the first time. You must wait for the animation to end to "see clearly" the content, and it is especially obvious on mobile phones. , is also inefficient in. So, I later changed to fade-in directly, speeding up the animation a little bit, and taking into account the entrance animation.

Contrast & Symmetry

If all admission are using fade in from bottom will become a little repetitive, so add a little contrast and symmetry can be slightly embellished it.

The first is in the Lamb Lottie animation and the downward arrow Lottie animation. The former gradually moves upwards, and the latter gradually moves downwards, forming a contrast. Because the arrow is down, so use fade in from top would be more logical .

Another place is the timeline here, left to right content usage admission, admission to the left then the right content, but also to follow the admission of animation logic .


The only place where exaggerated animation is used is " Please like, ask for attention, ask for reposting, three links in one click!" of "Contact me " .

The main reason is that this section is really too single, adding an exaggerated animation to add a bit of dynamic, it should not be too much to emphasize the animation here, haha .


Color, domestic aesthetic generally small fresh -oriented, and as Europe's gone rough road, so the use of the color flavors, colors, with red, yellow, orange, black -based.

The color values here are relatively similar. Do not choose a color with too large a color span, otherwise your page will become one piece in the east and one piece in the west, with a strong sense of fragmentation.

If you are not very sensitive to the selected color, may on Adobe's theme color is recommended , there are many ultra-theme color choice is yours.


The background is really hard to choose! The difficulties are:

  • Can't be too fancy. Otherwise, the content will be snatched away by the background
  • The size of the picture should be small. Many people will only open your homepage once. At this time, there is no HTTP cache, so when a large background is loaded, the effect of loading from the beginning to the foot will appear

Although only two points have been mentioned, 90% of the pictures are unqualified: landscape pictures, personal photos, and literary photos. However, these photos are often the key to improving the homepage. What pictures are there, small and not so single? the answer is:

In the case of background-repeat: repeat or background-size: cover|contain, there will not be too many visually changing pictures to meet the above requirements.

Here are two recommended websites that automatically generate advanced SVG background images:

  • svgbackgrounds , there are 48 free SVG backgrounds, and you can customize some styles, there are more than 200 paid, I think 48 is enough
  • was originally a website for loading animations. Later, SVG background images are also made. There are more custom templates in it. The free version can only generate static ones, and the paid version can generate dynamic SVG backgrounds. Similarly, the free version just Enough


At the code level, subcontracted with React's React.lazy and Suspense :

const Home = React.lazy( () => import ( './sections/Home' )); const About = React.lazy( () => import ( './sections/About' )); const Project = React .lazy( () => import ( './sections/Project' )); const Contact = React.lazy( () => import ( './sections/Contact' )); const Footer = React.lazy( ( ) => import ( './sections/Footer' )); const App: FC = () => ( < div id = "app" > < Suspense fallback = { < Loading/> }> < Nav/> < main > < Home/> < About/> < Project/> < Contact/> </main > < Footer/> </Suspense > </div > ); Copy code

For the picture optimization, had wanted to use imagemin Webpack to do but creat-react-app pit too, and tried to react-app-rewired and craco have no effect, well, themselves or manually compress it, anyway, not a few Graphs. Both the avatar and the background image are converted to webp format to minimize the size.

Finally font library optimized when it comes to this I used the font library HongLei above, the entire library has 1.1 MB , while I used the word "sea monster" is the word, a little does not pay. So, I used fontmin to compress the font library to 4 KB , which can display fonts faster.

At last

The entire homepage was written for 2 weeks in my spare time, most of the time I was trying out various designs, colors, and backgrounds, and the implementation was quite simple. Like it in my github point a Star right, fork and magic welcome change!

In fact, Github deployment and CDN acceleration are also very important. Since this article is too long, let's put it down.

By the way, I recently opened an official account [The Sea Monster Who Writes Code]. If you think I ve written well, you can also follow it whenever you want~