The world of web front-end development has seen significant advancements in recent years. However, the core of what users experience on the web remains the same: HTML structure styled with CSS.
Creating layouts can appear simple initially, but complexities often arise. Without a deep understanding of specific CSS features, achieving advanced layouts solely with CSS can seem impossible.
This article presents eight powerful CSS tips and techniques that utilize lesser-known CSS properties to implement advanced layouts and visual effects.
1. Optimizing CSS Sibling Selectors
Challenge: Missing optimization opportunities by not leveraging sibling selectors.
Solution: Utilize sibling selectors strategically. When styling lists and needing to differentiate the first or last item, your initial inclination might be to use the :first-child and :last-child pseudo CSS selectors.
For instance, when styling a CSS-only hamburger menu icon:
This approach is logical: each bar has a bottom margin except the last one.
However, the same effect can be achieved using the adjacent sibling selector (+):
This also makes sense: every element after the first bar has a top margin. This trick not only reduces code size (which adds up in larger projects) but also opens up new possibilities.
Consider this example of a card list:
Each card contains a title and text, with the text hidden by default. To reveal the text only for the active card (with the .active class) and those following it, you can use this CSS:
Adding a touch of JavaScript makes this interactive.
Relying solely on JavaScript for this functionality would require a script like this:
where including jQuery as a dependency helps achieve concise code.
2. Standardizing HTML Element Sizing
Challenge: Inconsistent rendering of HTML element sizes across browsers.
Solution: Set box-sizing to border-box for all elements. Internet Explorer, despite its flaws, excelled in one area: consistent box sizing.
Unlike Internet Explorer, other browsers calculate element width based on content only, treating padding and borders as extra. A width: 200px div with 20px padding and a 2px border would render as 242 pixels wide.
Internet Explorer, however, includes padding and border within the defined width. In this case, the div would be 200 pixels wide as intended.
Once accustomed to this behavior, you might find it to be more logical, despite it not aligning with standards.
If a width is specified as 200px, it should render as a 200px wide box, regardless of padding.
To maintain consistent element sizes (and therefore layouts) across browsers, use the following CSS:
The second selector set prevents layout issues in HTML elements styled without border-box in mind.
box-sizing: border-box is so valuable that it’s a cornerstone of the popular CSS framework sanitize.css.
3. Creating Dynamic Height Elements
Challenge: Maintaining an element’s height proportional to its width.
Solution: Use vertical padding as a substitute for height.
Suppose you need an element’s height to always match its CSS width. height: 100% won’t work as elements naturally adjust their height to their content.
The solution is to set the height to 0 and use padding-top or padding-bottom to control the actual height of .container. These padding properties can be defined as a percentage of the element’s width:
Now, .container will always maintain a square shape regardless of its width. overflow: hidden prevents content from exceeding these proportions.
This technique, with modifications, is ideal for creating aspect-ratio-preserving video embeds. Simply align the embed to the top and left of .container using position: absolute, set its dimensions to 100% to fill .container, and adjust .container’s padding-bottom to match the video’s aspect ratio.
position: relative on .container ensures that the iframe absolute positioning works properly. The updated padding-bottom is calculated by dividing the aspect ratio’s height by its width and multiplying by 100. For a 16:9 aspect ratio, the padding-bottom percentage would be 9 divided by 16 (0.5625) multiplied by 100, resulting in 56.25%.
4. Creating Dynamic Width Elements
Challenge: Maintaining an element’s width proportional to its height.
Solution: Utilize font-size as the basis for the element’s dimensions.
What about the reverse scenario, where a container’s width adjusts to its height? Here, font-size comes into play. Remember that width and height can be specified in em units, representing a ratio of the element’s font-size.
An element with a font-size of 40px, a width of 2em, and a height of 1em would have a width of 80 pixels (40 x 2) and a height of 40 pixels (40 x 1).
To modify .container’s height, simply adjust the font-size.
The only limitation is that CSS alone cannot automatically match an element’s font-size to its parent’s height. However, this technique significantly streamlines a JavaScript resize script from:
| |
to:
| |
5. Vertically Centering Dynamic Content
Challenge: Vertically centering an element (with unknown height) within another element.
Solution: Set the outer element’s display to table, then style the inner element as a CSS table-cell. Alternatively, utilize CSS Flexbox.
Vertically centering a single line of text can be achieved using line-height:
For multi-line text or non-text content, CSS tables offer a solution. Style .container with display: table, then apply display: table-cell and vertical-align: middle to .text:
Consider this technique the vertical counterpart to margin: 0 auto. CSS3’s Flexbox provides an elegant alternative if Internet Explorer’s buggy support is acceptable:
6. Equal Height Columns
Challenge: Maintaining equal height for multiple columns.
Solution: Apply a large negative margin-bottom to each column and offset it with an equally large padding-bottom. CSS tables and Flexbox are viable alternatives.
CSS allows the creation of side-by-side columns using float or display: inline-block.
Note the use of box-sizing: border-box to ensure accurate sizing of the .cols elements (refer to Standardizing HTML Element Sizing).
The borders of the first and last columns might not extend fully, failing to match the height of the tallest column. To address this, simply add overflow: hidden to .row. Then, set each .col element’s margin-bottom to 99999px and padding-bottom to 100009px (99999px + the 10px padding applied to other sides of .col).
Flexbox offers a more straightforward solution. Again, consider browser support before implementing.
Another option with broader browser support is to utilize CSS tables (without vertical-align: middle).
7. Thinking Outside the Box
Challenge: Escaping the limitations of rectangular layouts.
Solution: Leverage transform: rotate(x) or border-radius.
Imagine a common website layout with a series of vertically stacked content panes, each converging at a single point. The markup and CSS might look like this:
To transform these rectangular panes into a stack of parallelograms, albeit with increased markup complexity, you can implement the following:
Let’s break down this code:
.pane-containercontrols the height of each pane. The negativemargin-bottomensures the panes stack tightly..pane-background, its child.mask-box, and its grandchild.imageare all styled withposition: absolute. Each element has distincttop,left,bottom, andrightvalues to eliminate spacing issues caused by the rotations described below..mask-boxis rotated 2 degrees counter-clockwise..imageis rotated -2 degrees to counteract the rotation of.mask-box..mask-boxhasoverflow: hiddento clip the.imageelement along its rotated top and bottom edges.
Similarly, transforming an image into a circle or oval is incredibly straightforward. Simply apply border-radius: 100% to the img element.
Such real-time CSS manipulations reduce the need for pre-designed content. Instead of applying a circular mask in Photoshop, developers can achieve the same effect directly in CSS, preserving the original image.
This content-agnostic approach also benefits future redesigns by keeping content independent of the current design.
8. Implementing Night Mode
Challenge: Creating a night mode without introducing a separate stylesheet.
Solution: Utilize CSS filters.
Many apps offer a night mode to improve readability in low-light conditions. Modern browsers allow for similar effects using CSS filters, which apply Photoshop-like adjustments.
The invert filter, as its name suggests, inverts the colors of an element’s content. This eliminates the need for additional stylesheets.
Applying this filter to black text on a white background simulates a night mode effect. !important ensures these color overrides take precedence.
However, images might appear distorted due to the color inversion. Fortunately, CSS allows for multiple filters to be applied simultaneously. Adding the hue-rotate filter corrects the appearance of images and other visual content:
This works because hue-rotate(180deg) essentially replicates the effect of invert(1). Here’s a demo of how the night mode CSS would function when toggled by a JavaScript button.
Maximizing CSS Potential
Unless there are fundamental shifts in browser technology or website development practices, a strong understanding of CSS will remain an essential skill in web development.
The common thread among these CSS tips is the emphasis on leveraging CSS to its full potential, enabling the browser to handle the complex processing. When executed correctly, this approach leads to improved results, enhanced performance, and ultimately, a superior user experience.
Feel free to share any interesting and valuable CSS tricks you’ve encountered in the comments below.