Home >Web Front-end >CSS Tutorial >Sass Maps vs. Nested Lists

Sass Maps vs. Nested Lists

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌Original
2025-02-24 08:46:09892browse

Sass Maps vs. Nested Lists

Core points

  • Sass maps and nested lists are both data structures in Sass, and mappings were introduced in Sass 3.3. Mapping provides key-value pairs that allow for more complex data storage, while nested lists are simpler structures that can save complex data, but lack key-value pairing.
  • Despite the added complexity of mapping, they become popular because of their ability to store a variety of data (such as breakpoint widths, color values, grid layouts, type proportions, and other responsive typography details). On the other hand, nested lists are more practical due to their simplicity and less input.
  • One of the main advantages of using Sass mapping is the ability to directly access specific values, which makes the code more efficient and easier to read. However, nested lists may be faster to write and maintain, but they lack the mapping's error checking and detailed query capabilities.
  • While nested lists may be more efficient in terms of input, they require absolute certainty of the number of items each list will contain and their order. Missing values ​​in nested lists can cause errors that Sass does not report, while for mappings, the map-get() function can still provide the desired value even if one value is missing.

The title of this article may surprise some people. If you are a Sass veteran, you may remember to use a list of lists to simulate the days when nested arrays of data (before Ruby-Sass-3.3). (Ruby) Sass 3.3 adds a new data type called Mapping. Lists of lists can save complex data in nested formats, but have no key-value pairing. The map adds key-value pairs and lets create an array of data.

With the advent of mapping, many of our Sass users started putting everything into the mapping (and for good reason!). All breakpoint widths, color values, grid layouts, type proportions, and other responsive typography details can be put into the map!

Now that Sass has a key-value pair mapping, is there any good reason to use a list of lists? One theoretical reason is backward compatibility: if your Sass is likely maintained by a developer with older versions installed, the list will help them. However, in practice, the Sass version is usually controlled by package.json or other project configurations, and the Ruby gem can be updated with just one command (gem update sass).

A more practical reason you might choose to use nested lists instead of mappings is that there is less input. Let's compare maps and nested lists to see how they compare in their respective syntax and loop traversal.

Grammar comparison

In our example, let's create a data structure that controls responsive typography. It will store four breakpoints (well, one is the smallest default view). For each breakpoint, we will store the minimum width, maximum width, base font size, and base line height.

Complex mapping syntax

The following is how we store data in a map. A large map will contain four keys (breakpoint labels) whose values ​​are maps of variables we need to store and use. In this readable format, we have over 450 characters and 26 lines.

<code>$breakpoint-map: (
  small: (
    min-width: null,
    max-width: 479px,
    base-font: 16px,
    vertical-rhythm: 1.3
  ),
  medium: (
    min-width: 480px,
    max-width: 959px,
    base-font: 18px,
    vertical-rhythm: 1.414
  ),
  large: (
    min-width: 960px,
    max-width: 1099px,
    base-font: 18px,
    vertical-rhythm: 1.5
  ),
  xlarge: (
    min-width: 1100px,
    max-width: null,
    base-font: 21px,
    vertical-rhythm: 1.618
  )
);</code>

Nested List Syntax

Nested lists that store the same data are much shorter. However, we no longer append the key to the data, so we have to rely on looping through it or calling it with the nth() function. That is, it is much shorter than the map: less than 180 characters, only 6 lines.

<code>$breakpoint-list: (
  (small, null, 479px, 16px, 1.3),
  (medium, 480px, 959px, 18px, 1.414),
  (large, 960px, 1099px, 18px, 1.5),
  (xlarge, 1100px, null, 21px, 1.618)
);</code>

Cycle comparison

When writing a data structure, writing a list only requires writing a third of the mapping time. But if we need to loop through these values, then how do we compare?

Complex mapping loop

We can loop through the top items in this map using the following code:

<code>@each $label, $map in $breakpoint-map {}</code>

The two variables ($label and $map) at the beginning of this line are dynamically allocated when iterating the data in the map in the loop. Each top-level data block has two components: keys and values. We assign the key to $label and the value (which is a nested map) to $map. In this loop we can use the variables $label and $map, which will automatically represent the key and value of the current entry.

The loop will iterate four times, one nested map each iterating. However, to get useful data from nested maps, we need to use the map-get() function. This function takes two parameters—the name of the map and the name of the required key—and returns the value associated with the key. It is the equivalent of the $array['key'] and $object->key of PHP or the object.key syntax of JavaScript in Sass.

To use @each to iterate over all submaps and assign their values ​​to useful variables using map-get(), we end up with a 6-line, 220-character loop.

<code>@each $label, $map in $breakpoint-map {
  $min-width: map-get($map, min-width);
  $max-width: map-get($map, max-width);
  $base-font: map-get($map, base-font);
  $vertical-rhythm: map-get($map, vertical-rhythm);
}</code>

Nested list loop

Nested lists do make loops more efficient. For maps, we have to assign the map to dynamic loop variables and then assign all values ​​to variables using map-get(), but for lists we can quickly assign all values ​​to variables.

Since each item in the top-level list has the same five values ​​in the same order, we can immediately assign each value to a dynamic variable for use in a loop. With these variables, we do not need to assign subvalues ​​to available variables using map-get(). The nested list loop we need is only two lines, less than 100 characters.

<code>@each $label, $min-width, $max-width, $base-font, $vertical-rhythm in $breakpoint-list {
}</code>

Nested List Warning

Nested lists are the main developer performance advantages: Overall, you may enter less than half as much as you did when using the mapping. However, there is a reason to add maps to Sass: they provide a function that lists do not have: key-value mapping.

Missed value

If you are relying on nested lists, you must be absolutely sure you know how many items each list will contain and the order they are. Let's see what happens if we miss an item in the list:

<code>$breakpoint-map: (
  small: (
    min-width: null,
    max-width: 479px,
    base-font: 16px,
    vertical-rhythm: 1.3
  ),
  medium: (
    min-width: 480px,
    max-width: 959px,
    base-font: 18px,
    vertical-rhythm: 1.414
  ),
  large: (
    min-width: 960px,
    max-width: 1099px,
    base-font: 18px,
    vertical-rhythm: 1.5
  ),
  xlarge: (
    min-width: 1100px,
    max-width: null,
    base-font: 21px,
    vertical-rhythm: 1.618
  )
);</code>

If we try to run the code, the last list will break. It will correctly assign "xlarge" to $label and "1100px" to $min-width, but then it assigns "21px" to $max-width and "1.618" to $base-font, making $vertical-rhythm is empty. As a result, we get an invalid font size declaration and a missing line height property in the last breakpoint. Also, Sass doesn't report an error for this, so we don't know if things succeed. If we try to use the maximum width for media queries, we will end up with the font size value (only 21px) - I think this would be a very useless maximum width!

If we use map instead, even if a value is missing, the map-get() function will give us what we need. This is our tradeoff: the simplicity and speed we get in the list, we lose specificity and error prevention in the mapping.

Query a specific list

Another related problem with using nested lists is querying specific lists. Since the map has keys, you can quickly access any submap using map-get():

<code>$breakpoint-list: (
  (small, null, 479px, 16px, 1.3),
  (medium, 480px, 959px, 18px, 1.414),
  (large, 960px, 1099px, 18px, 1.5),
  (xlarge, 1100px, null, 21px, 1.618)
);</code>

To get data for medium lists from nested lists, we need a more complex function:

<code>@each $label, $map in $breakpoint-map {}</code>

This function loops through all lists in $breakpoint-list, checks the first value of the label we want, and returns the list if a match is found. If the end of the @each loop is reached without a match found, it will return null. It's basically a quick homemade interpretation of the list's map-get(), which uses the first value as a pseudo-key.

Missing mapping function

Sass has many useful functions to handle mappings: nested lists do not exist in the same function. For example, you can use map-merge() to add additional key-value pairs to the map. Use map-merge() with shared keys to update the value of the shared key. You can add a new list using join() or append(), but the update function that simulates map-merge() will require another custom Sass function.

Another useful mapping function is map-has-key(). This function is useful for validating any custom function that depends on map-get(). However, there are no comparable functions for the list.

You can use SassyLists to simulate the mapping function of a list. (This library provided these functions before Sass added mapping support.)

Conclusion

Since maps use key-value pairs, they are more powerful than lists. The additional Sass mapping function provides a practical way to find data and verify mapped values.

Nested Sass lists may be faster to write and maintain, but they may not be as suitable as mappings for error checking or detailed querying. Most of the time, I think mapping is a better option, although there is an increase in verboseness. For smaller blocks of code and single-use loops, I occasionally use nested lists, but the mapping is more suitable for project-wide settings and data storage.

Have you compared maps and nested lists in any of your work, or refactored the code to prioritize one over the other? Share your experience in the comments!

You can see the code used in this tutorial in this Sassmeister gist.

FAQ for Sass Mapping and Nested Lists (FAQ)

What is the main difference between a Sass map and a nested list?

Sass mapping and nested lists are both powerful tools in Sass preprocessors, but they have obvious differences. Sass maps are similar to associative arrays in other programming languages, where each value is associated with a unique key. This makes it easy to retrieve, update and manipulate data. On the other hand, nested lists are a series of values ​​similar to arrays in JavaScript. They are best suited when you need to store and iterate over a range of values, but they lack the ability to directly access specific values ​​provided by the mapping.

How to use Sass mapping?

To use Sass map, you first need to define a map with a pair of brackets, each key-value pair separated by a colon. For example, $map: (key1: value1, key2: value2). You can then use the map-get function to access the values ​​in the map as follows: map-get($map, key1).

Can I nest Sass maps like nested lists?

Yes, you can nest Sass maps like nested lists. This is especially useful when you want to combine relevant data together. To access the values ​​in a nested map, you need to use the map-get function twice: map-get(map-get($map, key1), key2).

How to iterate over Sass maps?

You can iterate over the Sass map using the @each directive. The @each directive takes two variables: key and value. Here is an example: @each $key, $value in $map { … }.

What are the advantages of using Sass mapping instead of nested lists?

Sass mapping has several advantages over nested lists. They allow direct access to specific values, making your code more efficient and easier to read. They also provide built-in functions for manipulating mappings, such as adding, deleting, and updating key-value pairs.

Can I convert nested lists to Sass maps?

Yes, you can use the map-from-list function to convert nested lists to Sass maps. This function takes a list of pairs and returns a map where each pair is a key-value pair in the map.

How to use nested lists in Sass?

To use nested lists in Sass, you first need to define a list with a pair of brackets, each value separated by a space or comma. For example, $list: (value1, value2, value3). You can then use the nth function to access the values ​​in the list as follows: nth($list, 1).

Can I use Sass maps and nested lists at the same time?

Yes, you can use both Sass mapping and nested lists. For example, you can use mappings to store a series of lists and vice versa. This is useful for organizing complex data structures.

What are the limitations of using Sass mapping or nested lists?

While Sass mapping and nested lists are powerful tools, they do have some limitations. For example, the Sass map cannot have duplicate keys, and the order of keys in the map cannot be guaranteed. Likewise, if nested lists become too large or too complex, they can be difficult to manage.

How to choose between using Sass maps or nested lists?

The choice of using Sass map or nested list depends on your specific needs. If you need to directly access specific values ​​and be able to manipulate data, Sass mapping may be the best choice. If you just need to store and iterate over a series of values, a nested list is enough.

The above is the detailed content of Sass Maps vs. Nested Lists. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn