<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Koala Widgets</title>
	<atom:link href="https://staging.koalawidgets.com/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description></description>
	<lastBuildDate>Mon, 14 Oct 2024 13:53:22 +0000</lastBuildDate>
	<language>en-AU</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.2</generator>
	<item>
		<title>Easy CSS Only Animation between pages with @view-transition</title>
		<link>https://staging.koalawidgets.com/css-only-animation-between-pages-view-transition/</link>
		
		<dc:creator><![CDATA[8web]]></dc:creator>
		<pubDate>Mon, 14 Oct 2024 12:57:27 +0000</pubDate>
				<category><![CDATA[Web Designers]]></category>
		<guid isPermaLink="false">https://koalawidgets.com/?p=2315</guid>

					<description><![CDATA[<p>If you are wondering how to achieve the sliding transition between pages of this website, here&#8217;s the code to do so: 123456789101112131415161718192021222324252627282930313233/* Create a custom animation between pages */ @view-transition { &#160; navigation: auto; } @keyframes move-out { &#160; from { &#160; &#160; transform: translateX(0%); &#160; } &#160; to { &#160; &#160; transform: translateX(-100%); &#160; [&#8230;]</p>
<p>The post <a href="https://staging.koalawidgets.com/css-only-animation-between-pages-view-transition/">Easy CSS Only Animation between pages with @view-transition</a> appeared first on <a href="https://staging.koalawidgets.com">Koala Widgets</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div>If you are wondering how to achieve the sliding transition between pages of this website, here&#8217;s the code to do so:</div>
<div>
<p><div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">/* Create a custom animation between pages */<br />
@view-transition {<br />
&nbsp; navigation: auto;<br />
}<br />
@keyframes move-out {<br />
&nbsp; from {<br />
&nbsp; &nbsp; transform: translateX(0%);<br />
&nbsp; }<br />
<br />
&nbsp; to {<br />
&nbsp; &nbsp; transform: translateX(-100%);<br />
&nbsp; }<br />
}<br />
<br />
@keyframes move-in {<br />
&nbsp; from {<br />
&nbsp; &nbsp; transform: translateX(100%);<br />
&nbsp; }<br />
<br />
&nbsp; to {<br />
&nbsp; &nbsp; transform: translateX(0%);<br />
&nbsp; }<br />
}<br />
::view-transition-old(root) {<br />
&nbsp; animation: 0.4s ease-in both move-out;<br />
}<br />
::view-transition-new(root) {<br />
&nbsp; animation: 0.4s ease-in both move-in;<br />
}<br />
<br />
header.tm-header .uk-navbar-container{<br />
&nbsp; &nbsp; view-transition-name: header-transition;<br />
}</div></td></tr></tbody></table></div>
</p>
</div>
<div>The code above has 2 parts, the sliding effect and the header (desktop only) that doesn&#8217;t move.</div>
<h2>The sliding effect between pages</h2>
<div>The sliding effect is achieved using the code from line 2 to 29. You can copy this code to your website and you will obtain exactly the same effect.</div>
<p><img decoding="async" src="/wp-content/uploads/2024/10/view-transition-sliding-effect.jpg" alt=""></p>
<h2>The header remains static</h2>
<div>I&#8217;ve assigned a unique view-transition-name to the header, to exclude it from the sliding transition.</div>
<div>That way, it looks like the header remains static while the rest of the content slides in.</div>
<div>This is achieved in lines 31 to 33 from the code above.</div>
<h2>Documentation</h2>
<div>
<p>You can find more info about <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@view-transition" target="_blank" rel="noopener">@view-transition here</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/view-transition-name" target="_blank" rel="noopener">view-transition-name here</a>.</p>
</div>
<div>
<p>        <img decoding="async" src="/wp-content/uploads/2024/09/pablo-blue-bg.jpg" alt=""></p>
<h3>Pablo A Santamaria</h3>
<p>Written by</p>
<div>
<p>Entrepreneur &#038; developer with a passion for CSS &amp; SaaS. CoFounder of Koala Widgets.</p>
<p><a class="el-link uk-icon-button" href="https://x.com/pabo_" target="_blank" rel="noopener noreferrer"><span uk-icon="icon: x;" class="uk-icon"></span></a></p>
</div>
</div>
<p><span id="more-2315"></span><br />
<!-- {"type":"layout","children":[{"type":"section","props":{"image_position":"center-center","padding_remove_top":false,"style":"default","title_breakpoint":"xl","title_position":"top-left","title_rotation":"left","vertical_align":"","width":"small"},"children":[{"type":"row","props":{"layout":"2-3,1-3","margin":"default","row_gap":"large"},"children":[{"type":"column","props":{"image_position":"center-center","position_sticky_breakpoint":"m","width_medium":"2-3"},"children":[{"type":"headline","props":{"block_align":"center","text_align":"center","title_element":"h1"},"source":{"query":{"name":"posts.singlePost"},"props":{"content":{"filters":{"search":""},"name":"title"}}}},{"type":"text","props":{"column_breakpoint":"m","content":"If you are wondering how to achieve the sliding transition between pages of this website, here's the code to do so:","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p><code>\/* Create a custom animation between pages *\/\n@view-transition {\n  navigation: auto;\n}\n@keyframes move-out {\n  from {\n    transform: translateX(0%);\n  }\n\n  to {\n    transform: translateX(-100%);\n  }\n}\n\n@keyframes move-in {\n  from {\n    transform: translateX(100%);\n  }\n\n  to {\n    transform: translateX(0%);\n  }\n}\n::view-transition-old(root) {\n  animation: 0.4s ease-in both move-out;\n}\n::view-transition-new(root) {\n  animation: 0.4s ease-in both move-in;\n}\n\nheader.tm-header .uk-navbar-container{\n    view-transition-name: header-transition;\n}<\/code><\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"The code above has 2 parts, the sliding effect and the header (desktop only) that doesn't move.","margin":"default"}},{"type":"headline","props":{"content":"The sliding effect between pages","margin_remove_top":true,"title_element":"h2"},"name":"h2"},{"type":"text","props":{"column_breakpoint":"m","content":"The sliding effect is achieved using the code from line 2 to 29. You can copy this code to your website and you will obtain exactly the same effect.","margin":"default"}},{"type":"image","props":{"image":"wp-content\/uploads\/2024\/10\/view-transition-sliding-effect.jpg","image_svg_color":"emphasis","margin":"default"}},{"type":"headline","props":{"content":"The header remains static","margin_remove_top":true,"title_element":"h2"},"name":"h2"},{"type":"text","props":{"column_breakpoint":"m","content":"I've assigned a unique view-transition-name to the header, to exclude it from the sliding transition.","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"That way, it looks like the header remains static while the rest of the content slides in.","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"This is achieved in lines 31 to 33 from the code above.","margin":"default"}},{"type":"headline","props":{"content":"Documentation","margin_remove_top":true,"title_element":"h2"},"name":"h2"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>You can find more info about <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/@view-transition\" target=\"_blank\" rel=\"noopener\">@view-transition here<\/a> and <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/view-transition-name\" target=\"_blank\" rel=\"noopener\">view-transition-name here<\/a>.<\/p>","margin":"default"}}]},{"type":"column","props":{"image_position":"center-center","position_sticky_breakpoint":"m","width_medium":"1-3"},"children":[{"type":"panel","props":{"content":"

<p>Entrepreneur & developer with a passion for CSS &amp; SaaS. CoFounder of Koala Widgets.<\/p>\n

<p><a class=\"el-link uk-icon-button\" href=\"https:\/\/x.com\/pabo_\" target=\"_blank\" rel=\"noopener noreferrer\"><span uk-icon=\"icon: x;\" class=\"uk-icon\"><\/span><\/a><\/p>","content_column_breakpoint":"m","css":".el-image{max-width:80px;}","icon_width":80,"image":"wp-content\/uploads\/2024\/09\/pablo-blue-bg.jpg","image_align":"top","image_border":"circle","image_box_decoration":"mask","image_grid_breakpoint":"m","image_grid_width":"1-2","image_svg_color":"emphasis","link_style":"default","link_target":false,"link_text":"Follow on X","margin":"default","margin_remove_bottom":true,"meta":"Written by","meta_align":"above-title","meta_element":"div","meta_style":"text-meta","panel_padding":"small","panel_style":"card-secondary","text_align":"center","title":"Pablo A Santamaria","title_align":"top","title_element":"h3","title_grid_breakpoint":"m","title_grid_width":"1-2","title_hover_style":"reset","title_margin":"remove","title_style":"h4"}}]}]}],"name":"Post"}],"version":"4.4.10"} --></p>
<p>The post <a href="https://staging.koalawidgets.com/css-only-animation-between-pages-view-transition/">Easy CSS Only Animation between pages with @view-transition</a> appeared first on <a href="https://staging.koalawidgets.com">Koala Widgets</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Grow your Web Design Business Effectively</title>
		<link>https://staging.koalawidgets.com/how-to-grow-web-design-business-effectively/</link>
		
		<dc:creator><![CDATA[8web]]></dc:creator>
		<pubDate>Fri, 13 Sep 2024 05:58:49 +0000</pubDate>
				<category><![CDATA[Web Designers]]></category>
		<guid isPermaLink="false">https://koalawidgets.com/?p=2275</guid>

					<description><![CDATA[<p>5 Different ways to grow your web design business There are many publications that talk about how to scale a business, but what is the best way to grow a web design business specifically? The solution may sound simple, sell more websites and hire employees to build them. Well, that&#8217;s a way to do it, [&#8230;]</p>
<p>The post <a href="https://staging.koalawidgets.com/how-to-grow-web-design-business-effectively/">How to Grow your Web Design Business Effectively</a> appeared first on <a href="https://staging.koalawidgets.com">Koala Widgets</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><img decoding="async" src="/wp-content/uploads/2024/09/IST_31178_06646.jpg" alt="Lady thinking of 5 Different ways to grow her web design business"></p>
<h2>5 Different ways to grow your web design business</h2>
<div>
<p>There are many publications that talk about how to scale a business, but what is the best way to grow a web design business specifically?</p>
</div>
<div>
<p>The solution may sound simple, sell more websites and hire employees to build them.</p>
<p>Well, that&#8217;s a way to do it, but is it the best way? Are there any other ways to do it?</p>
<p>The answer to the first question is &#8220;it depends&#8221; and the second is &#8220;yes&#8221;.</p>
<p>You will find this helpful if you are a solopreneur, freelancer or you may have a team working for you already and are exploring other ways to grow your business.</p>
<p>In reality, the only way to be able to scale your business is by removing bottle necks.</p>
<p>The main bottle neck by excellence is time. It is the one resource that you can&#8217;t get more of.</p>
<p>The key to grow your business is divorcing wealth from time.</p>
<p>To do so, you should create a system that works, even if you don&#8217;t put any time into it.</p>
<p>MJ DeMarco on his book The Millionaire Fastlane writes about the 5 types systems, he calls them money trees: rental systems, computer/software systems, content systems, distribution systems and human resources systems.</p>
</div>
<h3>
<div>
<div><span>Human Resources Systems</span></div>
</div>
</h3>
<div>
<p>The simple solution we mentioned before is a human resources system.</p>
<p>I&#8217;ve seen many stories of web design agencies that grew up this way.</p>
<p>To do so, they also have a team/person executing a marketing strategy that helps them bring a constant influx of new clients.</p>
<p>These agencies tipically become marketing agencies and offer services such as SEO or Social Media Marketing, that&#8217;s generally something they do well, it was what allow them to get enough clients to hire employees in the first place, now they can do it for others.</p>
<p>But if you are like me, you&#8217;re probably better at creating awesome websites and not so good at promoting yourself or your services and don&#8217;t have enough work to start employing people.</p>
<p>Let&#8217;s explore the other ways to scale your business.</p>
</div>
<h3>Rental Systems</h3>
<div>
<p>Renting equipment is not really something a web designer wants to do.</p>
<p>How about renting space in your server, so people can put their websites there.</p>
<p>That&#8217;s right, we are talking about website hosting, it is a rental system.</p>
<p>Warning, this is not a good option for everybody, specialised technical knowledge is necessary and you&#8217;ll need to provide support to your clients.</p>
<p>This type of system may or may not be for you, but even if it isn&#8217;t, there is nothing stopping you from making some money from it.</p>
<p>There are companies that pay recurring commissions in their website hosting affiliate programs.</p>
<p><a href="https://kinsta.com/affiliates/" target="_blank" rel="noopener">Kinsta</a> in the US or <a href="https://8webdesign.au/affiliate-program/" target="_blank" rel="noopener">8 Web Design</a> in Australia are great options.</p>
</div>
<h3>Distribution Systems</h3>
<div>
<p>As a web designer, it&#8217;s hard to imagine a distribution system.</p>
<p>The best example of a distribution system in our field is <a href="https://elements.envato.com/web-templates" target="_blank" rel="noopener">Envato Market</a>. Where template/theme creators can sell their creations.</p>
<p>Uber, AirBnB and Amazon are just some of the most well known businesses of this kind.</p>
<p>You may have the ability to build a website to connect sellers and buyers.</p>
<p>If you have a killer idea, as a web designer you have an unfair advantage to be the creator of the next &#8220;AirBnB of [blank]&#8221;.</p>
</div>
<h3>Content Systems</h3>
<div>
<p>Youtube channels, blogs, courses, newsletters, podcasts are great examples of content systems.</p>
<p>As a web designer, you could start one of these.</p>
<p>Becoming a successful content creator is not easy, there is a lot of competition and people&#8217;s attention is becoming a more and more scarse resource these days.</p>
<p>That&#8217;s why when it comes to content systems, I have a hybrid approach:</p>
<p>Use content systems to help you promote your other services/products.</p>
<p>If you happen to do great and this system may become your main thing, but if not, you are still getting the benefits of a small audience.</p>
<p>There are plenty of stories out there about web designers creating content systems.</p>
<p><a href="https://x.com/KevinJPowell" target="_blank" rel="noopener">Kevin Powell</a>&#8216;s story is a great example, not only because he has a successful <a href="https://www.youtube.com/@KevinPowell" target="_blank" rel="noopener">Youtube Channel</a>, but also because he has <a href="https://www.kevinpowell.co/courses/" target="_blank" rel="noopener">courses to teach CSS</a>.</p>
<p>Two different content systems that support each other, needless to say, that&#8217;s Kev&#8217;s main activity now.</p>
</div>
<h3>Computer/Sowtware Systems</h3>
<div>
<p>I&#8217;ve left this type of system last, because that&#8217;s the route I&#8217;ve chosen.</p>
<p>Out of all types of systems mentioned, it is the most interesting to me because the Internet has made more millionaires in 10 years than there were in the previous century.</p>
<p>Also, once a software is built, they can be run with very little maintenance.</p>
<p>As a web designer, the obvious place to start is by building an online application of some sort.</p>
<p>The most common way to monetise an online application is via subscription, making it a rental system as well.</p>
<p>At Koala Widgets, we build software systems in the form of Widgets that people can embed in their websites.</p>
<p>Our clients pay a subscription and they get something that attracts visitors to their websites.</p>
<p>After the widget is built, we can have 1, 10, a thousand or a million users and the work won&#8217;t change much, it&#8217;s very scalable.</p>
</div>
<h2>
<div>
<div><span>Conclusion</span></div>
</div>
</h2>
<div>
<p>I hope this article gives you an overview of the different ways to grow your web design business.</p>
<p>I know, in some cases, it means changing the business model.</p>
<p>BTW, if you haven&#8217;t read my previous article where I explain <a href="/web-design-bad-business-model/">why Web Design is a bad business model</a>, you may want to check it out.</p>
</div>
<div>
<p>        <img decoding="async" src="/wp-content/uploads/2024/09/pablo-blue-bg.jpg" alt=""></p>
<h3>Pablo A Santamaria</h3>
<p>Written by</p>
<div>
<p>Entrepreneur &#038; developer with a passion for CSS &amp; SaaS. CoFounder of Koala Widgets.</p>
<p><a class="el-link uk-icon-button" href="https://x.com/pabo_" target="_blank" rel="noopener noreferrer"><span uk-icon="icon: x;" class="uk-icon"></span></a></p>
</div>
</div>
<p><span id="more-2275"></span><br />
<!-- {"type":"layout","children":[{"type":"section","props":{"image_position":"center-center","padding_remove_top":false,"style":"default","title_breakpoint":"xl","title_position":"top-left","title_rotation":"left","vertical_align":"","width":"small"},"children":[{"type":"row","props":{"layout":"2-3,1-3","margin":"default","row_gap":"large"},"children":[{"type":"column","props":{"image_position":"center-center","position_sticky_breakpoint":"m","width_medium":"2-3"},"children":[{"type":"headline","props":{"block_align":"center","text_align":"center","title_element":"h1"},"source":{"query":{"name":"posts.singlePost"},"props":{"content":{"filters":{"search":""},"name":"title"}}}},{"type":"image","props":{"image":"wp-content\/uploads\/2024\/09\/IST_31178_06646.jpg","image_alt":"Lady thinking of 5 Different ways to grow her web design business","image_svg_color":"emphasis","margin":"default"}},{"type":"headline","props":{"content":"5 Different ways to grow your web design business","margin_remove_bottom":true,"title_element":"h2"},"name":"h2"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>There are many publications that talk about how to scale a business, but what is the best way to grow a web design business specifically?<\/p>","margin":"default","text_color":"emphasis","text_style":"large"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>The solution may sound simple, sell more websites and hire employees to build them.<\/p>\n

<p>Well, that's a way to do it, but is it the best way? Are there any other ways to do it?<\/p>\n

<p>The answer to the first question is \"it depends\" and the second is \"yes\".<\/p>\n

<p>You will find this helpful if you are a solopreneur, freelancer or you may have a team working for you already and are exploring other ways to grow your business.<\/p>\n

<p>In reality, the only way to be able to scale your business is by removing bottle necks.<\/p>\n

<p>The main bottle neck by excellence is time. It is the one resource that you can't get more of.<\/p>\n

<p>The key to grow your business is divorcing wealth from time.<\/p>\n

<p>To do so, you should create a system that works, even if you don't put any time into it.<\/p>\n

<p>MJ DeMarco on his book The Millionaire Fastlane writes about the 5 types systems, he calls them money trees: rental systems, computer\/software systems, content systems, distribution systems and human resources systems.<\/p>","margin":"default","text_color":"emphasis"}},{"type":"headline","props":{"content":"

<div>\n

<div><span>Human Resources Systems<\/span><\/div>\n<\/div>","margin_remove_bottom":true,"title_element":"h3"},"name":"h3"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>The simple solution we mentioned before is a human resources system.<\/p>\n

<p>I've seen many stories of web design agencies that grew up this way.<\/p>\n

<p>To do so, they also have a team\/person executing a marketing strategy that helps them bring a constant influx of new clients.<\/p>\n

<p>These agencies tipically become marketing agencies and offer services such as SEO or Social Media Marketing, that's generally something they do well, it was what allow them to get enough clients to hire employees in the first place, now they can do it for others.<\/p>\n

<p>But if you are like me, you're probably better at creating awesome websites and not so good at promoting yourself or your services and don't have enough work to start employing people.<\/p>\n

<p>Let's explore the other ways to scale your business.<\/p>","margin":"default","text_color":"emphasis"}},{"type":"headline","props":{"content":"Rental Systems","margin_remove_bottom":true,"title_element":"h3"},"name":"h3"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Renting equipment is not really something a web designer wants to do.<\/p>\n

<p>How about renting space in your server, so people can put their websites there.<\/p>\n

<p>That's right, we are talking about website hosting, it is a rental system.<\/p>\n

<p>Warning, this is not a good option for everybody, specialised technical knowledge is necessary and you'll need to provide support to your clients.<\/p>\n

<p>This type of system may or may not be for you, but even if it isn't, there is nothing stopping you from making some money from it.<\/p>\n

<p>There are companies that pay recurring commissions in their website hosting affiliate programs.<\/p>\n

<p><a href=\"https:\/\/kinsta.com\/affiliates\/\" target=\"_blank\" rel=\"noopener\">Kinsta<\/a> in the US or <a href=\"https:\/\/8webdesign.au\/affiliate-program\/\" target=\"_blank\" rel=\"noopener\">8 Web Design<\/a> in Australia are great options.<\/p>","margin":"default","text_color":"emphasis"}},{"type":"headline","props":{"content":"Distribution Systems","margin_remove_bottom":true,"title_element":"h3"},"name":"h3"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>As a web designer, it's hard to imagine a distribution system.<\/p>\n

<p>The best example of a distribution system in our field is <a href=\"https:\/\/elements.envato.com\/web-templates\" target=\"_blank\" rel=\"noopener\">Envato Market<\/a>. Where template\/theme creators can sell their creations.<\/p>\n

<p>Uber, AirBnB and Amazon are just some of the most well known businesses of this kind.<\/p>\n

<p>You may have the ability to build a website to connect sellers and buyers.<\/p>\n

<p>If you have a killer idea, as a web designer you have an unfair advantage to be the creator of the next \"AirBnB of [blank]\".<\/p>","margin":"default","text_color":"emphasis"}},{"type":"headline","props":{"content":"Content Systems","margin_remove_bottom":true,"title_element":"h3"},"name":"h3"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Youtube channels, blogs, courses, newsletters, podcasts are great examples of content systems.<\/p>\n

<p>As a web designer, you could start one of these.<\/p>\n

<p>Becoming a successful content creator is not easy, there is a lot of competition and people's attention is becoming a more and more scarse resource these days.<\/p>\n

<p>That's why when it comes to content systems, I have a hybrid approach:<\/p>\n

<p>Use content systems to help you promote your other services\/products.<\/p>\n

<p>If you happen to do great and this system may become your main thing, but if not, you are still getting the benefits of a small audience.<\/p>\n

<p>There are plenty of stories out there about web designers creating content systems.<\/p>\n

<p><a href=\"https:\/\/x.com\/KevinJPowell\" target=\"_blank\" rel=\"noopener\">Kevin Powell<\/a>'s story is a great example, not only because he has a successful <a href=\"https:\/\/www.youtube.com\/@KevinPowell\" target=\"_blank\" rel=\"noopener\">Youtube Channel<\/a>, but also because he has <a href=\"https:\/\/www.kevinpowell.co\/courses\/\" target=\"_blank\" rel=\"noopener\">courses to teach CSS<\/a>.<\/p>\n

<p>Two different content systems that support each other, needless to say, that's Kev's main activity now.<\/p>","margin":"default","text_color":"emphasis"}},{"type":"headline","props":{"content":"Computer\/Sowtware Systems","margin_remove_bottom":true,"title_element":"h3"},"name":"h3"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>I've left this type of system last, because that's the route I've chosen.<\/p>\n

<p>Out of all types of systems mentioned, it is the most interesting to me because the Internet has made more millionaires in 10 years than there were in the previous century.<\/p>\n

<p>Also, once a software is built, they can be run with very little maintenance.<\/p>\n

<p>As a web designer, the obvious place to start is by building an online application of some sort.<\/p>\n

<p>The most common way to monetise an online application is via subscription, making it a rental system as well.<\/p>\n

<p>At Koala Widgets, we build software systems in the form of Widgets that people can embed in their websites.<\/p>\n

<p>Our clients pay a subscription and they get something that attracts visitors to their websites.<\/p>\n

<p>After the widget is built, we can have 1, 10, a thousand or a million users and the work won't change much, it's very scalable.<\/p>","margin":"default","text_color":"emphasis"}},{"type":"headline","props":{"content":"

<div>\n

<div><span>Conclusion<\/span><\/div>\n<\/div>","margin_remove_bottom":true,"title_element":"h2"},"name":"h2"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>I hope this article gives you an overview of the different ways to grow your web design business.<\/p>\n

<p>I know, in some cases, it means changing the business model.<\/p>\n

<p>BTW, if you haven't read my previous article where I explain <a href=\"\/web-design-bad-business-model\/\">why Web Design is a bad business model<\/a>, you may want to check it out.<\/p>","margin":"default","text_color":"emphasis"}}]},{"type":"column","props":{"image_position":"center-center","position_sticky_breakpoint":"m","width_medium":"1-3"},"children":[{"type":"panel","props":{"content":"

<p>Entrepreneur & developer with a passion for CSS &amp; SaaS. CoFounder of Koala Widgets.<\/p>\n

<p><a class=\"el-link uk-icon-button\" href=\"https:\/\/x.com\/pabo_\" target=\"_blank\" rel=\"noopener noreferrer\"><span uk-icon=\"icon: x;\" class=\"uk-icon\"><\/span><\/a><\/p>","content_column_breakpoint":"m","css":".el-image{max-width:80px;}","icon_width":80,"image":"wp-content\/uploads\/2024\/09\/pablo-blue-bg.jpg","image_align":"top","image_border":"circle","image_box_decoration":"mask","image_grid_breakpoint":"m","image_grid_width":"1-2","image_svg_color":"emphasis","link_style":"default","link_target":false,"link_text":"Follow on X","margin":"default","margin_remove_bottom":true,"meta":"Written by","meta_align":"above-title","meta_element":"div","meta_style":"text-meta","panel_padding":"small","panel_style":"card-secondary","text_align":"center","title":"Pablo A Santamaria","title_align":"top","title_element":"h3","title_grid_breakpoint":"m","title_grid_width":"1-2","title_hover_style":"reset","title_margin":"remove","title_style":"h4"}}]}]}],"name":"Post"}],"version":"4.4.10"} --></p>
<p>The post <a href="https://staging.koalawidgets.com/how-to-grow-web-design-business-effectively/">How to Grow your Web Design Business Effectively</a> appeared first on <a href="https://staging.koalawidgets.com">Koala Widgets</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to center elements on the last row in CSS Grid?</title>
		<link>https://staging.koalawidgets.com/how-to-center-elements-on-the-last-row-in-css-grid/</link>
		
		<dc:creator><![CDATA[8web]]></dc:creator>
		<pubDate>Wed, 28 Aug 2024 02:16:24 +0000</pubDate>
				<category><![CDATA[Web Designers]]></category>
		<guid isPermaLink="false">https://koalawidgets.com/?p=2142</guid>

					<description><![CDATA[<p>If you are looking for a quick answer to center elements in the last row of CSS Grid, use the codepen below. Getting here wasn&#8217;t a straight forward process. Read below if you want to learn in depth how this code works, how to expand this solution and how I got here. See the Pen [&#8230;]</p>
<p>The post <a href="https://staging.koalawidgets.com/how-to-center-elements-on-the-last-row-in-css-grid/">How to center elements on the last row in CSS Grid?</a> appeared first on <a href="https://staging.koalawidgets.com">Koala Widgets</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div>
<p>If you are looking for a quick answer to center elements in the last row of CSS Grid, use the codepen below.</p>
<p>Getting here wasn&#8217;t a straight forward process. Read below if you want to learn in depth how this code works, how to expand this solution and how I got here.</p>
</div>
<div>
<p class="codepen" data-height="572" data-theme-id="dark" data-slug-hash="abgKYXv" data-pen-title="Untitled" data-user="koalawidgets" style="height: 472px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/koalawidgets/pen/abgKYXv"><br />
  Untitled</a> by Koala Widgets (<a href="https://codepen.io/koalawidgets">@koalawidgets</a>)<br />
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<p><script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
</div>
<h2>Defining the desired layout</h2>
<div>
<p>For a while, I&#8217;ve been searching for a flexible layout that meets these criteria:</p>
</div>
<ul>
<li>
<div>The elements should have a flexible width</div>
</li>
<li>
<div>The last row should be centered</div>
</li>
<li>
<div>It should be easy to edit, so it&#8217;s a copy/paste process to use in other projects</div>
</li>
<li>
<div>All the elements should have the same width</div>
</li>
<li>
<div>All the elements in the same row should have the same height</div>
</li>
<li>
<div>The number of columns should change automatically, according to the screen width</div>
</li>
<li>
<div>The solution should work for any number of elements</div>
</li>
<li>
<div>There should be a gap between the elements</div>
</li>
<li>
<div>The solution should be achievable with CSS. Meaning, no Javascript.</div>
</li>
<li>
<div>The elements should use the full width of the wrapper</div>
</li>
</ul>
<p><img decoding="async" src="/wp-content/uploads/2024/08/Screen-Shot-2024-08-28-at-12.48.20-pm.png" alt="Desired layout after centering elements on the last row in CSS Grid"></p>
<h2>The right time to find a solution to center the last row elements in a grid using CSS</h2>
<div>
<p>In the past, I settled for solutions that don&#8217;t meet all my criteria, however, with the current state of CSS, I thought it must be possible.</p>
</div>
<h3>There is Hope</h3>
<div>
<p>My CSS mentor <a href="https://x.com/KevinJPowell" target="_blank" rel="noopener">Kevin Powell</a> recently did a live YouTube <a href="https://www.youtube.com/watch?v=S2XstSrGJOw" target="_blank" rel="noopener">responsive layouts workshop</a>. If there is someone who knows how to achieve this, that is Kev.</p>
</div>
<div>
<p>At some point in the video 1:50:55, Kev had a grid on his screen and somebody asked to center the last row elements.</p>
</div>
<div>
<p>His response was both dissapointing and hopeful; &#8220;<em>That&#8217;s something I wouldn&#8217;t be able to do with grid&#8230; I wouldn&#8217;t use grid, in that case I would use flexbox</em>&#8220;.</p>
</div>
<div>
<p>This got me started on a quest to find a solution using flexbox.</p>
</div>
<h3>The YOOTheme approach that works</h3>
<div>
<p>Since we are using the page builder YOOTheme Pro in this website, we can easily use the editor to add a Grid, and configure the settings to achieve the desired result.</p>
</div>
<ul>
<li>
<h3>Title</h3>
<div>
<p>Lorem ipsum dolor sit amet</p>
</div>
</li>
<li>
<h3>Title</h3>
<div>
<p>Lorem ipsum dolor sit amet.</p>
<p>Longer.</p>
</div>
</li>
<li>
<h3>Title</h3>
<div>
<p>Lorem ipsum dolor sit amet</p>
</div>
</li>
<li>
<h3>Title</h3>
<div>
<p>Lorem ipsum dolor sit amet</p>
</div>
</li>
<li>
<h3>Title</h3>
<div>
<p>Lorem ipsum dolor sit amet</p>
</div>
</li>
<li>
<h3>Title</h3>
<div>
<p>Lorem ipsum dolor sit amet</p>
</div>
</li>
<li>
<h3>Title</h3>
<div>
<p>Lorem ipsum dolor sit amet</p>
</div>
</li>
</ul>
<p><img decoding="async" src="/wp-content/uploads/2024/08/Screen-Shot-2024-08-28-at-1.59.19-pm.png" alt=""></p>
<div>
<p>At first sight, this grid meets all the criteria, so let&#8217;s start by looking at the source code. You are welcome to inspect it in your browser as well.</p>
</div>
<div>
<p>This is the HTML when there are 4 columns showing.</p>
</div>
<p><img decoding="async" src="/wp-content/uploads/2024/08/Screen-Shot-2024-08-28-at-2.09.23-pm.png" alt="Code used by Yootheme Pro to center elements on the last row in CSS Grid"></p>
<div>
<p>The main code to achieve this is a simple flexbox that justifies the content in the centre.</p>
</div>
<p><img decoding="async" src="/wp-content/uploads/2024/08/Screen-Shot-2024-08-28-at-2.14.20-pm.png" alt="Code used by Yootheme Pro to center elements on the last row using flexbox"></p>
<div>
<p>Flexbox is also allowing all the items in the same row to have the same height.</p>
</div>
<div>
<p>Then, they use percentages to control the column width based on the screen size, so there is a fair bit of code behind this, which is totally fine.</p>
</div>
<div>
<p>Also, for the gap between the elements, they are using a left padding on the elements, and a negative padding on the wrapper, to even out the first element of each row.</p>
</div>
<p><img decoding="async" src="/wp-content/uploads/2024/08/Screen-Shot-2024-08-28-at-2.11.04-pm.png" alt="Media queries example"></p>
<div>
<p>In conclusion, this is a good approach and I would just need to define the number of columns according to the screen width as I did in the settings of YOOTheme Pro.</p>
</div>
<div>
<p>However, it is not as portable as I would like, because I would need to pre-define break points for the media queries, which may be different in other projects.</p>
</div>
<div>
<p>Also, telling the number of columns in various screen sizes, is not as elegant as simply defining the minimun size of the items.</p>
</div>
<div>
<p>So, here&#8217;s my quest to find such solution:</p>
</div>
<h3>Looking for a simpler flexbox solution to center elements in the last row</h3>
<div>
<p>Using flexbox by default almost worked perfectly, except for the last column, that stretched the item to take the full width of the row.</p>
</div>
<p><img decoding="async" src="/wp-content/uploads/2024/08/Screen-Shot-2024-08-27-at-7.58.19-pm.png" alt="Attempt 1 to center elements in the last row using flexbox"></p>
<div>
<p>The solution for this is simple, just use</p>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">flex-grow:0;</div></td></tr></tbody></table></div>
</p>
</div>
<p><img decoding="async" src="/wp-content/uploads/2024/08/Screen-Shot-2024-08-27-at-7.57.33-pm.png" alt="Attempt 2 to center elements in the last row using flexbox"></p>
<div>While this centers the items neatly, the items in the first columns are not using 100% of the wrapper width, which doesn&#8217;t meet the criteria. </div>
<div>I&#8217;m out of ideas using flexbox, all roads take me to the Yootheme Pro approach, so I started exploring the Grid option.</div>
<h2>Exploring Grid</h2>
<div>Grid by default meets all my criteria, except centering the elements in the last row, so if I can solve that somehow, the job is done.</div>
<div>
<p>Luckily, I came across the article <a href="https://css-irl.info/controlling-leftover-grid-items/" target="_blank" rel="noopener">Controlling Leftover Grid Items with Pseudo-selectors</a> where the author finds a solution to center elements in the last row of grid.</p>
</div>
<div>
<p>This is a very clever solution, just assign 2 cells to every item, then move the item in the last row to the desired position.</p>
</div>
<div>Their article uses a 3 column layout and explains how to achieve the result when there are 1 or 2 items in the last row.</div>
<h3>Centering the elements</h3>
<h4>2 Column Layouts</h4>
<p><img decoding="async" src="/wp-content/uploads/2024/09/Screen-Shot-2024-09-02-at-9.16.30-pm.png" alt="2 column CSS grid with item in the last row centered"></p>
<div>
<p>In the image above, the last item is targetted in CSS, by selecting the last element, that is also an odd number. Keep in mind, that another way to say &#8220;odd numbers&#8221; is by selecting the multiples of 2, then adding a unit to it: 2n + 1.</p>
</div>
<div>
<p>Then, we just tell this item to end in line #4. As you can see in the image, lines are placed at the beginning at the end and at the gaps.</p>
</div>
<div>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br />2<br />3<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">.item:last-child:nth-child(2n + 1){<br />
&nbsp; &nbsp; grid-column-end:4;<br />
}</div></td></tr></tbody></table></div>
</div>
<div>That&#8217;s all we need to do when there are 2 columns, but when there are 3 columns the solution is a bit different.</div>
<h4>3 Column Layouts</h4>
<p><img decoding="async" src="/wp-content/uploads/2024/09/Screen-Shot-2024-09-02-at-9.26.00-pm.png" alt="3 column CSS grid with item in the last row centered"></p>
<div>When there is only 1 item in the last row, we need to select the last element that also follows the sequence 4, 7, 10, 13&#8230; In other words multiples of 3 but adding a unit to it: 3n+1. And tell it to finish in line #5.</div>
<div>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br />2<br />3<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">.item:last-child:nth-child(3n + 1){<br />
&nbsp; &nbsp; grid-column-end: 5;<br />
}</div></td></tr></tbody></table></div>
</div>
<div>
<p>When there are 2 item in the last row, we need to select the second last element that also follows the sequence 4, 7, 10, 13&#8230; And tell it to finish in line #4.</p>
</div>
<p><img decoding="async" src="/wp-content/uploads/2024/09/Screen-Shot-2024-09-02-at-9.25.32-pm.png" alt="3 column CSS grid with 2 items in the last row centered"></p>
<div>
<p><div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br />2<br />3<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">.item:nth-last-child(2):nth-child(3n + 1){<br />
&nbsp; &nbsp; grid-column-end: 4;<br />
}</div></td></tr></tbody></table></div>
</p>
</div>
<div>
<p>Then, the actual last item will be automatically placed in the right spot as it remains next to the second last.</p>
</div>
<div>Now that we&#8217;ve done it with 2 and 3 columns, you get the idea. In my final solution I also did 4, 5 and 6 columns, but you can keep going if you need to.</div>
<h3>Determining the number of columns</h3>
<div>You may be wondering, what&#8217;s the point of adding all the code for various numbers of columns, if we still don&#8217;t know the number of columns to use.</div>
<div>Well, to determine the number of columns, we need to define the width of the items, and remember, we want to achieve a layout that allows for elements with variable width.</div>
<div>
<p>So let&#8217;s start by defining a couple of variables:</p>
<ul>
<li>Item width</li>
<li>Grid gap</li>
</ul>
</div>
<div>
<p><div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">:root{<br />
&nbsp; --min-width:200px;<br />
&nbsp; --grid-gap:20px;<br />
}</div></td></tr></tbody></table></div>
</p>
</div>
<div>In order to make this code portable between projects, I created these values as variables, so they can be easily edited in one place.</div>
<div>Now, let&#8217;s define the item, so it occupies 2 columns in the grid.</div>
<div>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br />2<br />3<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">.item{<br />
&nbsp; grid-column: span 2;<br />
}</div></td></tr></tbody></table></div>
</div>
<div>Now, let&#8217;s define the grid.</div>
<div>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">.wrapper{<br />
&nbsp; display: grid;<br />
&nbsp; grid-gap: var(--grid-gap);<br />
&nbsp; <br />
&nbsp; /* Defining the columns */<br />
&nbsp; grid-template-columns: repeat(<br />
&nbsp; &nbsp; auto-fit,<br />
&nbsp; &nbsp; minmax(<br />
&nbsp; &nbsp; &nbsp; min(<br />
&nbsp; &nbsp; &nbsp; &nbsp; calc((var(--min-width) - var(--grid-gap))/2),<br />
&nbsp; &nbsp; &nbsp; &nbsp; calc((100% - var(--grid-gap)) / 2)<br />
&nbsp; &nbsp; &nbsp; ),<br />
&nbsp; &nbsp; &nbsp; 1fr<br />
&nbsp; &nbsp; )<br />
&nbsp; );<br />
&nbsp; <br />
&nbsp; /* Setting up the container for the queries */<br />
&nbsp; container: grid-wrapper / inline-size;<br />
&nbsp; <br />
&nbsp; /* Optional */<br />
&nbsp; max-width:calc(var(--min-width)*6 + var(--grid-gap)*5);<br />
}</div></td></tr></tbody></table></div>
</div>
<div>
<p>To understand what we are doing here, I&#8217;m assuming that you understand how display:grid; works, so the display and grid-gap attributes should be self-explanatory. If not, you can check these <a href="https://www.youtube.com/playlist?list=PL4-IK0AVhVjPv5tfS82UF_iQgFp4Bl998" target="_blank" rel="noopener">great videos on Grid</a>.</p>
</div>
<div>
<p>The tricky line to understand is grid-template-columns. We are using <em>repeat</em> to define the columns. <em>Repeat</em> has 2 arguments:</p>
</div>
<div>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">grid-template-columns: repeat(<br />
&nbsp; &nbsp; auto-fit,<br />
&nbsp; &nbsp; minmax(...)<br />
);</div></td></tr></tbody></table></div>
</div>
<div>
<p>The first argument defines the number of times that the track list should be repeated. We&#8217;ve used <em>auto-fit</em> in this case which automatically adjust the number of repetitions to the largest possible number that doesn&#8217;t cause the grid to overflow.</p>
</div>
<div>
<p>The second argument is using a <em>minmax()</em> function, where we define the minimum and maximum width of our columns, but remember, our items occupy 2 columns + a gap.</p>
</div>
<h4>The math behind the width of the columns</h4>
<div>
<p>Let&#8217;s start by explaining the first argument of the <em>minmax()</em>, which defines the minimum width.</p>
</div>
<div>
<p>Do you remember we defined the min-width of the elements as a variable? Let&#8217;s use the defined values as examples for our grid.</p>
</div>
<div>Since the minimum width of our items is 200px, and each item is occupying 2 columns in the grid, it means that the minimum widht of the grid column is 90px, because every item will occupy 2 columns + 1 gap: 90px + 20px + 90px = 200px.</div>
<div>Which explains this calculation, for the minimum width of the grid column:</div>
<div>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">calc((var(--min-width) - var(--grid-gap))/2)</div></td></tr></tbody></table></div>
</div>
<div>
<p>But, what if the user is using a super narrow phone? Well, in that case, we want the minimum width of the item to be 100% to prevent horizontal scrolling. Since the item is occupying 2 columns, we get: X% + 20px + X% = 100%, which explains the following calculation:</p>
</div>
<div>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">calc((100% - var(--grid-gap)) / 2)&lt;br /&gt;</div></td></tr></tbody></table></div>
</div>
<div>
<p>Now, we put those two calculations as arguments inside the function <em>min()</em>, which will automatically select the smallest of the two, and that&#8217;s the first argument of our <em>minmax()</em>.</p>
</div>
<div>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">min(<br />
&nbsp; calc((var(--min-width) - var(--grid-gap))/2),<br />
&nbsp; calc((100% - var(--grid-gap)) / 2)<br />
)</div></td></tr></tbody></table></div>
</div>
<div>
<p>The second argument of our <em>minmax()</em> is the maximum widht, which we&#8217;ve defined as 1fr, which represents a “fraction” of the available space in the grid container. </p>
</div>
<h2>A solution ahead of its time</h2>
<div>
<p>Now, it&#8217;s time to use container queries to determine the number of columns. Let&#8217;s start with 2 column layouts.</p>
</div>
<div>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">/* 2 Column Layouts */<br />
@container grid-wrapper (min-width: calc(var(--min-width)*2 + var(--grid-gap))) and (max-width: calc(var(--min-width)*3 + var(--grid-gap)*2)) {<br />
&nbsp; /* Dealing with 1 orphan item */<br />
&nbsp; .item:last-child:nth-child(2n + 1){<br />
&nbsp; &nbsp; grid-column-end: 4;<br />
&nbsp; }<br />
}</div></td></tr></tbody></table></div>
</div>
<div>
<p>In this container query, we are targetting a <em>min-width</em> that just allows for 2 items to display side by side, and a <em>max-width</em> just before 3 items are displayed in the same row.</p>
</div>
<div>
<p>Unfortunately, CSS variables don&#8217;t work in media queries or container queries, so the code you just saw above won&#8217;t work, unfortunately. For now, I have to manually edit this to give fixed values that match our variables <em>var(&#8211;min-width)</em> and <em>var(&#8211;grid-gap)</em>.</p>
</div>
<div>
<p>Having said that. I&#8217;m writing for example <em>200px*2</em> instead of <em>400px</em>, so it&#8217;s quick to replace.</p>
</div>
<div>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">/* 2 Column Layouts */<br />
@container grid-wrapper (min-width: calc(200px*2 + 20px)) and (max-width: calc(200px*3 + 20px*2)) {<br />
&nbsp; /* Dealing with 1 orphan item */<br />
&nbsp; .item:last-child:nth-child(2n + 1){<br />
&nbsp; &nbsp; grid-column-end: 4;<br />
&nbsp; }<br />
}</div></td></tr></tbody></table></div>
</div>
<div>Then, I repeated the same process, using container queries for 3, 4, 5 and 6 columns.</div>
<h3>Final details</h3>
<div>You may have noticed the following unexplained line in our wrapper CSS code:</div>
<div>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">/* Optional */<br />
max-width:calc(var(--min-width)*6 + var(--grid-gap)*5);</div></td></tr></tbody></table></div>
</div>
<div>We are giving our wrapper a max-width, big enough to show 6 items per row, but in this particular case we don&#8217;t want it any bigger, because we only did container queries up to 6 column layouts.</div>
<div>In the final code, you may notice the use of outlines, which we&#8217;ve used only to see the wrapper and items in the screen without affecting the width/height of the elements.</div>
<h3>A future ready solution</h3>
<div>In the future, we may be surprised by new CSS Grid features, for example something like.</div>
<div>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap;">last-row:center;</div></td></tr></tbody></table></div>
</div>
<div>Or maybe, media and container queries will start to work with CSS variables.</div>
<div>Either way, this code is ready to be addapted for these changes without having to change much.</div>
<h2>The final solution to center elements on the last row in CSS Grid</h2>
<div>This is the same CodePen you saw at the beginning of this article.</div>
<div>
<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="css" data-slug-hash="abgKYXv" data-pen-title="Centering last row with CSS Grid" data-user="koalawidgets" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/koalawidgets/pen/abgKYXv"><br />
  Centering last row with CSS Grid</a> by Koala Widgets (<a href="https://codepen.io/koalawidgets">@koalawidgets</a>)<br />
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<p><script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
</div>
<div>
<p>        <img decoding="async" src="/wp-content/uploads/2024/09/pablo-blue-bg.jpg" alt=""></p>
<h3>Pablo A Santamaria</h3>
<p>Written by</p>
<div>
<p>Entrepreneur &#038; developer with a passion for CSS &amp; SaaS. CoFounder of Koala Widgets.</p>
<p><a class="el-link uk-icon-button" href="https://x.com/pabo_" target="_blank" rel="noopener noreferrer"><span uk-icon="icon: x;" class="uk-icon"></span></a></p>
</div>
</div>
<p><span id="more-2142"></span><br />
<!-- {"type":"layout","children":[{"type":"section","props":{"image_position":"center-center","padding_remove_top":false,"style":"default","title_breakpoint":"xl","title_position":"top-left","title_rotation":"left","vertical_align":"","width":"small"},"children":[{"type":"row","props":{"layout":"2-3,1-3","margin":"default","row_gap":"large"},"children":[{"type":"column","props":{"image_position":"center-center","position_sticky_breakpoint":"m","width_medium":"2-3"},"children":[{"type":"headline","props":{"block_align":"center","text_align":"center","title_element":"h1"},"source":{"query":{"name":"posts.singlePost"},"props":{"content":{"filters":{"search":""},"name":"title"}}}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>If you are looking for a quick answer to center elements in the last row of CSS Grid, use the codepen below.<\/p>\n

<p>Getting here wasn't a straight forward process. Read below if you want to learn in depth how this code works, how to expand this solution and how I got here.<\/p>","margin":"default","text_color":"emphasis","text_style":"large"}},{"type":"html","props":{"content":"

<p class=\"codepen\" data-height=\"572\" data-theme-id=\"dark\" data-slug-hash=\"abgKYXv\" data-pen-title=\"Untitled\" data-user=\"koalawidgets\" style=\"height: 472px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;\">\n  <span>See the Pen <a href=\"https:\/\/codepen.io\/koalawidgets\/pen\/abgKYXv\">\n  Untitled<\/a> by Koala Widgets (<a href=\"https:\/\/codepen.io\/koalawidgets\">@koalawidgets<\/a>)\n  on <a href=\"https:\/\/codepen.io\">CodePen<\/a>.<\/span>\n<\/p>\n<script async src=\"https:\/\/cpwebassets.codepen.io\/assets\/embed\/ei.js\"><\/script>"}},{"type":"headline","props":{"content":"Defining the desired layout","margin_remove_top":false,"title_element":"h2"},"name":"h2"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>For a while, I've been searching for a flexible layout that meets these criteria:<\/p>","margin":"default"}},{"type":"list","props":{"column_breakpoint":"m","image_align":"left","image_svg_color":"emphasis","image_vertical_align":true,"list_element":"ul","list_horizontal_separator":", ","list_marker":"bullet","list_type":"vertical","show_image":true,"show_link":true},"children":[{"type":"list_item","props":{"content":"The elements should have a flexible width"}},{"type":"list_item","props":{"content":"The last row should be centered"}},{"type":"list_item","props":{"content":"It should be easy to edit, so it's a copy\/paste process to use in other projects"}},{"type":"list_item","props":{"content":"All the elements should have the same width"}},{"type":"list_item","props":{"content":"All the elements in the same row should have the same height"}},{"type":"list_item","props":{"content":"The number of columns should change automatically, according to the screen width"}},{"type":"list_item","props":{"content":"The solution should work for any number of elements"}},{"type":"list_item","props":{"content":"There should be a gap between the elements"}},{"type":"list_item","props":{"content":"The solution should be achievable with CSS. Meaning, no Javascript."}},{"type":"list_item","props":{"content":"The elements should use the full width of the wrapper"}}]},{"type":"image","props":{"image":"wp-content\/uploads\/2024\/08\/Screen-Shot-2024-08-28-at-12.48.20-pm.png","image_alt":"Desired layout after centering elements on the last row in CSS Grid","image_svg_color":"emphasis","margin":"default"}},{"type":"headline","props":{"content":"The right time to find a solution to center the last row elements in a grid using CSS","margin_remove_top":true,"title_element":"h2"},"name":"h2"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>In the past, I settled for solutions that don't meet all my criteria, however, with the current state of CSS, I thought it must be possible.<\/p>","margin":"default"}},{"type":"headline","props":{"content":"There is Hope","title_element":"h3"},"name":"h3"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>My CSS mentor <a href=\"https:\/\/x.com\/KevinJPowell\" target=\"_blank\" rel=\"noopener\">Kevin Powell<\/a> recently did a live YouTube <a href=\"https:\/\/www.youtube.com\/watch?v=S2XstSrGJOw\" target=\"_blank\" rel=\"noopener\">responsive layouts workshop<\/a>. If there is someone who knows how to achieve this, that is Kev.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>At some point in the video 1:50:55, Kev had a grid on his screen and somebody asked to center the last row elements.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>His response was both dissapointing and hopeful; \"<em>That's something I wouldn't be able to do with grid... I wouldn't use grid, in that case I would use flexbox<\/em>\".<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>This got me started on a quest to find a solution using flexbox.<\/p>","margin":"default"}},{"type":"headline","props":{"content":"The YOOTheme approach that works","title_element":"h3"},"name":"h3"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Since we are using the page builder YOOTheme Pro in this website, we can easily use the editor to add a Grid, and configure the settings to achieve the desired result.<\/p>","margin":"default"}},{"type":"grid","props":{"content_column_breakpoint":"m","filter_align":"left","filter_all":true,"filter_grid_breakpoint":"m","filter_grid_width":"auto","filter_position":"top","filter_style":"tab","grid_column_align":true,"grid_default":"1","grid_large":"4","grid_medium":"3","grid_row_align":false,"grid_small":"2","icon_width":80,"image_align":"top","image_grid_breakpoint":"m","image_grid_width":"1-2","image_svg_color":"emphasis","item_animation":true,"link_style":"default","link_text":"Read more","margin":"default","meta_align":"below-title","meta_element":"div","meta_style":"text-meta","panel_padding":"small","panel_style":"card-primary","show_content":true,"show_image":true,"show_link":true,"show_meta":true,"show_title":true,"text_align":"center","title_align":"top","title_element":"h3","title_grid_breakpoint":"m","title_grid_width":"1-2","title_hover_style":"reset"},"children":[{"type":"grid_item","props":{"content":"

<p>Lorem ipsum dolor sit amet<\/p>","title":"Title"}},{"type":"grid_item","props":{"content":"

<p>Lorem ipsum dolor sit amet.<\/p>\n

<p>Longer.<\/p>","title":"Title"}},{"type":"grid_item","props":{"content":"

<p>Lorem ipsum dolor sit amet<\/p>","title":"Title"}},{"type":"grid_item","props":{"content":"

<p>Lorem ipsum dolor sit amet<\/p>","title":"Title"}},{"type":"grid_item","props":{"content":"

<p>Lorem ipsum dolor sit amet<\/p>","title":"Title"}},{"type":"grid_item","props":{"content":"

<p>Lorem ipsum dolor sit amet<\/p>","title":"Title"}},{"type":"grid_item","props":{"content":"

<p>Lorem ipsum dolor sit amet<\/p>","title":"Title"}}]},{"type":"image","props":{"image":"wp-content\/uploads\/2024\/08\/Screen-Shot-2024-08-28-at-1.59.19-pm.png","image_svg_color":"emphasis","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>At first sight, this grid meets all the criteria, so let's start by looking at the source code. You are welcome to inspect it in your browser as well.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>This is the HTML when there are 4 columns showing.<\/p>","margin":"default"}},{"type":"image","props":{"image":"wp-content\/uploads\/2024\/08\/Screen-Shot-2024-08-28-at-2.09.23-pm.png","image_alt":"Code used by Yootheme Pro to center elements on the last row in CSS Grid","image_svg_color":"emphasis","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>The main code to achieve this is a simple flexbox that justifies the content in the centre.<\/p>","margin":"default"}},{"type":"image","props":{"image":"wp-content\/uploads\/2024\/08\/Screen-Shot-2024-08-28-at-2.14.20-pm.png","image_alt":"Code used by Yootheme Pro to center elements on the last row using flexbox","image_svg_color":"emphasis","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Flexbox is also allowing all the items in the same row to have the same height.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Then, they use percentages to control the column width based on the screen size, so there is a fair bit of code behind this, which is totally fine.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Also, for the gap between the elements, they are using a left padding on the elements, and a negative padding on the wrapper, to even out the first element of each row.<\/p>","margin":"default"}},{"type":"image","props":{"image":"wp-content\/uploads\/2024\/08\/Screen-Shot-2024-08-28-at-2.11.04-pm.png","image_alt":"Media queries example","image_svg_color":"emphasis","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>In conclusion, this is a good approach and I would just need to define the number of columns according to the screen width as I did in the settings of YOOTheme Pro.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>However, it is not as portable as I would like, because I would need to pre-define break points for the media queries, which may be different in other projects.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Also, telling the number of columns in various screen sizes, is not as elegant as simply defining the minimun size of the items.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>So, here's my quest to find such solution:<\/p>","margin":"default"}},{"type":"headline","props":{"content":"Looking for a simpler flexbox solution to center elements in the last row","title_element":"h3"},"name":"h3"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Using flexbox by default almost worked perfectly, except for the last column, that stretched the item to take the full width of the row.<\/p>","margin":"default"}},{"type":"image","props":{"image":"wp-content\/uploads\/2024\/08\/Screen-Shot-2024-08-27-at-7.58.19-pm.png","image_alt":"Attempt 1 to center elements in the last row using flexbox","image_svg_color":"emphasis","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>The solution for this is simple, just use <code>flex-grow:0;<\/code><\/p>","margin":"default"}},{"type":"image","props":{"image":"wp-content\/uploads\/2024\/08\/Screen-Shot-2024-08-27-at-7.57.33-pm.png","image_alt":"Attempt 2 to center elements in the last row using flexbox","image_svg_color":"emphasis","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"While this centers the items neatly, the items in the first columns are not using 100% of the wrapper width, which doesn't meet the criteria. ","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"I'm out of ideas using flexbox, all roads take me to the Yootheme Pro approach, so I started exploring the Grid option.","margin":"default"}},{"type":"headline","props":{"content":"Exploring Grid","margin_remove_top":true,"title_element":"h2"},"name":"h2"},{"type":"text","props":{"column_breakpoint":"m","content":"Grid by default meets all my criteria, except centering the elements in the last row, so if I can solve that somehow, the job is done.","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Luckily, I came across the article <a href=\"https:\/\/css-irl.info\/controlling-leftover-grid-items\/\" target=\"_blank\" rel=\"noopener\">Controlling Leftover Grid Items with Pseudo-selectors<\/a> where the author finds a solution to center elements in the last row of grid.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>This is a very clever solution, just assign 2 cells to every item, then move the item in the last row to the desired position.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"Their article uses a 3 column layout and explains how to achieve the result when there are 1 or 2 items in the last row.","margin":"default"}},{"type":"headline","props":{"content":"Centering the elements","title_element":"h3"},"name":"h3"},{"type":"headline","props":{"content":"2 Column Layouts","title_element":"h4"},"name":"h4"},{"type":"image","props":{"image":"wp-content\/uploads\/2024\/09\/Screen-Shot-2024-09-02-at-9.16.30-pm.png","image_alt":"2 column CSS grid with item in the last row centered","image_svg_color":"emphasis","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>In the image above, the last item is targetted in CSS, by selecting the last element, that is also an odd number. Keep in mind, that another way to say \"odd numbers\" is by selecting the multiples of 2, then adding a unit to it: 2n + 1.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Then, we just tell this item to end in line #4. As you can see in the image, lines are placed at the beginning at the end and at the gaps.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"<code>.item:last-child:nth-child(2n + 1){\n    grid-column-end:4;\n}<\/code>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"That's all we need to do when there are 2 columns, but when there are 3 columns the solution is a bit different.","margin":"default"}},{"type":"headline","props":{"content":"3 Column Layouts","title_element":"h4"},"name":"h4"},{"type":"image","props":{"image":"wp-content\/uploads\/2024\/09\/Screen-Shot-2024-09-02-at-9.26.00-pm.png","image_alt":"3 column CSS grid with item in the last row centered","image_svg_color":"emphasis","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"When there is only 1 item in the last row, we need to select the last element that also follows the sequence 4, 7, 10, 13... In other words multiples of 3 but adding a unit to it: 3n+1. And tell it to finish in line #5.","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"<code>.item:last-child:nth-child(3n + 1){\n    grid-column-end: 5;\n}<\/code>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>When there are 2 item in the last row, we need to select the second last element that also follows the sequence 4, 7, 10, 13... And tell it to finish in line #4.<\/p>","margin":"default"}},{"type":"image","props":{"image":"wp-content\/uploads\/2024\/09\/Screen-Shot-2024-09-02-at-9.25.32-pm.png","image_alt":"3 column CSS grid with 2 items in the last row centered","image_svg_color":"emphasis","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p><code>.item:nth-last-child(2):nth-child(3n + 1){\n    grid-column-end: 4;\n}<\/code><\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Then, the actual last item will be automatically placed in the right spot as it remains next to the second last.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"Now that we've done it with 2 and 3 columns, you get the idea. In my final solution I also did 4, 5 and 6 columns, but you can keep going if you need to.","margin":"default"}},{"type":"headline","props":{"content":"Determining the number of columns","title_element":"h3"},"name":"h3"},{"type":"text","props":{"column_breakpoint":"m","content":"You may be wondering, what's the point of adding all the code for various numbers of columns, if we still don't know the number of columns to use.","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"Well, to determine the number of columns, we need to define the width of the items, and remember, we want to achieve a layout that allows for elements with variable width.","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>So let's start by defining a couple of variables:<\/p>\n

<ul>\n

<li>Item width<\/li>\n

<li>Grid gap<\/li>\n<\/ul>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p><code>:root{\n  --min-width:200px;\n  --grid-gap:20px;\n}<\/code><\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"In order to make this code portable between projects, I created these values as variables, so they can be easily edited in one place.","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"Now, let's define the item, so it occupies 2 columns in the grid.","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"<code>.item{\n  grid-column: span 2;\n}<\/code>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"Now, let's define the grid.","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"<code>.wrapper{\n  display: grid;\n  grid-gap: var(--grid-gap);\n  \n  \/* Defining the columns *\/\n  grid-template-columns: repeat(\n    auto-fit,\n    minmax(\n      min(\n        calc((var(--min-width) - var(--grid-gap))\/2),\n    \tcalc((100% - var(--grid-gap)) \/ 2)\n      ),\n      1fr\n    )\n  );\n  \n  \/* Setting up the container for the queries *\/\n  container: grid-wrapper \/ inline-size;\n  \n  \/* Optional *\/\n  max-width:calc(var(--min-width)*6 + var(--grid-gap)*5);\n}<\/code>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>To understand what we are doing here, I'm assuming that you understand how display:grid; works, so the display and grid-gap attributes should be self-explanatory. If not, you can check these <a href=\"https:\/\/www.youtube.com\/playlist?list=PL4-IK0AVhVjPv5tfS82UF_iQgFp4Bl998\" target=\"_blank\" rel=\"noopener\">great videos on Grid<\/a>.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>The tricky line to understand is grid-template-columns. We are using <em>repeat<\/em> to define the columns. <em>Repeat<\/em> has 2 arguments:<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"<code>grid-template-columns: repeat(\n    auto-fit,\n    minmax(...)\n);<\/code>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>The first argument defines the number of times that the track list should be repeated. We've used <em>auto-fit<\/em> in this case which automatically adjust the number of repetitions to the largest possible number that doesn't cause the grid to overflow.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>The second argument is using a <em>minmax()<\/em> function, where we define the minimum and maximum width of our columns, but remember, our items occupy 2 columns + a gap.<\/p>","margin":"default"}},{"type":"headline","props":{"content":"The math behind the width of the columns","title_element":"h4"},"name":"h4"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Let's start by explaining the first argument of the <em>minmax()<\/em>, which defines the minimum width.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Do you remember we defined the min-width of the elements as a variable? Let's use the defined values as examples for our grid.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"Since the minimum width of our items is 200px, and each item is occupying 2 columns in the grid, it means that the minimum widht of the grid column is 90px, because every item will occupy 2 columns + 1 gap: 90px + 20px + 90px = 200px.","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"Which explains this calculation, for the minimum width of the grid column:","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"<code>calc((var(--min-width) - var(--grid-gap))\/2)<\/code>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>But, what if the user is using a super narrow phone? Well, in that case, we want the minimum width of the item to be 100% to prevent horizontal scrolling. Since the item is occupying 2 columns, we get: X% + 20px + X% = 100%, which explains the following calculation:<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"<code>calc((100% - var(--grid-gap)) \/ 2)<br \/><\/code>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Now, we put those two calculations as arguments inside the function <em>min()<\/em>, which will automatically select the smallest of the two, and that's the first argument of our <em>minmax()<\/em>.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"<code>min(\n  calc((var(--min-width) - var(--grid-gap))\/2),\n  calc((100% - var(--grid-gap)) \/ 2)\n)<\/code>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>The second argument of our <em>minmax()<\/em> is the maximum widht, which we've defined as 1fr, which represents a \u201cfraction\u201d of the available space in the grid container.\u00a0<\/p>","margin":"default"}},{"type":"headline","props":{"content":"A solution ahead of its time","margin_remove_top":true,"title_element":"h2"},"name":"h2"},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Now, it's time to use container queries to determine the number of columns. Let's start with 2 column layouts.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"<code>\/* 2 Column Layouts *\/\n@container grid-wrapper (min-width: calc(var(--min-width)*2 + var(--grid-gap))) and (max-width: calc(var(--min-width)*3 + var(--grid-gap)*2)) {\n  \/* Dealing with 1 orphan item *\/\n  .item:last-child:nth-child(2n + 1){\n    grid-column-end: 4;\n  }\n}<\/code>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>In this container query, we are targetting a <em>min-width<\/em> that just allows for 2 items to display side by side, and a <em>max-width<\/em> just before 3 items are displayed in the same row.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Unfortunately, CSS variables don't work in media queries or container queries, so the code you just saw above won't work, unfortunately. For now, I have to manually edit this to give fixed values that match our variables <em>var(--min-width)<\/em> and <em>var(--grid-gap)<\/em>.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Having said that. I'm writing for example <em>200px*2<\/em> instead of <em>400px<\/em>, so it's quick to replace.<\/p>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"<code>\/* 2 Column Layouts *\/\n@container grid-wrapper (min-width: calc(200px*2 + 20px)) and (max-width: calc(200px*3 + 20px*2)) {\n  \/* Dealing with 1 orphan item *\/\n  .item:last-child:nth-child(2n + 1){\n    grid-column-end: 4;\n  }\n}<\/code>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"Then, I repeated the same process, using container queries for 3, 4, 5 and 6 columns.","margin":"default"}},{"type":"headline","props":{"content":"Final details","title_element":"h3"},"name":"h3"},{"type":"text","props":{"column_breakpoint":"m","content":"You may have noticed the following unexplained line in our wrapper CSS code:","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"<code>\/* Optional *\/\nmax-width:calc(var(--min-width)*6 + var(--grid-gap)*5);<\/code>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"We are giving our wrapper a max-width, big enough to show 6 items per row, but in this particular case we don't want it any bigger, because we only did container queries up to 6 column layouts.","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"In the final code, you may notice the use of outlines, which we've used only to see the wrapper and items in the screen without affecting the width\/height of the elements.","margin":"default"}},{"type":"headline","props":{"content":"A future ready solution","title_element":"h3"},"name":"h3"},{"type":"text","props":{"column_breakpoint":"m","content":"In the future, we may be surprised by new CSS Grid features, for example something like.","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"<code>last-row:center;<\/code>","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"Or maybe, media and container queries will start to work with CSS variables.","margin":"default"}},{"type":"text","props":{"column_breakpoint":"m","content":"Either way, this code is ready to be addapted for these changes without having to change much.","margin":"default"}},{"type":"headline","props":{"content":"The final solution to center elements on the last row in CSS Grid","margin_remove_top":true,"title_element":"h2"},"name":"h2"},{"type":"text","props":{"column_breakpoint":"m","content":"This is the same CodePen you saw at the beginning of this article.","margin":"default"}},{"type":"html","props":{"content":"

<p class=\"codepen\" data-height=\"300\" data-theme-id=\"dark\" data-default-tab=\"css\" data-slug-hash=\"abgKYXv\" data-pen-title=\"Centering last row with CSS Grid\" data-user=\"koalawidgets\" style=\"height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;\">\n  <span>See the Pen <a href=\"https:\/\/codepen.io\/koalawidgets\/pen\/abgKYXv\">\n  Centering last row with CSS Grid<\/a> by Koala Widgets (<a href=\"https:\/\/codepen.io\/koalawidgets\">@koalawidgets<\/a>)\n  on <a href=\"https:\/\/codepen.io\">CodePen<\/a>.<\/span>\n<\/p>\n<script async src=\"https:\/\/cpwebassets.codepen.io\/assets\/embed\/ei.js\"><\/script>"}}]},{"type":"column","props":{"image_position":"center-center","position_sticky_breakpoint":"m","width_medium":"1-3"},"children":[{"type":"panel","props":{"content":"

<p>Entrepreneur & developer with a passion for CSS &amp; SaaS. CoFounder of Koala Widgets.<\/p>\n

<p><a class=\"el-link uk-icon-button\" href=\"https:\/\/x.com\/pabo_\" target=\"_blank\" rel=\"noopener noreferrer\"><span uk-icon=\"icon: x;\" class=\"uk-icon\"><\/span><\/a><\/p>","content_column_breakpoint":"m","css":".el-image{max-width:80px;}","icon_width":80,"image":"wp-content\/uploads\/2024\/09\/pablo-blue-bg.jpg","image_align":"top","image_border":"circle","image_box_decoration":"mask","image_grid_breakpoint":"m","image_grid_width":"1-2","image_svg_color":"emphasis","link_style":"default","link_target":false,"link_text":"Follow on X","margin":"default","margin_remove_bottom":true,"meta":"Written by","meta_align":"above-title","meta_element":"div","meta_style":"text-meta","panel_padding":"small","panel_style":"card-secondary","text_align":"center","title":"Pablo A Santamaria","title_align":"top","title_element":"h3","title_grid_breakpoint":"m","title_grid_width":"1-2","title_hover_style":"reset","title_margin":"remove","title_style":"h4"}}]}]}],"name":"Post"}],"version":"4.4.8"} --></p>
<p>The post <a href="https://staging.koalawidgets.com/how-to-center-elements-on-the-last-row-in-css-grid/">How to center elements on the last row in CSS Grid?</a> appeared first on <a href="https://staging.koalawidgets.com">Koala Widgets</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Web Design, a Bad Business Model</title>
		<link>https://staging.koalawidgets.com/web-design-bad-business-model/</link>
		
		<dc:creator><![CDATA[8web]]></dc:creator>
		<pubDate>Tue, 13 Aug 2024 12:10:40 +0000</pubDate>
				<category><![CDATA[Web Designers]]></category>
		<guid isPermaLink="false">https://koalawidgets.com/?p=2117</guid>

					<description><![CDATA[<p>After running a small Web Design company for over a decade, I can tell you, building websites for clients is not the best business model. Defining the Rat Race in Web Design The rat race is a term used to describe the cycle of work and consumption, typical of living paycheck to paycheck. Essentially, it&#8217;s [&#8230;]</p>
<p>The post <a href="https://staging.koalawidgets.com/web-design-bad-business-model/">Web Design, a Bad Business Model</a> appeared first on <a href="https://staging.koalawidgets.com">Koala Widgets</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><img decoding="async" src="/wp-content/uploads/2024/08/web-designer-rat-race.jpg" alt=""></p>
<div>
<p>After running a small Web Design company for over a decade, I can tell you, building websites for clients is not the best business model.</p>
</div>
<h2>Defining the Rat Race in Web Design</h2>
<div>
<div>
<div><span>The rat race is a term used to describe the cycle of work and consumption, typical of living paycheck to paycheck. Essentially, it&#8217;s the feeling of being trapped in a never-ending pursuit of more without truly enjoying the journey.</span></div>
<p></p>
<div><span>However, from a web design business perspective, it has a different meaning; finding new clients to create websites for over and over again. It is a repetitive endless cycle; find a client, build a website, then find another client to build another website and so on. In general terms, it&#8217;s The Client Acquisition Rat Race.</span></div>
<p></p>
<div><span>If you are a solopreneur, the problem is even worst, when you have time to find new clients it&#8217;s because you don&#8217;t have enough work, and viceversa. Finding the right balance is hard.</span></div>
<p></p>
<div><span>Websites are more often than not a once-off project. Companies don&#8217;t change thier websites for years. If you do a good job, a website can last over a decade (we&#8217;ve built a few of those). Some clients return to the same web designer for a revamp, but most of the time, they want to try a different designer every time.</span></div>
</div>
</div>
<h2>Escaping the Client Acquisition Rat Race</h2>
<div>
<p>The answer is simple, <strong>recurring services</strong>.</p>
<p>Successful web designers typically don’t just offer web design, often they become marketing agencies/consultants that offer all sorts of marketing services:</p>
<ul>
<li>Marketing strategy</li>
<li>Social media</li>
<li>Paid advertising</li>
<li>SEO</li>
<li>etc.</li>
</ul>
<p>That way, they don&#8217;t have to find new clients every time, client acquisition is less crucial if you have recurring services.</p>
<p>Building websites for clients becomes just part of what they do.</p>
<p>Marketing services are naturally a better business model, because these are recurring services.</p>
<p>However, marketing services is not a solution for everybody, what if you don&#8217;t have the skills or the passion for it?</p>
</div>
<h3>Non-marketing Recurring Services</h3>
<div>
<p>The truth is, we are not great marketers. Being a small team of 2, our skills are more on the technical side of the spectrum.</p>
<p>Early in the journey we introduced recurring services:</p>
<ul>
<li>Email</li>
<li>Website security</li>
<li>Hosting</li>
<li>Domains</li>
</ul>
<p>These services are great, but they come with a problem too.</p>
<p>Email, Hosting &amp; Domains are comoditised services and it’s very hard to market by differenciation from the competition. Having said that, these services can become very easy to provide and while the margins are small, they add up to help your business become profitable.</p>
<p>Website security also produces recurring predictable income, which is great, we are working to grow this arm of the business.</p>
</div>
<h3>The Koala Widgets Way</h3>
<div>
<p>We recently launched this website to create and promote widgets for websites.</p>
<p>We are working on various Widgets, like this <a href="https://staging.koalawidgets.com/widget/website-cost-calculator/">Website Cost Calculator</a> or <a href="https://staging.koalawidgets.com/widget/cepi-calculator/">the <abbr title="Cover Expenses with Passive Income">CEPI</abbr> Calculator</a>, where clients can subscribe to embed them in their websites.</p>
<p>These widgets are the reason why Koala Widgets exists and it’s our current attempt to escape the web designer rat race.</p>
<p>It is still early days for the widgets and we don’t have many sales yet, but the subscription model it’s more promising than building websites for clients.</p>
</div>
<h2>What About You, How Do You Escape the Web Design Rat Race?</h2>
<div>
<p>Hopefully, you can take some ideas from this article and introduce more recurring services to your offer.</p>
</div>
<h3>Affiliate Marketing</h3>
<div>
<p>Finally, I have to mention affiliate marketing as an option.</p>
<p>I was hesitant to mention affiliate marketing because in most cases it doesn&#8217;t generate recurring revenew, so I have to clarify, I&#8217;m referring to recurring affiliate programs.</p>
<p>Some hosting companies like <a href="https://kinsta.com/affiliates/" target="_blank" rel="noopener">Kinsta</a> in the US or <a href="https://8webdesign.au/affiliate-program/" target="_blank" rel="noopener">8 Web Design</a> in Australia offer great recurring affiliate programs.</p>
<p>At Koala Widgets we also offer a recurring affiliate program. We value highly the distribution of our widgets and our Affiliate program is a reflection of that.</p>
</div>
<p><span id="more-2117"></span><br />
<!-- {"type":"layout","children":[{"type":"section","props":{"image_position":"center-center","padding_remove_top":false,"style":"default","title_breakpoint":"xl","title_position":"top-left","title_rotation":"left","vertical_align":"","width":"xsmall"},"children":[{"type":"row","props":{"margin":"default","row_gap":"large"},"children":[{"type":"column","props":{"image_position":"center-center","position_sticky_breakpoint":"m"},"children":[{"type":"headline","props":{"block_align":"center","id":"postid-2117-title","text_align":"center","title_element":"h1"},"source":{"query":{"name":"posts.singlePost"},"props":{"content":{"filters":{"search":""},"name":"title"}}}},{"type":"image","props":{"id":"postid-2117-img","image":"wp-content\/uploads\/2024\/08\/web-designer-rat-race.jpg","image_svg_color":"emphasis","margin":"default","text_align":"center"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>After running a small Web Design company for over a decade, I can tell you, building websites for clients is not the best business model.<\/p>","margin":"default","text_style":"large"}},{"type":"headline","props":{"content":"Defining the Rat Race in Web Design","margin_remove_top":true,"title_element":"h2"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<div>\n

<div><span>The rat race is a term used to describe the cycle of work and consumption, typical of living paycheck to paycheck. Essentially, it's the feeling of being trapped in a never-ending pursuit of more without truly enjoying the journey.<\/span><\/div>\n<br \/>\n

<div><span>However, from a web design business perspective, it has a different meaning; finding new clients to create websites for over and over again. It is a repetitive endless cycle; find a client, build a website, then find another client to build another website and so on. In general terms, it's The Client Acquisition Rat Race.<\/span><\/div>\n<br \/>\n

<div><span>If you are a solopreneur, the problem is even worst, when you have time to find new clients it's because you don't have enough work, and viceversa. Finding the right balance is hard.<\/span><\/div>\n<br \/>\n

<div><span>Websites are more often than not a once-off project. Companies don't change thier websites for years. If you do a good job, a website can last over a decade (we've built a few of those). Some clients return to the same web designer for a revamp, but most of the time, they want to try a different designer every time.<\/span><\/div>\n<\/div>","margin":"default","text_color":"emphasis"}},{"type":"headline","props":{"content":"Escaping the Client Acquisition Rat Race","margin_remove_top":true,"title_element":"h2"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>The answer is simple, <strong>recurring services<\/strong>.<\/p>\n

<p>Successful web designers typically don\u2019t just offer web design, often they become marketing agencies\/consultants that offer all sorts of marketing services:<\/p>\n

<ul>\n

<li>Marketing strategy<\/li>\n

<li>Social media<\/li>\n

<li>Paid advertising<\/li>\n

<li>SEO<\/li>\n

<li>etc.<\/li>\n<\/ul>\n

<p>That way, they don't have to find new clients every time, client acquisition is less crucial if you have recurring services.<\/p>\n

<p>Building websites for clients becomes just part of what they do.<\/p>\n

<p>Marketing services are naturally a better business model, because these are recurring services.<\/p>\n

<p>However, marketing services is not a solution for everybody, what if you don't have the skills or the passion for it?<\/p>","margin":"default","text_color":"emphasis"}},{"type":"headline","props":{"content":"Non-marketing Recurring Services","margin_remove_top":true,"title_element":"h3"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>The truth is, we are not great marketers. Being a small team of 2, our skills are more on the technical side of the spectrum.<\/p>\n

<p>Early in the journey we introduced recurring services:<\/p>\n

<ul>\n

<li>Email<\/li>\n

<li>Website security<\/li>\n

<li>Hosting<\/li>\n

<li>Domains<\/li>\n<\/ul>\n

<p>These services are great, but they come with a problem too.<\/p>\n

<p>Email, Hosting &amp; Domains are comoditised services and it\u2019s very hard to market by differenciation from the competition. Having said that, these services can become very easy to provide and while the margins are small, they add up to help your business become profitable.<\/p>\n

<p>Website security also produces recurring predictable income, which is great, we are working to grow this arm of the business.<\/p>","margin":"default","text_color":"emphasis"}},{"type":"headline","props":{"content":"The Koala Widgets Way","margin_remove_top":true,"title_element":"h3"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>We recently launched this website to create and promote widgets for websites.<\/p>\n

<p>We are working on various Widgets, like this <a href=\"https:\/\/staging.koalawidgets.com\/widget\/website-cost-calculator\/\">Website Cost Calculator<\/a> or <a href=\"https:\/\/staging.koalawidgets.com\/widget\/cepi-calculator\/\">the <abbr title=\"Cover Expenses with Passive Income\">CEPI<\/abbr> Calculator<\/a>, where clients can subscribe to embed them in their websites.<\/p>\n

<p>These widgets are the reason why Koala Widgets exists and it\u2019s our current attempt to escape the web designer rat race.<\/p>\n

<p>It is still early days for the widgets and we don\u2019t have many sales yet, but the subscription model it\u2019s more promising than building websites for clients.<\/p>","margin":"default","text_color":"emphasis"}},{"type":"headline","props":{"content":"What About You, How Do You Escape the Web Design Rat Race?","margin_remove_top":true,"title_element":"h2"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Hopefully, you can take some ideas from this article and introduce more recurring services to your offer.<\/p>","margin":"default","text_color":"emphasis"}},{"type":"headline","props":{"content":"Affiliate Marketing","margin_remove_top":true,"title_element":"h3"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>Finally, I have to mention affiliate marketing as an option.<\/p>\n

<p>I was hesitant to mention affiliate marketing because in most cases it doesn't generate recurring revenew, so I have to clarify, I'm referring to recurring affiliate programs.<\/p>\n

<p>Some hosting companies like <a href=\"https:\/\/kinsta.com\/affiliates\/\" target=\"_blank\" rel=\"noopener\">Kinsta<\/a> in the US or <a href=\"https:\/\/8webdesign.au\/affiliate-program\/\" target=\"_blank\" rel=\"noopener\">8 Web Design<\/a> in Australia offer great recurring affiliate programs.<\/p>\n

<p>At Koala Widgets we also offer a recurring affiliate program. We value highly the distribution of our widgets and our Affiliate program is a reflection of that.<\/p>","margin":"default","text_color":"emphasis"}}]}]}],"name":"Post"},{"type":"section","props":{"image_position":"center-center","status":"disabled","style":"muted","title_breakpoint":"xl","title_position":"top-left","title_rotation":"left","vertical_align":"","width":"xlarge"},"children":[{"type":"row","children":[{"type":"column","props":{"image_position":"center-center","position_sticky_breakpoint":"m","width_medium":"1-1"},"children":[{"type":"headline","props":{"content":"More Stories","title_element":"h2","title_style":"h4"}},{"type":"grid","props":{"content_column_breakpoint":"m","css":"@media (max-width: 959px) {\n\t.el-element > * > :nth-child(2n+0) { display: none; }\n}","filter_align":"left","filter_all":true,"filter_grid_breakpoint":"m","filter_grid_width":"auto","filter_position":"top","filter_style":"tab","grid_default":"1","grid_medium":"3","grid_small":"2","icon_width":80,"image_align":"top","image_grid_breakpoint":"m","image_grid_width":"1-2","image_height":"400","image_link":true,"image_svg_color":"emphasis","image_width":"610","item_animation":true,"link_style":"default","link_text":"","margin":"medium","meta_align":"below-title","meta_color":"muted","meta_element":"div","meta_margin":"small","meta_style":"h6","parallax_easing":"1","show_content":true,"show_image":true,"show_link":true,"show_meta":true,"show_title":true,"title_align":"top","title_element":"h3","title_grid_breakpoint":"m","title_grid_width":"1-2","title_hover_style":"reset","title_link":true,"title_margin":"medium","title_style":"h6"},"children":[{"type":"grid_item","props":{"image":"wp-content\/themes\/yootheme\/packages\/theme\/assets\/images\/element-image-placeholder.png","item_element":"article","link":"#","meta":"<time datetime=\"2019-10-02T09:55:29+00:00\">02 October, 2019<\/time>","title":"Alpaca Wool \u2013 Why Is It Good for Clothes?"}},{"type":"grid_item","props":{"image":"wp-content\/themes\/yootheme\/packages\/theme\/assets\/images\/element-image-placeholder.png","item_element":"article","link":"#","meta":"<time datetime=\"2019-08-26T09:55:29+00:00\">26 August, 2019<\/time>","title":"Comfy Must-haves for the Summer Season"}},{"type":"grid_item","props":{"image":"wp-content\/themes\/yootheme\/packages\/theme\/assets\/images\/element-image-placeholder.png","item_element":"article","link":"#","meta":"<time datetime=\"2019-08-02T09:55:29+00:00\">02 August, 2019<\/time>","title":"Enjoying a Beach Holiday with a Baby"}}]}]}]}],"name":"Latest Posts"}],"version":"4.4.10"} --></p>
<p>The post <a href="https://staging.koalawidgets.com/web-design-bad-business-model/">Web Design, a Bad Business Model</a> appeared first on <a href="https://staging.koalawidgets.com">Koala Widgets</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Free Web Design Proposal Template for Freelance Designers</title>
		<link>https://staging.koalawidgets.com/free-web-design-proposal-template-freelance-designers/</link>
		
		<dc:creator><![CDATA[8web]]></dc:creator>
		<pubDate>Tue, 13 Aug 2024 10:49:00 +0000</pubDate>
				<category><![CDATA[Web Designers]]></category>
		<guid isPermaLink="false">https://koalawidgets.com/?p=2096</guid>

					<description><![CDATA[<p>Wait, What! The Website Proposal Template is a Presentation, not a Word or PDF document That&#8217;s right, the format of this website proposal template is a Google Presentation, and there is a very good reason to do it that way. When I did the 10K Bootcamp with uGurus, which is a prehistoric version of uacademy, [&#8230;]</p>
<p>The post <a href="https://staging.koalawidgets.com/free-web-design-proposal-template-freelance-designers/">Free Web Design Proposal Template for Freelance Designers</a> appeared first on <a href="https://staging.koalawidgets.com">Koala Widgets</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div>
<div class="g-slides" style="text-align:center;" id="postid-2096-img"><iframe src="https://docs.google.com/presentation/d/e/2PACX-1vRH8_9vElZLnfEPwz7r1pK2fheT6fPdXDSNy7oi_kacCY-REOd5lcEyVJ2NG0V6IpsoMMTpCq-dgNnX/embed?start=false&#038;loop=false&#038;delayms=3000" frameborder="0" width="100%" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe></div>
</div>
<div>Wait, What!</div>
<h2>The Website Proposal Template is a Presentation, not a Word or PDF document</h2>
<div>
<p>That&#8217;s right, the format of this website proposal template is a Google Presentation, and there is a very good reason to do it that way.</p>
</div>
<div>
<p>When I did the 10K Bootcamp with uGurus, which is a prehistoric version of <a href="https://ugurus.com/uacademy-launch-your-digital-agency/" target="_blank" rel="noopener">uacademy</a>, one of the commanments was; You shall not just email proposals.</p>
</div>
<h3>Always Present the Web Design Proposal to the Prospect</h3>
<div>
<p>After I stopped emailing proposals to the clients and started presenting them, my conversion rate increased dramatically.</p>
<p>Also, most web designers who were doing the training with experience a significant conversion rate improvement.</p>
<p>Considering all proposal are now presented instead of sent, it makes sense to use a Presentation format for the Web Design Proposal.</p>
</div>
<h2>Download for Free this Web Design Proposal Template</h2>
<div>
<p>This is the exact same format we&#8217;ve been using since 2018 and it has given us great results. I hope you find it useful and help you land your next client.</p>
<p>Complete the form below and receive our free web design proposal template for freelance designers in your inbox.</p>
</div>
<div>
<noscript class="ninja-forms-noscript-message">
	Notice: JavaScript is required for this content.</noscript>
<div id="nf-form-4-cont" class="nf-form-cont" aria-live="polite" aria-labelledby="nf-form-title-4" aria-describedby="nf-form-errors-4" role="form">

    <div class="nf-loading-spinner"></div>

</div>
        <!-- That data is being printed as a workaround to page builders reordering the order of the scripts loaded-->
        <script>var formDisplay=1;var nfForms=nfForms||[];var form=[];form.id='4';form.settings={"objectType":"Form Setting","editActive":true,"title":"Download Web Design Proposal Template","show_title":0,"allow_public_link":0,"embed_form":"","clear_complete":1,"hide_complete":0,"default_label_pos":"above","wrapper_class":"","element_class":"","form_title_heading_level":"3","key":"","add_submit":0,"currency":"","unique_field_error":"A form with this value has already been submitted.","logged_in":false,"not_logged_in_msg":"","sub_limit_msg":"The form has reached its submission limit.","calculations":[],"formContentData":["name_1723547610016","email_1723547580117","download_1723547626128"],"changeEmailErrorMsg":"Please enter a valid email address!","changeDateErrorMsg":"Please enter a valid date!","confirmFieldErrorMsg":"These fields must match!","fieldNumberNumMinError":"Number Min Error","fieldNumberNumMaxError":"Number Max Error","fieldNumberIncrementBy":"Please increment by ","formErrorsCorrectErrors":"Please correct errors before submitting this form.","validateRequiredField":"This is a required field.","honeypotHoneypotError":"Honeypot Error","fieldsMarkedRequired":"Fields marked with an <span class=\"ninja-forms-req-symbol\">*<\/span> are required","objectDomain":"display","drawerDisabled":false,"ninjaForms":"Ninja Forms","fieldTextareaRTEInsertLink":"Insert Link","fieldTextareaRTEInsertMedia":"Insert Media","fieldTextareaRTESelectAFile":"Select a file","formHoneypot":"If you are a human seeing this field, please leave it empty.","fileUploadOldCodeFileUploadInProgress":"File Upload in Progress.","fileUploadOldCodeFileUpload":"FILE UPLOAD","currencySymbol":"&#36;","thousands_sep":",","decimal_point":".","siteLocale":"en_AU","dateFormat":"m\/d\/Y","startOfWeek":"1","of":"of","previousMonth":"Previous Month","nextMonth":"Next Month","months":["January","February","March","April","May","June","July","August","September","October","November","December"],"monthsShort":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"weekdays":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"weekdaysShort":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"weekdaysMin":["Su","Mo","Tu","We","Th","Fr","Sa"],"recaptchaConsentMissing":"reCaptcha validation couldn&#039;t load.","recaptchaMissingCookie":"reCaptcha v3 validation couldn&#039;t load the cookie needed to submit the form.","recaptchaConsentEvent":"Accept reCaptcha cookies before sending the form.","currency_symbol":"","beforeForm":"","beforeFields":"","afterFields":"","afterForm":""};form.fields=[{"objectType":"Field","objectDomain":"fields","editActive":false,"order":1,"idAttribute":"id","type":"firstname","label":"Name","key":"name_1723547610016","label_pos":"above","required":1,"default":"","placeholder":"","container_class":"","element_class":"uk-input","admin_label":"","help_text":"","custom_name_attribute":"fname","personally_identifiable":1,"value":"","drawerDisabled":false,"id":26,"beforeField":"","afterField":"","parentType":"firstname","element_templates":["firstname","input"],"old_classname":"","wrap_template":"wrap"},{"objectType":"Field","objectDomain":"fields","editActive":false,"order":2,"idAttribute":"id","type":"email","label":"Email","key":"email_1723547580117","label_pos":"above","required":1,"default":"","placeholder":"","container_class":"","element_class":"uk-input","admin_label":"","help_text":"","custom_name_attribute":"email","personally_identifiable":1,"value":"","drawerDisabled":false,"id":27,"beforeField":"","afterField":"","parentType":"email","element_templates":["email","input"],"old_classname":"","wrap_template":"wrap"},{"objectType":"Field","objectDomain":"fields","editActive":false,"order":3,"idAttribute":"id","type":"submit","label":"Download","processing_label":"Processing","container_class":"","element_class":"uk-button uk-button-primary","key":"download_1723547626128","admin_label":"","drawerDisabled":false,"id":28,"beforeField":"","afterField":"","value":"","label_pos":"above","parentType":"textbox","element_templates":["submit","button","input"],"old_classname":"","wrap_template":"wrap-no-label"}];nfForms.push(form);</script>
        </div>
<p><span id="more-2096"></span><br />
<!-- {"type":"layout","children":[{"type":"section","props":{"image_position":"center-center","padding_remove_bottom":true,"padding_remove_horizontal":false,"padding_remove_top":false,"style":"default","title_breakpoint":"xl","title_position":"top-left","title_rotation":"left","vertical_align":"","width":"default"},"children":[{"type":"row","props":{"width":"xsmall"},"children":[{"type":"column","props":{"image_position":"center-center","position_sticky_breakpoint":"m"},"children":[{"type":"headline","props":{"block_align":"center","id":"postid-2096-title","text_align":"center","title_element":"h1"},"source":{"query":{"name":"posts.singlePost"},"props":{"content":{"filters":{"search":""},"name":"title"}}}}]}]},{"type":"row","props":{"alignment":"center","column_gap":"large","margin":"default","width":"default"},"children":[{"type":"column","props":{"image_position":"center-center","position_sticky_breakpoint":"m"},"children":[{"type":"html","props":{"content":"

<div class=\"g-slides\" style=\"text-align:center;\" id=\"postid-2096-img\"><iframe src=\"https:\/\/docs.google.com\/presentation\/d\/e\/2PACX-1vRH8_9vElZLnfEPwz7r1pK2fheT6fPdXDSNy7oi_kacCY-REOd5lcEyVJ2NG0V6IpsoMMTpCq-dgNnX\/embed?start=false&loop=false&delayms=3000\" frameborder=\"0\" width=\"100%\" allowfullscreen=\"true\" mozallowfullscreen=\"true\" webkitallowfullscreen=\"true\"><\/iframe><\/div>"}}]}]}],"name":"Hero"},{"type":"section","props":{"image_position":"center-center","padding_remove_top":false,"style":"default","title_breakpoint":"xl","title_position":"top-left","title_rotation":"left","vertical_align":"","width":"xsmall"},"children":[{"type":"row","props":{"margin":"default","row_gap":"large"},"children":[{"type":"column","props":{"image_position":"center-center","position_sticky_breakpoint":"m"},"children":[{"type":"headline","props":{"content":"Wait, What!","margin_remove_bottom":true,"title_element":"div","title_style":"h4"}},{"type":"headline","props":{"content":"The Website Proposal Template is a Presentation, not a Word or PDF document","margin_remove_top":true,"title_element":"h2"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>That's right, the format of this website proposal template is a Google Presentation, and there is a very good reason to do it that way.<\/p>","margin":"default","text_color":"emphasis","text_style":"large"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>When I did the 10K Bootcamp with uGurus, which is a prehistoric version of <a href=\"https:\/\/ugurus.com\/uacademy-launch-your-digital-agency\/\" target=\"_blank\" rel=\"noopener\">uacademy<\/a>, one of the commanments was; You shall not just email proposals.<\/p>","margin":"default"}},{"type":"headline","props":{"content":"Always Present the Web Design Proposal to the Prospect","title_element":"h3"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>After I stopped emailing proposals to the clients and started presenting them, my conversion rate increased dramatically.<\/p>\n

<p>Also, most web designers who were doing the training with experience a significant conversion rate improvement.<\/p>\n

<p>Considering all proposal are now presented instead of sent, it makes sense to use a Presentation format for the Web Design Proposal.<\/p>","margin":"default"}},{"type":"headline","props":{"content":"Download for Free this Web Design Proposal Template","margin_remove_top":false,"title_element":"h2"}},{"type":"text","props":{"column_breakpoint":"m","content":"

<p>This is the exact same format we've been using since 2018 and it has given us great results. I hope you find it useful and help you land your next client.<\/p>\n

<p>Complete the form below and receive our free web design proposal template for freelance designers in your inbox.<\/p>","margin":"default"}}]}]},{"type":"row","props":{"width":"xsmall"},"children":[{"type":"column","props":{"image_position":"center-center","position_sticky_breakpoint":"m"},"children":[{"type":"html","props":{"content":"[ninja_form id=4]","css":".el-element{max-width:300px;margin:0 auto;}"}}]}]}],"name":"Post"},{"type":"section","props":{"image_position":"center-center","status":"disabled","style":"muted","title_breakpoint":"xl","title_position":"top-left","title_rotation":"left","vertical_align":"","width":"xlarge"},"children":[{"type":"row","children":[{"type":"column","props":{"image_position":"center-center","position_sticky_breakpoint":"m","width_medium":"1-1"},"children":[{"type":"headline","props":{"content":"More Stories","title_element":"h2","title_style":"h4"}},{"type":"grid","props":{"content_column_breakpoint":"m","css":"@media (max-width: 959px) {\n\t.el-element > * > :nth-child(2n+0) { display: none; }\n}","filter_align":"left","filter_all":true,"filter_grid_breakpoint":"m","filter_grid_width":"auto","filter_position":"top","filter_style":"tab","grid_default":"1","grid_medium":"3","grid_small":"2","icon_width":80,"image_align":"top","image_grid_breakpoint":"m","image_grid_width":"1-2","image_height":"400","image_link":true,"image_svg_color":"emphasis","image_width":"610","item_animation":true,"link_style":"default","link_text":"","margin":"medium","meta_align":"below-title","meta_color":"muted","meta_element":"div","meta_margin":"small","meta_style":"h6","parallax_easing":"1","show_content":true,"show_image":true,"show_link":true,"show_meta":true,"show_title":true,"title_align":"top","title_element":"h3","title_grid_breakpoint":"m","title_grid_width":"1-2","title_hover_style":"reset","title_link":true,"title_margin":"medium","title_style":"h6"},"children":[{"type":"grid_item","props":{"image":"wp-content\/themes\/yootheme\/packages\/theme\/assets\/images\/element-image-placeholder.png","item_element":"article","link":"#","meta":"<time datetime=\"2019-10-02T09:55:29+00:00\">02 October, 2019<\/time>","title":"Alpaca Wool \u2013 Why Is It Good for Clothes?"}},{"type":"grid_item","props":{"image":"wp-content\/themes\/yootheme\/packages\/theme\/assets\/images\/element-image-placeholder.png","item_element":"article","link":"#","meta":"<time datetime=\"2019-08-26T09:55:29+00:00\">26 August, 2019<\/time>","title":"Comfy Must-haves for the Summer Season"}},{"type":"grid_item","props":{"image":"wp-content\/themes\/yootheme\/packages\/theme\/assets\/images\/element-image-placeholder.png","item_element":"article","link":"#","meta":"<time datetime=\"2019-08-02T09:55:29+00:00\">02 August, 2019<\/time>","title":"Enjoying a Beach Holiday with a Baby"}}]}]}]}],"name":"Latest Posts"}],"version":"4.4.10"} --></p>
<p>The post <a href="https://staging.koalawidgets.com/free-web-design-proposal-template-freelance-designers/">Free Web Design Proposal Template for Freelance Designers</a> appeared first on <a href="https://staging.koalawidgets.com">Koala Widgets</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
