Build a Twitter Clone From Scratch: The Design

Build a Twitter Clone From Scratch: The Design

Tutorial Details
    • Difficulty: Beginner
    • Completion Time: 1 Hour

This article represents the first in a new group effort by the Nettuts+ staff, which covers the process of designing and building a web app from scratch – in multiple languages! We’ll use a fictional Twitter-clone, called Ribbit, as the basis for this series.

In this tutorial, we need to focus on the UI. We’ll leverage the popular LESS Preprocessor to make our CSS as manageable as possible.


Introduction

Be sure to download the assets for this tutorial, if working along.

This tutorial is divided into five major parts, which explain how to style various pages of Ribbit’s layout. I will reference HTML elements using CSS selectors to make it easier to understand. But before diving into the layout, let’s briefly discuss nesting.

Nesting

In CSS, referencing a nested element can result in lengthy selectors. For example:

someId {
	/* ... */
}

someId div.someClass {
	/* ... */
}

someId div.someClass p.someOtherClass {
	/* ... */
}

someId div.someClass p.someOtherClass target {
	/* ... */
}

And it can grow even bigger! With LESS, you can nest one element in another, making it easier to read:

someId {
	/* ... */
    div.someClass {
        /* ... */
        p.someOtherClass {
            /* ... */
            target {
                /* ... */
            }
        }
    }
}

Variables and Mixins

Create a new file and name it, style.less. When using any style preprocessor, it’s a good idea to store important colors and sizes within variables; you can easily adjust their values without searching the file, looking for property values that you need to change. We will use a handful of variables for the text color, border color, and content width:

@text-color: #3F3E3D;
@border-color: #D2D2D2;
@content-width: 860px;

Now, let’s create two mixins. The first will create the illusion of anti-aliased text, and the second will allow for cross-browser gradients. The former is rather simple:

.antialiased (@color) {
    color: @color;
    text-shadow: @color 0 0 1px;
}

The trick is to create a shadow underneath the text with the same color and a one-pixel spread, making the browser display a nice shade around the text.

Now for the gradient; this is more complicated than the anti-aliased text because every browser implements gradients differently. Once we’ve compensated for the various vendor prefixes, here is the code:

.gradient4f (@p1, @c1, @p2, @c2, @p3, @c3, @p4, @c4) {
    background: @c1;
    background: -moz-linear-gradient(top,  @c1 @p1,  @c2 @p2,  @c3 @p3,  @c4 @p4);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(@p1, @c1), color-stop(@p2, @c2), color-stop(@p3, @c3), color-stop(@p4, @c4));
    background: -webkit-linear-gradient(top, @c1 @p1, @c2 @p2, @c3 @p3, @c4 @p4);
    background: -o-linear-gradient(top, @c1 @p1, @c2 @p2, @c3 @p3, @c4 @p4);
    background: -ms-linear-gradient(top, @c1 @p1, @c2 @p2, @c3 @p3, @c4 @p4);
    background: linear-gradient(to bottom, @c1 @p1, @c2 @p2, @c3 @p3, @c4 @p4);
}

Every browser has a prefix: -moz- for Firefox, -webkit- for Chrome, etc. The last line uses the W3C recommended version for gradients. If a browser supports it, it will override the previous properties because it’s the last background property declaration in the rule. The linear-gradient function accepts eight parameters: four pairs of percent-color values. It creates the gradient with four color steps.


Global Styles

Let’s next style some global elements, such as for buttons and links. We want all elements to use the Helvetica or Arial fonts with the text color defined earlier:

* {
    font-family: sans-serif;
    color: @text-color;
}

Body

The body is pretty easy; we need a white background with an image-based pattern. There are no margins and padding:

body {
    background: white url(gfx/bg.png);
    margin: 0;
    padding: 0;
}

Inputs

We’ll also provide a default style for all <input/> elements in the page:

input {
    width: 236px;
    height: 38px;
    border: 1px solid @border-color;
    padding: 0 10px;
    outline: none;
    font-size: 17px;

    &:focus {
        background: #FFFDF2;
    }
}

We set the default size and padding, and we use the @border-color variable to remove the annoying blue outline when the element is focused. You should notice another bit of LESS sugar: we can add CSS pseudo-classes (and normal classes too) using the & character (parent reference), as shown here:

&:focus {
    background: #FFFDF2;
}

This causes the input to have a light yellow background, when focused.

Submits

Submit buttons will use both the previously defined mixin and the border-radius to create nice effect:

input[type="submit"] {
    height: 36px;
    border: 1px solid #7BC574;
    border-radius: 2px;
    color: white;
    font-size: 12px;
    font-weight: bold;
    padding: 0 20px;
    cursor: pointer;
    .gradient4f(0%, #8CD585, 23%, #82CD7A, 86%, #55AD4C, 100%, #4FA945);
}

Links

The links should have a different color than normal text. We’ll also underline them on hover:

a {
    text-decoration: none;
    .antialiased(#58B84E);
    &:hover {
        text-decoration: underline;
    }
}

Basic Template

We will begin with the portion of the layout that remains the same in every page. Here is the HTML code, which I will explain below:

<!DOCTYPE HTML>
<html>
<head>
    <link rel="stylesheet/less" href="style.less">
    <script src="less.js"></script>
</head>
<body>
    <header>
        <div class="wrapper">
            <img src="gfx/logo.png">
            <span>Twitter Clone</span></p>

		</div>
	</header>
	<div id="content">
		<div class="wrapper">

		</div>
	</div>
	<footer>
		<div class="wrapper">
			Ribbit - A Twitter Clone Tutorial<img src="gfx/logo-nettuts.png">
		</div>
	</footer>
</body>
</html>

We start with a normal doctype definition and document head. You can use the less.js library and include the style.less in the development stage (as I did in this code). Later, you can compile the LESS file into CSS, if you don’t wish to use less.js. As you’ve probably noticed by now, the layout is divided into three parts: header, #content, and footer. You should save this HTML to see if you are styling everything correctly.

Header

Let’s tackle the header. It contains Ribbit’s logo and the two words: ‘Twitter Clone’. It’s wrapped in a wrapper, the width of which is controlled by the @content-width variable. There are several wrappers in the layout, and all are @content-width wide with auto margin:

.wrapper {
    width: @content-width;
    margin: auto;
}

The header itself is 85px tall and page wide:

header {
	background: url(gfx/bg-header.png);
	height: 85px;
	width: 100%;
}

After the width, add div.wrapper‘s style with vertical padding:

div.wrapper {
    padding: 11px 0;
}

So the header should look like:

header {
    background: url(gfx/bg-header.png);
    height: 85px;
    width: 100%;

    div.wrapper {
        padding: 11px 0;
    }

Images in the wrapper need to be 10px lower, in order to be nicely centered:

img {
    position: relative;
    top: 10px;
    margin: 0 15px 0 0;
}

Also, the font in <span/> elements must be larger than the default size:

span {
    font-size: 18px;
    margin: 0 42px 0 0;
}

Here’s how our design should look at this point.

Header in basic template.

Content

There’s not much we can do with #content at this time. We’ll add some margin to the bottom and a minimum height; the layout will look funky if it’s not tall enough:

#content {
	margin-bottom: 15px;
	min-height: 560px;
}

Inside, the wrapper needs to have some vertical margin with an automatic horizontal margin:

div.wrapper {
    margin: 38px auto;
}

Footer

Like the header, the footer is the same for all pages. We’ll use a background image and a smaller font size. We’ll also need to clear: both, because we’ll use floats in the content. Without clearing, the footer will not adjust in accordance with the content:

footer {
	background: url(gfx/bg-footer.png);
	height: 251px;
	font-size: 14px;
	clear: both;
}

Let’s now add some padding to the wrapper, and images within it should float to the right:

div.wrapper {
    padding: 15px;

    img {
        float: right;
    }
}

Here’s our footer:

Completed footer.

The Home Page

This page displays for users not logged in to Ribbit. Therefore, it will need to present the login form in the header and a register form, with a big frog image in the content. Let’s start with a basic template.

Login Boxes

Add this login form to the div.wrapper of the header, after the <span/> element:

<form>
    <input type="text">
    <input type="password">
</form>

These inputs are already styled, but we do need to add the margins and make the form display as inline. Append this after span in div.wrapper of header:

form {
    display: inline;

    input {
        margin: 0 0 0 14px;
    }
}

Register Form

Here is the HTML for the registration form:

<img src="gfx/frog.jpg">
<div class="panel right">
    <h1>New to Ribbit?</h1>
    <form>
        <input name="email" type="text">
        <input name="password" type="text">
        <input name="password2" type="password">
        <input type="submit" value="Create Account">
    </form>
</div>

Add this HTML within div.wrapper of #content. We want the image to have rounded corners and to be floated to the left (add this after margin in div.wrapper of #content):

img {
    border-radius: 6px;
    float: left;
}

Now, we can style the registration form. It will also be a panel that we’ll use later; that’s why we will style the .panel:

div.panel {
    border: 1px solid @border-color;
    background: white;
    margin: 0;
    margin-bottom: 29px;
    border-radius: 6px;
    font-size: 14px;
}

For now, though, we will only style the right panel. It’s narrower and sticks to the right side of the panel. Naturally, insert the following into div.panel:

&.right {
    width: 303px;
    height: 313px;
    float: right;
}

Also, we need to take care of the header and content of the panel. We use <h1/> elements for the header and <p/> elements for content. Notice that you can use the * wildcard inside of another element:

* {
    margin: 6px 0;
}
form {
    padding: 0 23px;
}
h1 {
    border-bottom: 1px solid @border-color;
    margin: 5px 0;
    font-weight: normal;
    font-size: 18px;
    padding: 13px 23px;
    height: 23px;
}
p {
    padding: 0 24px;
    margin: 18px 0;
}

Here is how div.panel‘s style should look:

div.panel {
    border: 1px solid @border-color;
    background: white;
    margin: 0;
    margin-bottom: 29px;
    border-radius: 6px;
    font-size: 14px;

    &.right {
        width: 303px;
        height: 313px;
        float: right;
    }
    
    * {
		margin: 6px 0;
	}
	h1 {
		border-bottom: 1px solid @border-color;
		margin: 5px 0;
		font-weight: normal;
		font-size: 18px;
		padding: 13px 23px;
		height: 23px;
	}
	p {
		padding: 0 24px;
		margin: 18px 0;
	}
}

And here is a screenshot of how this page should look, thus far (click to see full size):

Home page preview


Buddies Page

The Buddies page should be displayed when a user logs in. It will display a list of the last “Ribbits,” along with some statistics of your account. Once again, start with the basic template. This page, along with other pages, will display a logout button in place of the login form in the header:

<form>
    <input type="submit" id="btnLogOut" value="Log Out">
</form>

The buttons have already been styled, so we only need to pin it to the right side of container and add some margins:

#btnLogOut {
	float: right;
	margin: 14px 0 0 0;
}

Because this rule’s selector is an element’s ID, you can place it either outside of any element or within the header’s div.wrapper. It’s your choice, but remember that, if you choose to place it inside of another element, the compiled CSS will have a longer selector (header div.wrapper #btnLogOut).

“Create a Ribbit” Box

First, add this panel’s code to div.wrapper of #content:

<div id="createRibbit" class="panel right">
    <h1>Create a Ribbit</h1>
    <p>
        <form>
            <textarea name="text" class="ribbitText"></textarea>
            <input type="submit" value="Ribbit!">
        </form>
    </p>
</div>

The .right class was styled earlier, but we need to add some styling for the <textarea/> element. We’ll give it a proper size and border:

textarea.ribbitText {
    width: 249px;
    height: 160px;
    border: 1px solid @border-color;
}

Add this in the style definition of the right panel.

User Information

Now, let’s focus on the panel, which contains the user’s account information. We’ll temporarily populate it with some random content to see the styling:

<div id="ribbits" class="panel left">
    <h1>Your Ribbit Profile</h1>
    <div class="ribbitWrapper">
        <img class="avatar" src="gfx/user1.png">
        <span class="name">Frogger</span> @username
        <p>
            567 Ribbits<span class="spacing">45 Followers</span><span class="spacing">32 Following</span><br>
            Cras justo odio, dapibus ac facilisis in, egestas Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. <a href="#">http://net.tutsplus.com/tutorials/php/ ...</a>
        </p>
    </div>
</div>

It may look complex, but the structure is fairly simple, when you strip out the content:

<div id="ribbits" class="panel left">
  <h1>Your Ribbit Profile</h1>
  <div class="ribbitWrapper">
    <img class="avatar" src="gfx/user1.png">
    <span class="name"> </span>
    <p>
       <span class="spacing"> </span><span class="spacing"> </span><br>
    </p>
  </div>
</div>

Regardless, we have another panel; so we need to style it first:

&.left {
    width: @content-width - 327;
    float: left;
}

You probably know where to place this code (notice how easily you can perform arithmetical operations in LESS). This panel contains div.ribbitWrapper. So, add the following code:

div.ribbitWrapper {
    padding: 15px 0;
}

There are two <span/> elements inside this element, each with a different color and font size. They have classes of .name and .time:

span {
    &.name {
        font-size: 18px;
        color: #58B84E;
    }

    &.time {
        font-size: 12px;
        color: #CCC;
    }
}

We should also position the avatar image near the left border. Add the following code:

img.avatar {
    margin: 0 19px 0 20px;
    float: left;
}

Also, Ribbit’s text needs to be anti-aliased, justified and moved to the right. This code will place the text next to the avatar, as opposed to beneath it:

p {
    margin: 5px 50px 0 90px;
    padding: 0;
    text-align: justify;
    line-height: 1.5;
    .antialiased(@text-color);
}

In this paragraph, there are <span/> elements with vertical lines, visually separating them. This effect is achieved by using border, padding, and margin:

span.spacing {
    padding-left: 9px;
    margin-left: 9px;
    height: 10px;
    border-left: 1px solid @border-color;
}

Buddies’ Ribbits

This panel lists the latest ribbits from the people to whom the user follows. Insert the following after the user’s information panel:

<div class="panel left">
    <h1>Your Ribbit Buddies</h1>
    <div class="ribbitWrapper">
        <img class="avatar" src="gfx/user2.png">
        <span class="name">Kermit</span> @username <span class="time">15m</span>
        <p>
            Cras justo odio, dapibus ac facilisis in, egestas Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. <a href="#">http://net.tutsplus.com/tutorials/php/ ...</a>
        </p>
    </div>
    <div class="ribbitWrapper">
        <img class="avatar" src="gfx/user1.png">
        <span class="name">Frogger</span> @username <span class="time">15m</span>
        <p>
            Cras justo odio, dapibus ac facilisis in, egestas Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. <a href="#">http://net.tutsplus.com/tutorials/php/ ...</a>
        </p>
    </div>
    <div class="ribbitWrapper">
        <img class="avatar" src="gfx/user2.png">
        <span class="name">Kermit</span> @username <span class="time">15m</span>
        <p>
            Cras justo odio, dapibus ac facilisis in, egestas Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. <a href="#">http://net.tutsplus.com/tutorials/php/ ...</a>
        </p>
    </div>
    <div class="ribbitWrapper">
        <img class="avatar" src="gfx/user3.png">
        <span class="name">Hypnotoad</span> @username <span class="time">15m</span>
        <p>
            Cras justo odio, dapibus ac facilisis in, egestas Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. <a href="#">http://net.tutsplus.com/tutorials/php/ ...</a>
        </p>
    </div>
    <div class="ribbitWrapper">
        <img class="avatar" src="gfx/user2.png">
        <span class="name">Kermit</span> @username <span class="time">15m</span>
        <p>
            Cras justo odio, dapibus ac facilisis in, egestas Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. <a href="#">http://net.tutsplus.com/tutorials/php/ ...</a>
        </p>
    </div>
    <div class="ribbitWrapper">
        <img class="avatar" src="gfx/user3.png">
        <span class="name">Hypnotoad</span> @username <span class="time">15m</span>
        <p>
            Cras justo odio, dapibus ac facilisis in, egestas Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. <a href="#">http://net.tutsplus.com/tutorials/php/ ...</a>
        </p>
    </div>
</div>

There are few example ribbits to see how it looks. We’ll add some borders to visually separate them. Add this code in div.ribbitWrapper:

border-bottom: 1px solid @border-color;
&:last-child {
    border: none;
}

This styling adds the bottom border, while removing the border on the last div.ribbitWrapper; a border already exists on the panel.

Here is how this page should look now:

Buddies page preview


Public Ribbits Page

The “Public Ribbits” page will list the latest ribbits of profiles not marked as private, so that users can view the ribbits of those who they don’t have in their buddy list. Surprisingly, there is nothing else to style, but we do need to add a touch of HTML. The only difference between this and the previous page is that this one doesn’t have the user’s information panel, but it will have other content in the final site. So feel free to copy the code of the buddies page, but remove this panel:

<div id="ribbits" class="panel left">
    <h1>Your Ribbit Profile</h1>
    <div class="ribbitWrapper">
        <img class="avatar" src="gfx/user1.png">
        <span class="name">Frogger</span> @username
        <p>
            567 Ribbits<span class="spacing">45 Followers</span><span class="spacing">32 Following</span><br>
            Cras justo odio, dapibus ac facilisis in, egestas Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. <a href="#">http://net.tutsplus.com/tutorials/php/ ...</a>
        </p>
    </div>
</div>

Also change the header of the panel to “Public Ribbits.” Here is the preview of this page:

Public ribbits page preview


Public Profiles Page

On this page, users can see a list of profiles that are not marked as private. There is also a search box to find other profiles. We’ll start with the basic template.

Profile Search

The search box will use the .right panel with an <input/> element inside:

<div class="panel right">
    <h1>Search for profiles</h1>
    <p>
        <form>
            <input name="query" type="text">
            <input type="submit" value="Ribbit!">
        </form>
    </p>
</div>

Profiles List

Here are a handful of example profiles for the profile list, so that you can see how it looks in the browser. In a future lesson, we’ll of course replace this, accordingly.

<div id="ribbits" class="panel left">
    <h1>Public Profiles</h1>
    <div class="ribbitWrapper">
        <img class="avatar" src="gfx/user2.png">
        <span class="name">Kermit</span> @username <span class="time">625 followers <a href="#">follow</a></span>
        <p>
            Cras justo odio, dapibus ac facilisis in, egestas Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. <a href="#">http://net.tutsplus.com/tutorials/php/ ...</a>
        </p>
    </div>
    <div class="ribbitWrapper">
        <img class="avatar" src="gfx/user1.png">
        <span class="name">Frogger</span> @username <span class="time">329 followers <a href="#">follow</a></span>
        <p>
            Cras justo odio, dapibus ac facilisis in, egestas Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. <a href="#">http://net.tutsplus.com/tutorials/php/ ...</a>
        </p>
    </div>
    <div class="ribbitWrapper">
        <img class="avatar" src="gfx/user3.png">
        <span class="name">Hypnotoad</span> @username <span class="time">129 followers <a href="#">follow</a></span>
        <p>
            Cras justo odio, dapibus ac facilisis in, egestas Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. <a href="#">http://net.tutsplus.com/tutorials/php/ ...</a>
        </p>
    </div>
</div>

This page should look like:

Public profiles page preview


Compiling The CSS

Referencing a nested element can result in lengthy selectors.

As I noted earlier, for production, you can compile your LESS to CSS (and I recommend you do so for performance reasons). There are a few available online compilers:

Along with some stand-alone compilers:

  • Crunch! (which is a full-blown LESS editor)
  • WinLess (features auto compilation when the less file changes)
  • SimpLESS (includes CSS minification)

If any of these compilers do not work for you, Google for more; there are plenty! You can also use lessc from LESS’s site, but it’s much easier to compile your LESS files with other compilers. Of course, there is nothing wrong with using the less.js library to dynamically compile the layout; new browsers cache the resulting CSS.


Conclusion

As you can see, LESS is a powerful tool that makes it much easier and faster than plain CSS to style beautiful layouts.

But this is just the beginning. Be prepared to implement Ribbit’s back-end in a plethora of languages and platforms in the next set of tutorials!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • Aris B

    Great tutorial! Waiting for the backend :-)

    • http://twitter.com/brandonb927 Brandon Brown

      Me too, I’m curious to see how it performs

    • Amador Cuenca

      Can’t wait!

      • nn

        bbb

    • http://superdit.com aditia

      I’m waiting for database design

  • srigi

    At begining of series it would be nice to publish list of used technologies ;)

  • http://twitter.com/jeeppson Jesper Lindström

    The links to the big versions of the later screenshots are broken. Interesting series however, looking forward to see more!

  • http://www.facebook.com/jesus.bejarano.948 Jesus Bejarano

    This is so a random tutorial out of nowhere , i am waiting for the backend :)

  • Pete

    Beautiful design, really looking forward to the next tutorials, especially the back-end…

  • http://laranz.in/ lawrence77

    Which language you gonna use it for backend..?

  • http://twitter.com/jholyhead James

    Pity you’re not taking the opportunity to use this as a ‘real’ project case study, complete with requirements and planning stages.

    Writing code and markup is the easy bit.

    • Chris

      I agree with James. Might have been more appropriate to start from the very beginning (planning, wireframing etc.). Maybe utilizing other Tuts+ projects (webdesign team can do the wireframing and designing, then the Developers can come here and play with the backend, maybe a simple API could be built and then handed over to the mobiletuts guys to show the readers there how to build a twitter mobile app clone.) You then have a full-example of how to build a project from scratch to finish without any gaps in between.

      But not complaining, it is a nice start to a series and I enjoyed it. Just some feedback to consider for future projects (we all know how important user feedback is in webapps, right? At least, we would if it was a ‘real’ case study ;) ).

  • Thomas

    Why would you start with the design? IMO it makes more sense to start with the backend and core functionality. That way you can discover new possibilites, test how it feels to actually use your app or even discover that you can’t (or simply don’t have the skills to) build some features. Then, when you discover what the good, bad and ugly features are, you can design and polish your app some more.

    • jax

      you shouldn’t be designing your app and deciding features are too hard to implement, what better way to learn and improve your skills.

  • http://www.facebook.com/amoeba.inc Addai Francis

    I am really looking forward to the other parts of this tutorial series. I think it would have been great to have a run-down of the technologies that would be used before the UI design. But then again, I enjoyed it and I look forward to the rest.

  • http://villimagg.info/ Vilhjálmur Magnússon

    What’s wrong with the guy’s who are complaining like babies below? Seems like they have too many luxury-problems to crack. It’s a free tutorial. Enjoy it! …or leave it.

    • Margalus

      I wonder what’s wrong with you instead. They said this is amazing BUT they gave tips to improve it. A free resource, as well as a payed one, can be criticized as well as emphatized depending on you liked it or not.

      Your point is just stupid, the comment section is here to show our appreciation and/or tell the guys at Tutsplus what we liked and what not. If we all thought like you do the site would just need a thumbs up/thumbs down system like YouTube where there’s idiots disliking for no reason or without saying why they didn’t like a particular video(or, in this case, a resource).

      • http://villimagg.info/ Vilhjálmur Magnússon

        It is typical that often many people take things for granted and start demanding. When something is free in a world where nothing is free it’s important to remember to be grateful for the things that are given to us. And we haven’t done anything to deserve to get this information for free.

        When learning, most people who are into open source development search by them selfs for the information they need. If a tutorial they find only teaches part of what one is trying to learn then he/she goes on searching for the rest of the information he/she needs. That’s how it is in an open source community where information is free.

        If you want a complete tutorial from beginning to end then buy a subscription at various websites selling complete tutorials. Or buy books on the subject. There’s plenty of resources out there.

        My comment was meant towards people who comments where somewhat not polite in the matter that they sounded ungrateful for this free resource which the author put a lot of work into.

        It’s good to be constructive in a comment, or ask questions. But comments like “Pity you’re not taking the opportunity to use this as a ‘real’ project case study, complete with requirements and planning stages.” @twitter-39820751:disqus, is just unpolite. Maybe the author geared this tutorial more towards people who are obviously not as advanced as @James? or maybe…. what ever. Maybe his workflow is just different? What ever it is, this tutorial is good for what it’s worth.

        So, @8115b737bd2a6c6a5e520bcc40a223ea:disqus. You say that my point is just stupid. Well you sound pretty stupid yourself. I guess we’re just stupid then. If you think I sound stupid and I think you sound stupid then we must be really stupid?

        Lastly, I like to use this website for constructive things and to learn (especially since I need it since I’m such a stupid guy). Not to discuss stupid things with you so this will be my last one in this conversation. Have a nice day.

  • Joshua Roche

    Any chance of fixing the big images??

  • http://brayanrastelli.com/ Brayan Rastelli

    Great tutorial, but why not just use twitter bootstrap, instead of making all these styling? Plus the app would be responsive ;)
    PS: sorry for my bad english.

    • http://villimagg.info/ Vilhjálmur Magnússon

      Why not Stylus? Or YAML, or Skeleton, or Zurb Foundation, or Gumby framework, inuit.css……..and the list goes on…, why Twitter Bootstrap? Why look like every other web app on the web that uses Twitter Bootstrap? Why not be unique? I think the point of this tutorial is to get acquainted with a css pre-processor, in this case LESS, regardless of what css framework you choose to use for your own web apps. Plus, maybe the author of the tutorial thought that bringing in a full-featured css framework into a simple app like this would be an overkill, or unnecessary? Maybe he thought it was out of scope of the tutorial? Plus, you can get responsiveness via other frameworks than Bootstrap as well, and it’s easy to declare @media css stuff in your less/sass/css to reach responsiveness. And whatever it was or may be, for those who are not yet good with LESS/SASS can use this tutorial to learn some of it and apply it to their possible Bootstrap enhanced applications. Or….even better, apply it to their “whatever-css-framework-which-uses-LESS-or-SASS” in the future, be it Bootstrap or whatnot :)

      • http://www.facebook.com/profile.php?id=12406303 Robert Kyanberu

        I believe the reason Brayan specifically noted Bootstrap is that this is for a Twitter Clone. Twitter designed Bootstrap. Their site and app all make use of bootstrap-style UI elements. Ignoring Bootstrap entirely and re-writing all the styles is GREAT if you’re learning these things for the first time; but otherwise represents a significant time-sink when the app you’re trying to clone has esentially said “Here, use these. They are what I use!”

      • http://brayanrastelli.com/ Brayan Rastelli

        Couldn’t say it better @facebook-12406303:disqus :-)
        But I agree with you guys about not using frontend framework for learning purposes

      • http://villimagg.info/ Vilhjálmur Magnússon

        I know what you mean and at the same time I don’t think that just because it’s a Twitter Clone you have to use Bootstrap. I don’t see any logic there, sorry :) It’s a Twitter Clone by functionality and purpose but nothing say’s that because of that you have to use Bootstrap. I could make a Twitter Clone and style it completely differently and it would still be a Twitter Clone because of its functionality. I don’t see that styling has anything to do with it as the purpose of the app is the same and thus you get the same functionality weather the site is styled in this way or the other. It’s just graphical design and the app doesn’t care about its design nor does it know about its design and it works either way. :)

  • Panjijey

    Can you please make a video version ?

  • Jordan Wales

    Great post! I am way hyped to see the end result!

  • MPinteractiv

    Great but beginning with the backend , design bottom->up , the front-end is not that important. Begin with modelling the app , what are the actors ? the models ? a tweet , a user , relationship between users , etc … even with no specific code that’s the interesting part. Then model your database. model the services that will query the database , built the http api , then the front-end. once it is built design top->bottom. what kind of info the view needs ? etc …

  • Mark Starling

    “Remember, friends don’t let friends write LESS.” – http://sasscast.tumblr.com/post/38673939456/sass-and-media-queries

  • Matt

    Can anyone explain why the design looks so different when rendered in Chrome vs. the way it’s supposed to in other browsers?

  • Ty

    Just a FYI, I was having trouble with getting the .less to compile the styles on Chrome. It turns out that there is a bug that prevents processing .less files that start with file:/// etc. I had to start up MAMP (or WAMP on windows) to see the styling from the .less files.

  • 哈哈

  • Adam

    Thanks for the tutorial!

    Looking at the HTML at the top of the “Basic Template” section, I see that it has some issues:

    The
    <head> is missing the character encoding
    (e.g. <meta charset="utf-8">).
    The <head> is missing a <title> element.
    Both of the images have no alt attribute.
    There is a </p> where there shouldn’t be one.

    There are also some styling issues:

    If somebody were to create a ribbit that had, say, 60+ characters without any spaces, it would mess up the layout.
    Internet Explorer 9: the password field shows up below the logo.
    Internet
    Explorer 9: the button gradient doesn’t look right. Rather than going
    from light green to dark green, it goes from blue to black.
    Internet
    Explorer 9: all of the forms on the right (e.g. “New to Ribbit?” and
    “Create a Ribbit”) don’t have enough space to the right of the form
    fields.

    There may be other issues. I didn’t do exhaustive tests.

  • http://www.facebook.com/Misterberita Berita Gue

    awesome.. but dont understand about it.. :(