Sass: 为输入框创建 mixin

3

我刚接触Sass,需要帮助创建一个混合器来处理输入字段。

但是,如果有人知道已经有现成的混合器可以实现这个功能,或者Compass有一个可以完成这个任务的混合器,请告诉我(我们)。

我目前在我的.scss文件中有以下CSS规则:

input[type="text"],
input[type="password"],
input[type="email"],
input[type="search"],
input[type="url"],
textarea, 
select { ... }

input[type="text"]:hover,
input[type="text"]:focus,
input[type="password"]:hover,
input[type="password"]:focus,
input[type="email"]:hover,
input[type="email"]:focus,
input[type="search"]:hover,
input[type="search"]:focus,
input[type="url"]:hover,
input[type="url"]:focus,
textarea:hover,
textarea:focus,
select:hover,
select:focus  { ... }

现在,我们知道 HTML5 提供了一组漂亮的 输入类型,但是现在我不需要添加像 datemonthweek 这样的输入类型,这就是为什么我还没有列出它们的原因。
所以,如果将来需要添加它们,我会更新你在上面看到的列表。
然而,我的问题是我觉得我在这里反复重复自己,而且每次为新的输入类型选择项目、复制、粘贴和编辑的工作实在太愚蠢了,我几乎可以确定 Sass 的 mixin 可以帮助解决这个问题。问题是创建这个 mixin 对我来说非常困惑。
我在这里和网络上寻找类似的东西,但没有找到任何东西。
非常感谢您提供的任何帮助。

你真的需要列出这些类型吗?最终它们都会得到相同的样式,一个简单的 input{} 在这种情况下也可以达到同样的效果... - Christoph
1
@Christoph 如果你注意到了,只有文本类型的字段被列出来了(省略了日期、颜色、范围、数字等)。某些非文本元素如果尝试应用某些样式,就会看起来很奇怪,类似于文件输入元素。 - cimmanon
Cinnamon 是正确的。此外,按钮也是“输入”,我不想因为使用这样一个通用规则而在其他地方否定它们的属性。我找到了一个解决方案,请看下面(现在发布)。 - Ricardo Zea
你无法用 mixin 来解决这个问题,最好的情况是可以使用变量插值。 - Christoph
我不知道那是什么意思,我不是程序员,但似乎那就是原始的mixin所做的,所以我只是重复了它。 - Ricardo Zea
2个回答

4

好的,我最终找到了Sass混合库Bourbon

他们有一个针对HTML5输入类型的“附加组件”(这是他们创建的.scss文件的链接),但它没有:hover:focus伪元素。所以我添加了它们。

老实说,我不知道我所做的是否是编写此mixin的最佳方法,但这个东西运行得非常好:

//************************************************************************//
// Generate a variable ($all-text-inputs) with a list of all html5
// input types that have a text-based input, excluding textarea.
// http://diveintohtml5.org/forms.html
//************************************************************************//
$inputs-list: 'input[type="email"]',
              'input[type="number"]',
              'input[type="password"]',
              'input[type="search"]',
              'input[type="tel"]',
              'input[type="text"]',
              'input[type="url"]',

              // Webkit & Gecko may change the display of these in the future
              'input[type="color"]',
              'input[type="date"]',
              'input[type="datetime"]',
              'input[type="datetime-local"]',
              'input[type="month"]',
              'input[type="time"]',
              'input[type="week"]';

$unquoted-inputs-list: ();

@each $input-type in $inputs-list {
  $unquoted-inputs-list: append($unquoted-inputs-list, unquote($input-type), comma);
}

$all-text-inputs: $unquoted-inputs-list;

// You must use interpolation on the variable:
// #{$all-text-inputs}
//************************************************************************//
//   #{$all-text-inputs}, textarea {
//     border: 1px solid red;
//   }

// :hover and :focus pseudo elements
// Added by Ricardo Zea
// http://ricardozea.net
// @ricardozea
// Tracking: https://dev59.com/8GrWa4cB1Zd3GeqP91U1

$inputs-list-hf:'input[type="email"]:hover',
                'input[type="number"]:hover',
                'input[type="password"]:hover',
                'input[type="search"]:hover',
                'input[type="tel"]:hover',
                'input[type="text"]:hover',
                'input[type="url"]:hover',
                'input[type="color"]:hover',
                'input[type="date"]:hover',
                'input[type="datetime"]:hover',
                'input[type="datetime-local"]:hover',
                'input[type="month"]:hover',
                'input[type="time"]:hover',
                'input[type="week"]:hover',

                'input[type="email"]:focus',
                'input[type="number"]:focus',
                'input[type="password"]:focus',
                'input[type="search"]:focus',
                'input[type="tel"]:focus',
                'input[type="text"]:focus',
                'input[type="url"]:focus',
                'input[type="color"]:focus',
                'input[type="date"]:focus',
                'input[type="datetime"]:focus',
                'input[type="datetime-local"]:focus',
                'input[type="month"]:focus',
                'input[type="time"]:focus',
                'input[type="week"]:focus';

$unquoted-inputs-list-hf: ();

@each $input-type-hf in $inputs-list-hf {
  $unquoted-inputs-list-hf: append($unquoted-inputs-list-hf, unquote($input-type-hf), comma);
}

$all-text-inputs-hf: $unquoted-inputs-list-hf;

// You must use interpolation on the variable:
// #{$all-text-inputs-hf}
//************************************************************************//
//   #{$all-text-inputs-hf}, textarea {
//     border: 1px solid red;
//   }

如您所见,我复制并粘贴了原始混合,并添加了前缀-hf以及新规则中的:hover:focus

我的 .scss 文件中添加了这个@import

@import "html5-input-types";(不需要下划线_或文件扩展名.scss

在我的 .scss 文件的 '表单' 部分中,我添加了以下规则:

/*Normal state*/
#{$all-text-inputs}, 
textarea,
select { ... }

/*:hover and :focus states*/
#{$all-text-inputs-hf}, 
textarea:hover, 
textarea:focus,
select:hover,
select:focus { ... }

我知道我有一个textareaselect在mixin文件之外(html5-input-types.scss),不确定是否包含它们,得想一想。无论如何,这对我来说效果很好,虽然如果将来有任何变化,我仍需要更新html5-input-types.scss,但至少我比以前更有效地处理这些输入字段。希望我做的能帮到别人。如果您有改进mixin的建议,请务必让我(我们)知道。谢谢。

好的,就像我说的那样,你只能使用插值变量。由于我认为你只是针对输入和悬停/聚焦使用了一个规则,所以你最终会遇到很大的开销 - 在我看来这不值得。 (如果您一遍又一遍地使用这些列表,则有意义)。这只会减慢SASS解析速度... - Christoph
3
#{$all-text-inputs}, textarea, select { ... &:hover, &:focus { ... } } 这段代码可以减少输入量。 - cimmanon
@Christoph 解析是由我的计算机完成的,而不是我或服务器,所以没有伤害。此外,我可以使用此文件在其他项目中反复使用,而无需将整个规则块复制并粘贴到每个.scss文件中。正如我所说,如果您有更好的方法,请与所有人分享。自己想出这个方法很棒,因为我了解了一些关于SASS和mixins以及“插值变量”的知识。谢谢。 - Ricardo Zea
@cimmanon 哎呀!你说得对,哈哈。但是上面的解决方案更好。我给你点了个赞。谢谢。 - Ricardo Zea
我刚刚尝试了使用Yeoman,但是它并没有起作用。有人知道Yeoman的解决方法吗? - Pavel Nikolov

1

如果有人因同样的原因遇到这个问题,为什么不让SASS来完成工作呢?

CodePen

$form-background: #f8f8f8;
$form-color: #000;
$form-border: 1px solid lighten($form-color, 50%);

$form-focus-background: darken($form-background, 10%);
$form-focus-color: #999;
$form-focus-border: 1px solid $form-color;

%input-styles {
    width: 15em;
    min-height: 30px;
    margin: 0 0 15px 15px;
    background: $form-background;
    color: $form-color;
    border: $form-border;
    transition: .2s ease-in-out;
    transition-property: color, background-color, border;
}

%input-styles--focus {
    background-color: $form-focus-background;
    color: $form-focus-color;
    border: $form-focus-border;
}

@mixin input-styles($styles, $focus_styles) {
    $types: 'email', 'number', 'radio', 'password', 'search', 'tel',
            'text', 'url', 'color', 'date', 'datetime',
            'datetime-local', 'month', 'time', 'week';

    @each $type in $types {
        input[type="#{$type}"] {
            @extend #{$styles};

            &:focus {
                @extend #{$focus_styles};
            }
        }
    }

    select,
    textarea {
        @extend #{$styles};

        &:focus {
            @extend #{$focus_styles};
        }
    }
}

@include input-styles('%input-styles', '%input-styles--focus');

不是我不能创建它,但是在你的回答中添加一个工作演示对其他人来说将是非常有帮助的。这只是一个建议。 - Ricardo Zea
1
添加了一个 CodePen,@RicardoZea。 - Chris Schloegel
太棒了!你的回答有了巨大的改进。我给了你一个赞,还在 CodePen 上点了个赞 :)。谢谢! - Ricardo Zea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接