Once again, I want to tell you about the results of a site design study that attracted my attention. Last time I wrote about the CSS mechanisms that underlie the new Facebook design. And now I’m curious to explore Twitter CSS. The new Twitter design appeared almost a year ago. I found a lot of interesting things in the CSS CSS: something seemed just fine to me, and something was strange.
User avatars aspect ratio
I noticed an interesting implementation of the user avatar on the profile page. This implementation uses a CSS technique for preserving the aspect ratio of an element.User avatar on the profile pageThe following HTML and CSS code illustrates the implementation of the avatar.<a href="#" class="avatar">
<div class="avatar-aspect-ratio"></div>
<img alt="" src="me.jpg">
</a>
.avatar {
position: relative;
width: 25%;
display: block;
}
.avatar-aspect-ratio {
width: 100%;
padding-bottom: 100%;
}
.avatar img {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
}
The technique of preserving the aspect ratio of an element works due to the fact that when an element has a vertical indent (property padding-bottom
or padding-top
), the indent depends on the width of the element. Take a look at the following example:.element {
width: 250px;
padding-bottom: 100%;
}
The calculated value padding-bottom
is equal 250px
. This means that we have a perfect square. The Twitter team used the same technique, but applied to an element <img>
that, in relation to the parent element, is absolutely positioned. Why? Here is the reason.Something is wrong with the avatar.When the image is not positioned absolutely, the avatar will look like the one shown in the previous figure. The image must be positioned using a value100%
for width and height. With this approach, its size will be set in accordance with the size of the wrapper element.Now that we’ve figured out the idea behind this solution, let's get back to how this idea was implemented on Twitter.The property iswidth: 25%
based on the width of the wrapper element. On my screen it is -600px
. I wondered why such a technique was chosen. After I learned more about CSS code, I noticed that the same component is used in the Edit Profile modal window. True, the element here is smaller due to the use of the following style:.avatar {
max-width: 8rem;
}
I really like the idea of managing images by influencing only the property width
. Here is a video illustrating this idea.Image Width ControlHere you can find a demo project for this section.Percentage upper indent
In order for the user’s avatar to overlap the photo located at the top of the profile page, a negative external indent specified in percent is used:.avatar {
margin-top: -18%;
}
True, in the Edit Profile modal window, the design is already used to adjust the upper indentation margin-top: -3rem
. Note that the indentation in the modal window is set using units rem
. The same units are used to set the property max-width
.Strange use of the calc () CSS function
I noticed that the following CSS is used to style some buttons:.button {
min-width: calc(45.08px)
}
Why pass functions a calc()
single value? I don’t see the point. Maybe they wanted to round the number 45.08? But with this approach, it is not rounded to 45. The width of the button is very small. The button, when translating the application into an RTL language, such as Arabic, will be too small.A button that is too smallThe functioncalc()
appears in the inline CSS. Therefore, I believe that this is the result of the dynamic styling of the button using React.Mix CSS backgrounds and HTML images
In many places on the site, I found a mix of background images defined by CSS and HTML images. Take a look at the following example:<div style="background-image: url(me.jpg);"></div>
<img alt="" src="me.jpg">
I saw this in the user profile, and in the component used in the formation of the grid layout. Interestingly, the opacity
element property is <img>
set to 0
. The source of the active image is a property background-image
. In addition, a property is used here background-size: cover
that avoids image distortion.I tried to do the opposite, that is, to display the element <img>
and hide the CSS background, and compared the grid layouts. The results of this comparison are shown below.On the left is the option in which the background image is used, and on the right is the option in which the HTML image is used.Obviously, the image on the right is distorted! I don’t know why the development team did not use the CSS propertyobject-fit: cover
to prevent distortion. And I would like to know about why two images are used here.Reset Styles
I noticed one pattern, which is the constant use of the CSS class that is added to the elements <div>
. Here is the relevant CSS:.css-1dbjc4n {
align-items: stretch;
border: 0 solid black;
box-sizing: border-box;
display: flex;
flex-basis: auto;
flex-direction: column;
flex-shrink: 0;
margin-bottom: 0px;
margin-left: 0px;
margin-right: 0px;
margin-top: 0px;
min-height: 0px;
min-width: 0px;
padding-bottom: 0px;
padding-left: 0px;
padding-right: 0px;
padding-top: 0px;
position: relative;
z-index: 0;
}
This style applies literally to every element <div>
on the page. Why? Isn't resetting CSS styles enough here?Some of the styles described above are quite understandable to me, sort of min-width: 0
, since there is some connection with Flexbox. But what about indentation, indentation, borders? Why does one element <div>
need to be reset styles, given the fact that this element does not have the appropriate properties?Flexbox and min-width: 0
The default value of the property min-width
is auto
, which turns out to be zero. When something is displayed as a flex element, the value of its property min-width
is equal to the size of its contents. Allowing this behavior may violate the layout if the content of the element is larger than it is.In order to avoid this problem, you need to reset the property min-width
for descendants of flex-elements.Flex item and Flexbox wrapperThe layout shown above shows what might happen if the content of the flex item is too long. Note that the text goes beyond the bounds of the wrapper element. But what happens when using the propertymin-width: 0
.The content does not go beyond the flex elementUsing position: sticky property
I noticed the use of the property position: sticky
in the right sidebar of Twitter (where media trends and recommendations regarding users to follow are displayed). It seemed interesting to me how the work with property values was organized bottom
and top
when scrolling. The default values are as follows:.sidebar {
position: sticky;
width: 350px;
bottom: -470.5px;
}
When the page scrolls down, the property bottom
is replaced with the property top: -480.5px
. I think that designers did this in order to allow the user to reach the end of the sidebar first. The property is top
added after that.Separator Elements
Just like in the Facebook design I analyzed earlier, in the Twitter design, in many places, separator elements are used. All these are flex elements whose width is set using the property flex-basis
.Separator ElementsThe first element shown in the previous image uses the property when setting the separator elementflex-grow: 1
. The second uses a fixed width specified in pixels.Making Tweet Content
TweetAbove is created by me tweet. At first glance, it may seem that we have before us an element<p>
or<span>
, in which text is added. But, as it turned out, each smiley is represented by a separate tag<span>
, and if the text is between two such elements, it is also made out as a tag<span>
.The design of the text of the tweetEmoticon - this<span>
, in which there is an element<div>
,<div>
contains two images. One is the CSS background, the second is the HTML image.Since the first sentence is wrapped in a tag<span>
, there must be separators between it and elements of the same level as it. Designers added a new line at the beginning of the second sentence in order to separate the sentences.Second sentenceUsing calculated values to separate items
Back buttonWhen performing a search on Twitter, or when opening a profile page, a button can be seen
. A style has been applied to this buttonmargin-left: -4px
, specifying a negative outer left indent. I was interested in the procedure for calculating this value..back-button {
margin-left: calc(5px + (-1 * (39px - 1.5em)) / 2);
}
The above calculations result in a value -4px
. Why not just ask -4px
? Is this better in this case than using a function calc()
?Width of navigation links
Navigation linksFrom the first day, when I came across a navigation links panel, I noticed that when you hover over them, their width turns out to be equal to their content. I wondered why not make the icon and label cover the entire width of the navigation element.Here, my attention was drawn to the use of a propertyflex-direction: column
for each element of the navigation bar. Why? Is this necessary in a situation where only one child is used here?External indent added just in case
The indentation in question is present in the design to prevent unwanted page layout behavior. I drew attention to two examples of the use of indentation added to elements, so to speak, “just in case”. Let's look at them.Indentation added to elements “just in case”. On the left is the normal content of the element. On the right is the content that is noticeably longer than normal.Pay attention to what happens when the content of the element is noticeably longer than its normal content. Namely, the following occurs here:- The text is cropped.
- There is an indent between the elements.
External indentation plays the role of a placeholder, which prevents the element from occupying the entire space. If you take this into account in time, you can avoid unexpected problems that may arise during the project. It is recommended that you always test page layouts using content that is longer than a “normal” length.Modal windows in small viewing areas
I examined the modal profile editing window. It turned out that at a certain height of the viewing area, the button for Save
such a window is not available. Here is how it looks.Inaccessible Save buttonSince the modal window does not support scrolling,Save
I could not getto the button. But the window used to control the appearance of elements supports dynamic height change and scrolling.A window that supports dynamic height changesWhy does one window support scrolling and the other not? It is interesting to know which one, according to Twitter designers, is more important? As for me - this is exactly the window that is used to edit the profile.Do you plan to adopt any ideas from Twitter design?